From a9c53d461a6a2f6d46464d9ad7771c760a663aca Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Wed, 9 Oct 2024 12:53:14 +0200 Subject: [PATCH 01/11] init commit permeability Co-authored by: Jacob Frasunkiewicz --- src/GeoParams.jl | 23 +++-- src/MaterialParameters.jl | 97 ++++++++++--------- src/Permeability/Permeability.jl | 156 +++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+), 51 deletions(-) create mode 100644 src/Permeability/Permeability.jl diff --git a/src/GeoParams.jl b/src/GeoParams.jl index dea42709..aadc4929 100644 --- a/src/GeoParams.jl +++ b/src/GeoParams.jl @@ -335,6 +335,17 @@ export compute_meltfraction, Vector_MeltingParam, SmoothMelting + +using .MaterialParameters.Permeability +export compute_permeability, + compute_permeability!, + param_info, + AbstractPermeability, + ConstantPermeability, + HazenPermeability, + PowerLawPermeability, + CarmanKozenyPermeability + include("Traits/rheology.jl") export RheologyTrait export islinear, LinearRheologyTrait, NonLinearRheologyTrait @@ -363,7 +374,7 @@ function creeplaw_list(m::Module) out = string.(names(m; all=true, imported=true)) filter!(x -> !startswith(x, "#"), out) return [getfield(m, Symbol(x)) for x in out if !isnothing(tryparse(Int, string(x[end]))) || endswith(x, "a") || endswith(x, "b")] -end +end diffusion_law_list() = creeplaw_list(Diffusion) dislocation_law_list() = creeplaw_list(Dislocation) @@ -371,10 +382,10 @@ grainboundarysliding_law_list() = creeplaw_list(GBS) nonlinearpeierls_law_list() = creeplaw_list(NonLinearPeierls) peierls_law_list() = creeplaw_list(Peierls) -export diffusion_law_list, - dislocation_law_list, - grainboundarysliding_law_list, - nonlinearpeierls_law_list, +export diffusion_law_list, + dislocation_law_list, + grainboundarysliding_law_list, + nonlinearpeierls_law_list, peierls_law_list # Define Table output functions @@ -454,4 +465,4 @@ export get_G, get_Kb const get_shearmodulus = get_G const get_bulkmodulus = get_Kb -end # module GeoParams \ No newline at end of file +end # module GeoParams diff --git a/src/MaterialParameters.jl b/src/MaterialParameters.jl index 6fada711..2af74f4b 100644 --- a/src/MaterialParameters.jl +++ b/src/MaterialParameters.jl @@ -11,7 +11,7 @@ using Static import Base.show, Base.convert using GeoParams: - AbstractMaterialParam, AbstractMaterialParamsStruct, AbstractPhaseDiagramsStruct, AbstractComposite, ptr2string + AbstractMaterialParam, AbstractMaterialParamsStruct, AbstractPhaseDiagramsStruct, AbstractComposite, ptr2string # Define an "empty" Material parameter structure struct No_MaterialParam{_T} <: AbstractMaterialParam end @@ -44,6 +44,7 @@ include("./PhaseDiagrams/PhaseDiagrams.jl") #include("./Elasticity/Elasticity.jl") include("./ConstitutiveRelationships.jl") include("./Density/Density.jl") +include("./Permeability/Permeability.jl") include("./GravitationalAcceleration/GravitationalAcceleration.jl") include("./Energy/HeatCapacity.jl") include("./Energy/Conductivity.jl") @@ -58,7 +59,7 @@ using .ConstitutiveRelationships: print_rheology_matrix """ MaterialParams - + Structure that holds all material parameters for a given phase """ @@ -74,6 +75,7 @@ Structure that holds all material parameters for a given phase Vradioact<:Tuple, Vlatent<:Tuple, Vshearheat<:Tuple, + Vpermeability<:Tuple, Vmelting<:Tuple, Vseismvel<:Tuple, } <: AbstractMaterialParamsStruct @@ -85,38 +87,40 @@ Structure that holds all material parameters for a given phase CreepLaws::Vcreep = () # Creep laws Elasticity::Velastic = () # Elastic parameters Plasticity::Vplastic = () # Plasticity - CompositeRheology::Vcomposite = () # Composite (combined) rheologies - Conductivity::Vcond = () # Parameters related to the energy equation - HeatCapacity::Vheatc = () # Heat capacity + CompositeRheology::Vcomposite = () # Composite (combined) rheologies + Conductivity::Vcond = () # Parameters related to the energy equation + HeatCapacity::Vheatc = () # Heat capacity RadioactiveHeat::Vradioact = () # Radioactive heating source terms in energy conservation equation LatentHeat::Vlatent = () # Latent heating source terms in energy conservation equation ShearHeat::Vshearheat = () # Shear heating source terms in energy conservation equation + Permeability::Vpermeability = () # Permeability Melting::Vmelting = () # Melting model SeismicVelocity::Vseismvel = () # Seismic velocity end """ SetMaterialParams(; Name::String="", Phase::Int64=1, - Density = nothing, + Density = nothing, Gravity = nothing, - CreepLaws = nothing, - Elasticity = nothing, - Plasticity = nothing, + CreepLaws = nothing, + Elasticity = nothing, + Plasticity = nothing, CompositeRheology = nothing, - Conductivity = nothing, - HeatCapacity = nothing, + Conductivity = nothing, + HeatCapacity = nothing, RadioactiveHeat = nothing, LatentHeat = nothing, ShearHeat = nothing, + Permeability = nothing, Melting = nothing, SeismicVelocity = nothing, CharDim::GeoUnits = nothing) -Sets material parameters for a given phase. +Sets material parameters for a given phase. -If `CharDim` is specified the input parameters are non-dimensionalized. +If `CharDim` is specified the input parameters are non-dimensionalized. Note that if `Density` is specified, we also set `Gravity` even if not explicitly listed - + # Examples Define two viscous creep laws & constant density: @@ -126,10 +130,10 @@ julia> Phase = SetMaterialParams(Name="Viscous Matrix", CreepLaws = (PowerlawViscous(), LinearViscous(η=1e21Pa*s))) Phase 1 : Viscous Matrix | [dimensional units] - | - |-- Density : Constant density: ρ=2900 kg m⁻³ - |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² - |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ + | + |-- Density : Constant density: ρ=2900 kg m⁻³ + |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² + |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ | Linear viscosity: η=1.0e21 Pa s ``` @@ -142,11 +146,11 @@ julia> Phase = SetMaterialParams(Name="Viscous Matrix", Phase=33, CharDim = CharUnits_GEO) Phase 33: Viscous Matrix | [non-dimensional units] - | - |-- Density : P/T-dependent density: ρ0=2.9e-16, α=0.038194500000000006, β=0.01, T0=0.21454659702313156, P0=0.0 - |-- Gravity : Gravitational acceleration: g=9.810000000000002e18 - |-- CreepLaws : Powerlaw viscosity: η0=0.1, n=3, ε0=0.001 - | Linear viscosity: η=10000.0 + | + |-- Density : P/T-dependent density: ρ0=2.9e-16, α=0.038194500000000006, β=0.01, T0=0.21454659702313156, P0=0.0 + |-- Gravity : Gravitational acceleration: g=9.810000000000002e18 + |-- CreepLaws : Powerlaw viscosity: η0=0.1, n=3, ε0=0.001 + | Linear viscosity: η=10000.0 ``` You can also create an array that holds several parameters: @@ -164,19 +168,19 @@ julia> MatParam 2-element Vector{MaterialParams}: Phase 1 : Upper Crust | [dimensional units] - | - |-- Density : Constant density: ρ=2900 kg m⁻³ - |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² - |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ - | Linear viscosity: η=1.0e23 Pa s - + | + |-- Density : Constant density: ρ=2900 kg m⁻³ + |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² + |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ + | Linear viscosity: η=1.0e23 Pa s + Phase 2 : Lower Crust | [dimensional units] - | - |-- Density : P/T-dependent density: ρ0=3000 kg m⁻³, α=3.0e-5 K⁻¹, β=1.0e-9 Pa⁻¹, T0=0 °C, P0=0 MPa - |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² - |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=5, ε0=1.0e-15 s⁻¹ - | Linear viscosity: η=1.0e21 Pa s + | + |-- Density : P/T-dependent density: ρ0=3000 kg m⁻³, α=3.0e-5 K⁻¹, β=1.0e-9 Pa⁻¹, T0=0 °C, P0=0 MPa + |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² + |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=5, ε0=1.0e-15 s⁻¹ + | Linear viscosity: η=1.0e21 Pa s ``` @@ -195,6 +199,7 @@ function SetMaterialParams(; RadioactiveHeat=nothing, LatentHeat=nothing, ShearHeat=nothing, + Permeability=nothing, Melting=nothing, SeismicVelocity=nothing, CharDim=nothing, @@ -213,6 +218,7 @@ function SetMaterialParams(; ConvField(RadioactiveHeat, :RadioactiveHeat; maxAllowedFields=1), ConvField(LatentHeat, :LatentHeat; maxAllowedFields=1), ConvField(ShearHeat, :ShearHeat; maxAllowedFields=1), + ConvField(Permeability, :Permeability; maxAllowedFields=1), ConvField(Melting, :Melting; maxAllowedFields=1), ConvField(SeismicVelocity, :SeismicVelocity; maxAllowedFields=1), CharDim, @@ -233,12 +239,13 @@ function SetMaterialParams( RadioactiveHeat, LatentHeat, ShearHeat, + Permeability, Melting, SeismicVelocity, CharDim, ) - # define struct for phase, while also specifying the maximum number of definitions for every field + # define struct for phase, while also specifying the maximum number of definitions for every field phase = MaterialParams( pointer(ptr2string(Name)), Phase, @@ -254,12 +261,13 @@ function SetMaterialParams( RadioactiveHeat, LatentHeat, ShearHeat, + Permeability, Melting, SeismicVelocity, ) # [optionally] non-dimensionalize the struct - phase_nd = nondimensionalize_phase(phase, CharDim) + phase_nd = nondimensionalize_phase(phase, CharDim) return phase_nd end @@ -274,11 +282,11 @@ end set_gravity(Gravity, Density) = Gravity # Helper function that converts a field to a Tuple, provided it is not nothing -# This also checks for the maximum allowed number of definitions -# (some rheological phases may allow for an arbitrary combination per phase; others like density EoS not) +# This also checks for the maximum allowed number of definitions +# (some rheological phases may allow for an arbitrary combination per phase; others like density EoS not) ConvField(::Nothing, fieldname::Symbol; maxAllowedFields=1e6) = () ConvField(field::AbstractMaterialParam, fieldname::Symbol; maxAllowedFields=1e6) = (field, ) -function ConvField(field::NTuple{N, Any}, fieldname::Symbol; maxAllowedFields=1e6) where N +function ConvField(field::NTuple{N, Any}, fieldname::Symbol; maxAllowedFields=1e6) where N if length(field) > maxAllowedFields error("Maximum $(maxAllowedFields) field allowed for: $fieldname") end @@ -286,11 +294,11 @@ function ConvField(field::NTuple{N, Any}, fieldname::Symbol; maxAllowedFields=1e end # Helper that prints info about each of the material parameters -# for this to look nice, you need to define a Base.show +# for this to look nice, you need to define a Base.show function Print_MaterialParam(io::IO, name::Symbol, Data) if length(Data) > 0 if Data isa Ptr - str = unsafe_string(Data) + str = unsafe_string(Data) print(io, " |-- $(rpad(name,18)): $str \n") elseif typeof(Data[1]) <: AbstractMaterialParam @@ -299,7 +307,7 @@ function Print_MaterialParam(io::IO, name::Symbol, Data) str = Data[i] if isa(str, AbstractComposite) # The CompositeRheology object is formatted a bit different - str = print_composite(Data[i],32) + str = print_composite(Data[i],32) end if i == 1 @@ -329,7 +337,7 @@ function Base.show(io::IO, phase::MaterialParams) end end -# Slightly nicer printout in case we have a tuple with material parameters +# Slightly nicer printout in case we have a tuple with material parameters function Base.show(io::IO, phase_tuple::NTuple{N,MaterialParams}) where {N} for i in 1:N Base.show(io, phase_tuple[i]) @@ -349,7 +357,7 @@ function print_composite(a, spaces=10) str = str.*"\n" for i=2:length(str) for j=1:spaces - str[i] = " "*str[i] + str[i] = " "*str[i] end end str = join(str) @@ -358,4 +366,3 @@ function print_composite(a, spaces=10) end end - diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl new file mode 100644 index 00000000..86f03417 --- /dev/null +++ b/src/Permeability/Permeability.jl @@ -0,0 +1,156 @@ +module Permeability + +using Parameters, Unitful, LaTeXStrings, MuladdMacro +using ..Units +using ..PhaseDiagrams +using GeoParams: AbstractMaterialParam, AbstractMaterialParamsStruct, @extractors, add_extractor_functions +import ..Units: isdimensional +using ..MaterialParameters: No_MaterialParam, MaterialParamsInfo +import Base.show, GeoParams.param_info + +include("../Computations.jl") + +abstract type AbstractPermeability{T} <: AbstractMaterialParam end + +export compute_permeability, # calculation routines + compute_permeability!, # in place calculation + param_info, # info about the parameters + AbstractPermeability, + ConstantPermeability, # constant + HazenPermeability, # Hazen equation + PowerLawPermeability, # Power-law permeability + CarmanKozenyPermeability # Carman-Kozeny permeability + +# Define "empty" computational routines in case nothing is defined +function compute_permeability!( + k::_T, s::No_MaterialParam{_T}; ϕ::_T=zero(_T) +) where {_T} + return zero(_T) +end +function compute_permeability(s::No_MaterialParam{_T}; ϕ::_T=zero(_T)) where {_T} + return zero(_T) +end + +# Constant Permeability +@with_kw_noshow struct ConstantPermeability{_T,U} <: AbstractPermeability{_T} + k::GeoUnit{_T,U} = 1e-12m^2 # permeability +end +ConstantPermeability(args...) = ConstantPermeability(convert.(GeoUnit, args)...) +isdimensional(s::ConstantPermeability) = isdimensional(s.k) + +@inline compute_permeability(s::ConstantPermeability{_T}, args) where {_T} = s(; args...) +@inline compute_permeability(s::ConstantPermeability{_T}) where {_T} = s() + +function param_info(s::ConstantPermeability) + return MaterialParamsInfo(; Equation=L"k = cst") +end + +function compute_permeability!(k::AbstractArray, s::ConstantPermeability; kwargs...) + @unpack_val k_val = s + k[:] .= k_val + return nothing +end + +function compute_permeability!(k::AbstractArray, s::ConstantPermeability, args) + return compute_permeability!(k, s; args...) +end + +function show(io::IO, g::ConstantPermeability) + return print(io, "Constant permeability: k=$(UnitValue(g.k))") +end + +# Hazen Permeability +@with_kw_noshow struct HazenPermeability{_T,U1,U2} <: AbstractPermeability{_T} + C::GeoUnit{_T,U1} = 1.0 # Hazen constant + D10::GeoUnit{_T,U2} = 1e-4m # Effective grain size +end +HazenPermeability(args...) = HazenPermeability(convert.(GeoUnit, args)...) +isdimensional(s::HazenPermeability) = isdimensional(s.C) + +function param_info(s::HazenPermeability) + return MaterialParamsInfo(; Equation = L"k = C \cdot D_{10}^2") +end + +function (s::HazenPermeability{_T})(; kwargs...) where {_T} + if kwargs isa Quantity + @unpack_units C, D10 = s + else + @unpack_val C, D10 = s + end + + return C * D10^2 +end + +@inline (s::HazenPermeability)(args) = s(; args...) +@inline compute_permeability(s::HazenPermeability, args) = s(args) + +function show(io::IO, g::HazenPermeability) + return print(io, "Hazen permeability: k = C * D10^2; C=$(g.C); D10=$(g.D10)") +end + +# Power-law Permeability +@with_kw_noshow struct PowerLawPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} + c::GeoUnit{_T,U1} = 1.0 # Power-law constant + k0::GeoUnit{_T,U1} = 1e-12m^2 # reference permeability + n::GeoUnit{_T,U3} = 3.0 # exponent +end +PowerLawPermeability(args...) = PowerLawPermeability(convert.(GeoUnit, args)...) +isdimensional(s::PowerLawPermeability) = isdimensional(s.k0) + +function param_info(s::PowerLawPermeability) + return MaterialParamsInfo(; Equation = L"k = c * k_0 * (\phi^n)") +end + +function (s::PowerLawPermeability{_T})(; ϕ=0e0, kwargs...) where {_T} + if ϕ isa Quantity + @unpack_units c, k0, n = s + else + @unpack_val c, k0, n = s + end + + return c * k0 * ϕ^n +end + +@inline (s::PowerLawPermeability)(args) = s(; args...) +@inline compute_permeability(s::PowerLawPermeability, args) = s(args) + +function show(io::IO, g::PowerLawPermeability) + return print(io, "Power-law permeability: k = c* k0 * ϕ^n; c = $(g.c), k0=$(g.k0); n=$(g.n)") +end + +# Carman-Kozeny Permeability +@with_kw_noshow struct CarmanKozenyPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} + c::GeoUnit{_T,U1} = 1.0 # Carman-Kozeny constant + ϕ0::GeoUnit{_T,U2} = 0.01 # reference porosity + n::GeoUnit{_T,U3} = 3.0 # exponent +end +CarmanKozenyPermeability(args...) = CarmanKozenyPermeability(convert.(GeoUnit, args)...) +isdimensional(s::CarmanKozenyPermeability) = isdimensional(s.c) + +function param_info(s::CarmanKozenyPermeability) + return MaterialParamsInfo(; Equation = L"k = c \left(\frac{\phi}{\phi_0}\right)^n") +end + +function (s::CarmanKozenyPermeability{_T})(; ϕ=1e-2, kwargs...) where {_T} + if ϕ isa Quantity + @unpack_units c, ϕ0, n = s + else + @unpack_val c, ϕ0, n = s + end + + return c * (ϕ / ϕ0)^n +end + +@inline (s::CarmanKozenyPermeability)(args) = s(; args...) +@inline compute_permeability(s::CarmanKozenyPermeability, args) = s(args) + +function show(io::IO, g::CarmanKozenyPermeability) + return print(io, "Carman-Kozeny permeability: k = c * (ϕ / ϕ0)^n; c=$(g.c); ϕ0=$(g.ϕ0); n=$(g.n)") +end + +# extractor methods +for type in (ConstantPermeability, HazenPermeability, PowerLawPermeability, CarmanKozenyPermeability) + @extractors(type, :Permeability) +end + +end From 901742242a224a8e48f33d22d93acfb458ecd4dc Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Wed, 9 Oct 2024 12:53:14 +0200 Subject: [PATCH 02/11] init commit permeability Co-authored by: Jacob Frasunkiewicz --- src/GeoParams.jl | 23 +++-- src/MaterialParameters.jl | 97 ++++++++++--------- src/Permeability/Permeability.jl | 156 +++++++++++++++++++++++++++++++ 3 files changed, 225 insertions(+), 51 deletions(-) create mode 100644 src/Permeability/Permeability.jl diff --git a/src/GeoParams.jl b/src/GeoParams.jl index dea42709..aadc4929 100644 --- a/src/GeoParams.jl +++ b/src/GeoParams.jl @@ -335,6 +335,17 @@ export compute_meltfraction, Vector_MeltingParam, SmoothMelting + +using .MaterialParameters.Permeability +export compute_permeability, + compute_permeability!, + param_info, + AbstractPermeability, + ConstantPermeability, + HazenPermeability, + PowerLawPermeability, + CarmanKozenyPermeability + include("Traits/rheology.jl") export RheologyTrait export islinear, LinearRheologyTrait, NonLinearRheologyTrait @@ -363,7 +374,7 @@ function creeplaw_list(m::Module) out = string.(names(m; all=true, imported=true)) filter!(x -> !startswith(x, "#"), out) return [getfield(m, Symbol(x)) for x in out if !isnothing(tryparse(Int, string(x[end]))) || endswith(x, "a") || endswith(x, "b")] -end +end diffusion_law_list() = creeplaw_list(Diffusion) dislocation_law_list() = creeplaw_list(Dislocation) @@ -371,10 +382,10 @@ grainboundarysliding_law_list() = creeplaw_list(GBS) nonlinearpeierls_law_list() = creeplaw_list(NonLinearPeierls) peierls_law_list() = creeplaw_list(Peierls) -export diffusion_law_list, - dislocation_law_list, - grainboundarysliding_law_list, - nonlinearpeierls_law_list, +export diffusion_law_list, + dislocation_law_list, + grainboundarysliding_law_list, + nonlinearpeierls_law_list, peierls_law_list # Define Table output functions @@ -454,4 +465,4 @@ export get_G, get_Kb const get_shearmodulus = get_G const get_bulkmodulus = get_Kb -end # module GeoParams \ No newline at end of file +end # module GeoParams diff --git a/src/MaterialParameters.jl b/src/MaterialParameters.jl index 6fada711..2af74f4b 100644 --- a/src/MaterialParameters.jl +++ b/src/MaterialParameters.jl @@ -11,7 +11,7 @@ using Static import Base.show, Base.convert using GeoParams: - AbstractMaterialParam, AbstractMaterialParamsStruct, AbstractPhaseDiagramsStruct, AbstractComposite, ptr2string + AbstractMaterialParam, AbstractMaterialParamsStruct, AbstractPhaseDiagramsStruct, AbstractComposite, ptr2string # Define an "empty" Material parameter structure struct No_MaterialParam{_T} <: AbstractMaterialParam end @@ -44,6 +44,7 @@ include("./PhaseDiagrams/PhaseDiagrams.jl") #include("./Elasticity/Elasticity.jl") include("./ConstitutiveRelationships.jl") include("./Density/Density.jl") +include("./Permeability/Permeability.jl") include("./GravitationalAcceleration/GravitationalAcceleration.jl") include("./Energy/HeatCapacity.jl") include("./Energy/Conductivity.jl") @@ -58,7 +59,7 @@ using .ConstitutiveRelationships: print_rheology_matrix """ MaterialParams - + Structure that holds all material parameters for a given phase """ @@ -74,6 +75,7 @@ Structure that holds all material parameters for a given phase Vradioact<:Tuple, Vlatent<:Tuple, Vshearheat<:Tuple, + Vpermeability<:Tuple, Vmelting<:Tuple, Vseismvel<:Tuple, } <: AbstractMaterialParamsStruct @@ -85,38 +87,40 @@ Structure that holds all material parameters for a given phase CreepLaws::Vcreep = () # Creep laws Elasticity::Velastic = () # Elastic parameters Plasticity::Vplastic = () # Plasticity - CompositeRheology::Vcomposite = () # Composite (combined) rheologies - Conductivity::Vcond = () # Parameters related to the energy equation - HeatCapacity::Vheatc = () # Heat capacity + CompositeRheology::Vcomposite = () # Composite (combined) rheologies + Conductivity::Vcond = () # Parameters related to the energy equation + HeatCapacity::Vheatc = () # Heat capacity RadioactiveHeat::Vradioact = () # Radioactive heating source terms in energy conservation equation LatentHeat::Vlatent = () # Latent heating source terms in energy conservation equation ShearHeat::Vshearheat = () # Shear heating source terms in energy conservation equation + Permeability::Vpermeability = () # Permeability Melting::Vmelting = () # Melting model SeismicVelocity::Vseismvel = () # Seismic velocity end """ SetMaterialParams(; Name::String="", Phase::Int64=1, - Density = nothing, + Density = nothing, Gravity = nothing, - CreepLaws = nothing, - Elasticity = nothing, - Plasticity = nothing, + CreepLaws = nothing, + Elasticity = nothing, + Plasticity = nothing, CompositeRheology = nothing, - Conductivity = nothing, - HeatCapacity = nothing, + Conductivity = nothing, + HeatCapacity = nothing, RadioactiveHeat = nothing, LatentHeat = nothing, ShearHeat = nothing, + Permeability = nothing, Melting = nothing, SeismicVelocity = nothing, CharDim::GeoUnits = nothing) -Sets material parameters for a given phase. +Sets material parameters for a given phase. -If `CharDim` is specified the input parameters are non-dimensionalized. +If `CharDim` is specified the input parameters are non-dimensionalized. Note that if `Density` is specified, we also set `Gravity` even if not explicitly listed - + # Examples Define two viscous creep laws & constant density: @@ -126,10 +130,10 @@ julia> Phase = SetMaterialParams(Name="Viscous Matrix", CreepLaws = (PowerlawViscous(), LinearViscous(η=1e21Pa*s))) Phase 1 : Viscous Matrix | [dimensional units] - | - |-- Density : Constant density: ρ=2900 kg m⁻³ - |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² - |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ + | + |-- Density : Constant density: ρ=2900 kg m⁻³ + |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² + |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ | Linear viscosity: η=1.0e21 Pa s ``` @@ -142,11 +146,11 @@ julia> Phase = SetMaterialParams(Name="Viscous Matrix", Phase=33, CharDim = CharUnits_GEO) Phase 33: Viscous Matrix | [non-dimensional units] - | - |-- Density : P/T-dependent density: ρ0=2.9e-16, α=0.038194500000000006, β=0.01, T0=0.21454659702313156, P0=0.0 - |-- Gravity : Gravitational acceleration: g=9.810000000000002e18 - |-- CreepLaws : Powerlaw viscosity: η0=0.1, n=3, ε0=0.001 - | Linear viscosity: η=10000.0 + | + |-- Density : P/T-dependent density: ρ0=2.9e-16, α=0.038194500000000006, β=0.01, T0=0.21454659702313156, P0=0.0 + |-- Gravity : Gravitational acceleration: g=9.810000000000002e18 + |-- CreepLaws : Powerlaw viscosity: η0=0.1, n=3, ε0=0.001 + | Linear viscosity: η=10000.0 ``` You can also create an array that holds several parameters: @@ -164,19 +168,19 @@ julia> MatParam 2-element Vector{MaterialParams}: Phase 1 : Upper Crust | [dimensional units] - | - |-- Density : Constant density: ρ=2900 kg m⁻³ - |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² - |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ - | Linear viscosity: η=1.0e23 Pa s - + | + |-- Density : Constant density: ρ=2900 kg m⁻³ + |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² + |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=2.0, ε0=1.0e-15 s⁻¹ + | Linear viscosity: η=1.0e23 Pa s + Phase 2 : Lower Crust | [dimensional units] - | - |-- Density : P/T-dependent density: ρ0=3000 kg m⁻³, α=3.0e-5 K⁻¹, β=1.0e-9 Pa⁻¹, T0=0 °C, P0=0 MPa - |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² - |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=5, ε0=1.0e-15 s⁻¹ - | Linear viscosity: η=1.0e21 Pa s + | + |-- Density : P/T-dependent density: ρ0=3000 kg m⁻³, α=3.0e-5 K⁻¹, β=1.0e-9 Pa⁻¹, T0=0 °C, P0=0 MPa + |-- Gravity : Gravitational acceleration: g=9.81 m s⁻² + |-- CreepLaws : Powerlaw viscosity: η0=1.0e18 Pa s, n=5, ε0=1.0e-15 s⁻¹ + | Linear viscosity: η=1.0e21 Pa s ``` @@ -195,6 +199,7 @@ function SetMaterialParams(; RadioactiveHeat=nothing, LatentHeat=nothing, ShearHeat=nothing, + Permeability=nothing, Melting=nothing, SeismicVelocity=nothing, CharDim=nothing, @@ -213,6 +218,7 @@ function SetMaterialParams(; ConvField(RadioactiveHeat, :RadioactiveHeat; maxAllowedFields=1), ConvField(LatentHeat, :LatentHeat; maxAllowedFields=1), ConvField(ShearHeat, :ShearHeat; maxAllowedFields=1), + ConvField(Permeability, :Permeability; maxAllowedFields=1), ConvField(Melting, :Melting; maxAllowedFields=1), ConvField(SeismicVelocity, :SeismicVelocity; maxAllowedFields=1), CharDim, @@ -233,12 +239,13 @@ function SetMaterialParams( RadioactiveHeat, LatentHeat, ShearHeat, + Permeability, Melting, SeismicVelocity, CharDim, ) - # define struct for phase, while also specifying the maximum number of definitions for every field + # define struct for phase, while also specifying the maximum number of definitions for every field phase = MaterialParams( pointer(ptr2string(Name)), Phase, @@ -254,12 +261,13 @@ function SetMaterialParams( RadioactiveHeat, LatentHeat, ShearHeat, + Permeability, Melting, SeismicVelocity, ) # [optionally] non-dimensionalize the struct - phase_nd = nondimensionalize_phase(phase, CharDim) + phase_nd = nondimensionalize_phase(phase, CharDim) return phase_nd end @@ -274,11 +282,11 @@ end set_gravity(Gravity, Density) = Gravity # Helper function that converts a field to a Tuple, provided it is not nothing -# This also checks for the maximum allowed number of definitions -# (some rheological phases may allow for an arbitrary combination per phase; others like density EoS not) +# This also checks for the maximum allowed number of definitions +# (some rheological phases may allow for an arbitrary combination per phase; others like density EoS not) ConvField(::Nothing, fieldname::Symbol; maxAllowedFields=1e6) = () ConvField(field::AbstractMaterialParam, fieldname::Symbol; maxAllowedFields=1e6) = (field, ) -function ConvField(field::NTuple{N, Any}, fieldname::Symbol; maxAllowedFields=1e6) where N +function ConvField(field::NTuple{N, Any}, fieldname::Symbol; maxAllowedFields=1e6) where N if length(field) > maxAllowedFields error("Maximum $(maxAllowedFields) field allowed for: $fieldname") end @@ -286,11 +294,11 @@ function ConvField(field::NTuple{N, Any}, fieldname::Symbol; maxAllowedFields=1e end # Helper that prints info about each of the material parameters -# for this to look nice, you need to define a Base.show +# for this to look nice, you need to define a Base.show function Print_MaterialParam(io::IO, name::Symbol, Data) if length(Data) > 0 if Data isa Ptr - str = unsafe_string(Data) + str = unsafe_string(Data) print(io, " |-- $(rpad(name,18)): $str \n") elseif typeof(Data[1]) <: AbstractMaterialParam @@ -299,7 +307,7 @@ function Print_MaterialParam(io::IO, name::Symbol, Data) str = Data[i] if isa(str, AbstractComposite) # The CompositeRheology object is formatted a bit different - str = print_composite(Data[i],32) + str = print_composite(Data[i],32) end if i == 1 @@ -329,7 +337,7 @@ function Base.show(io::IO, phase::MaterialParams) end end -# Slightly nicer printout in case we have a tuple with material parameters +# Slightly nicer printout in case we have a tuple with material parameters function Base.show(io::IO, phase_tuple::NTuple{N,MaterialParams}) where {N} for i in 1:N Base.show(io, phase_tuple[i]) @@ -349,7 +357,7 @@ function print_composite(a, spaces=10) str = str.*"\n" for i=2:length(str) for j=1:spaces - str[i] = " "*str[i] + str[i] = " "*str[i] end end str = join(str) @@ -358,4 +366,3 @@ function print_composite(a, spaces=10) end end - diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl new file mode 100644 index 00000000..86f03417 --- /dev/null +++ b/src/Permeability/Permeability.jl @@ -0,0 +1,156 @@ +module Permeability + +using Parameters, Unitful, LaTeXStrings, MuladdMacro +using ..Units +using ..PhaseDiagrams +using GeoParams: AbstractMaterialParam, AbstractMaterialParamsStruct, @extractors, add_extractor_functions +import ..Units: isdimensional +using ..MaterialParameters: No_MaterialParam, MaterialParamsInfo +import Base.show, GeoParams.param_info + +include("../Computations.jl") + +abstract type AbstractPermeability{T} <: AbstractMaterialParam end + +export compute_permeability, # calculation routines + compute_permeability!, # in place calculation + param_info, # info about the parameters + AbstractPermeability, + ConstantPermeability, # constant + HazenPermeability, # Hazen equation + PowerLawPermeability, # Power-law permeability + CarmanKozenyPermeability # Carman-Kozeny permeability + +# Define "empty" computational routines in case nothing is defined +function compute_permeability!( + k::_T, s::No_MaterialParam{_T}; ϕ::_T=zero(_T) +) where {_T} + return zero(_T) +end +function compute_permeability(s::No_MaterialParam{_T}; ϕ::_T=zero(_T)) where {_T} + return zero(_T) +end + +# Constant Permeability +@with_kw_noshow struct ConstantPermeability{_T,U} <: AbstractPermeability{_T} + k::GeoUnit{_T,U} = 1e-12m^2 # permeability +end +ConstantPermeability(args...) = ConstantPermeability(convert.(GeoUnit, args)...) +isdimensional(s::ConstantPermeability) = isdimensional(s.k) + +@inline compute_permeability(s::ConstantPermeability{_T}, args) where {_T} = s(; args...) +@inline compute_permeability(s::ConstantPermeability{_T}) where {_T} = s() + +function param_info(s::ConstantPermeability) + return MaterialParamsInfo(; Equation=L"k = cst") +end + +function compute_permeability!(k::AbstractArray, s::ConstantPermeability; kwargs...) + @unpack_val k_val = s + k[:] .= k_val + return nothing +end + +function compute_permeability!(k::AbstractArray, s::ConstantPermeability, args) + return compute_permeability!(k, s; args...) +end + +function show(io::IO, g::ConstantPermeability) + return print(io, "Constant permeability: k=$(UnitValue(g.k))") +end + +# Hazen Permeability +@with_kw_noshow struct HazenPermeability{_T,U1,U2} <: AbstractPermeability{_T} + C::GeoUnit{_T,U1} = 1.0 # Hazen constant + D10::GeoUnit{_T,U2} = 1e-4m # Effective grain size +end +HazenPermeability(args...) = HazenPermeability(convert.(GeoUnit, args)...) +isdimensional(s::HazenPermeability) = isdimensional(s.C) + +function param_info(s::HazenPermeability) + return MaterialParamsInfo(; Equation = L"k = C \cdot D_{10}^2") +end + +function (s::HazenPermeability{_T})(; kwargs...) where {_T} + if kwargs isa Quantity + @unpack_units C, D10 = s + else + @unpack_val C, D10 = s + end + + return C * D10^2 +end + +@inline (s::HazenPermeability)(args) = s(; args...) +@inline compute_permeability(s::HazenPermeability, args) = s(args) + +function show(io::IO, g::HazenPermeability) + return print(io, "Hazen permeability: k = C * D10^2; C=$(g.C); D10=$(g.D10)") +end + +# Power-law Permeability +@with_kw_noshow struct PowerLawPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} + c::GeoUnit{_T,U1} = 1.0 # Power-law constant + k0::GeoUnit{_T,U1} = 1e-12m^2 # reference permeability + n::GeoUnit{_T,U3} = 3.0 # exponent +end +PowerLawPermeability(args...) = PowerLawPermeability(convert.(GeoUnit, args)...) +isdimensional(s::PowerLawPermeability) = isdimensional(s.k0) + +function param_info(s::PowerLawPermeability) + return MaterialParamsInfo(; Equation = L"k = c * k_0 * (\phi^n)") +end + +function (s::PowerLawPermeability{_T})(; ϕ=0e0, kwargs...) where {_T} + if ϕ isa Quantity + @unpack_units c, k0, n = s + else + @unpack_val c, k0, n = s + end + + return c * k0 * ϕ^n +end + +@inline (s::PowerLawPermeability)(args) = s(; args...) +@inline compute_permeability(s::PowerLawPermeability, args) = s(args) + +function show(io::IO, g::PowerLawPermeability) + return print(io, "Power-law permeability: k = c* k0 * ϕ^n; c = $(g.c), k0=$(g.k0); n=$(g.n)") +end + +# Carman-Kozeny Permeability +@with_kw_noshow struct CarmanKozenyPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} + c::GeoUnit{_T,U1} = 1.0 # Carman-Kozeny constant + ϕ0::GeoUnit{_T,U2} = 0.01 # reference porosity + n::GeoUnit{_T,U3} = 3.0 # exponent +end +CarmanKozenyPermeability(args...) = CarmanKozenyPermeability(convert.(GeoUnit, args)...) +isdimensional(s::CarmanKozenyPermeability) = isdimensional(s.c) + +function param_info(s::CarmanKozenyPermeability) + return MaterialParamsInfo(; Equation = L"k = c \left(\frac{\phi}{\phi_0}\right)^n") +end + +function (s::CarmanKozenyPermeability{_T})(; ϕ=1e-2, kwargs...) where {_T} + if ϕ isa Quantity + @unpack_units c, ϕ0, n = s + else + @unpack_val c, ϕ0, n = s + end + + return c * (ϕ / ϕ0)^n +end + +@inline (s::CarmanKozenyPermeability)(args) = s(; args...) +@inline compute_permeability(s::CarmanKozenyPermeability, args) = s(args) + +function show(io::IO, g::CarmanKozenyPermeability) + return print(io, "Carman-Kozeny permeability: k = c * (ϕ / ϕ0)^n; c=$(g.c); ϕ0=$(g.ϕ0); n=$(g.n)") +end + +# extractor methods +for type in (ConstantPermeability, HazenPermeability, PowerLawPermeability, CarmanKozenyPermeability) + @extractors(type, :Permeability) +end + +end From 7a58461c0ea409ff2fe82d7fd73c7ec0a60ebf07 Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Wed, 9 Oct 2024 17:39:14 +0200 Subject: [PATCH 03/11] add a few tests --- src/Permeability/Permeability.jl | 28 +++++------ src/aliases.jl | 1 + test/test_Permeability.jl | 79 ++++++++++++++++++++++++++++++++ 3 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 test/test_Permeability.jl diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl index 86f03417..1fbfa662 100644 --- a/src/Permeability/Permeability.jl +++ b/src/Permeability/Permeability.jl @@ -61,11 +61,11 @@ end # Hazen Permeability @with_kw_noshow struct HazenPermeability{_T,U1,U2} <: AbstractPermeability{_T} - C::GeoUnit{_T,U1} = 1.0 # Hazen constant - D10::GeoUnit{_T,U2} = 1e-4m # Effective grain size + C::GeoUnit{_T,U1} = 1.0 * NoUnits # Hazen constant + D10::GeoUnit{_T,U2} = 1e-4 * m # Effective grain size end HazenPermeability(args...) = HazenPermeability(convert.(GeoUnit, args)...) -isdimensional(s::HazenPermeability) = isdimensional(s.C) +isdimensional(s::HazenPermeability) = isdimensional(s.D10) function param_info(s::HazenPermeability) return MaterialParamsInfo(; Equation = L"k = C \cdot D_{10}^2") @@ -82,23 +82,25 @@ function (s::HazenPermeability{_T})(; kwargs...) where {_T} end @inline (s::HazenPermeability)(args) = s(; args...) -@inline compute_permeability(s::HazenPermeability, args) = s(args) +@inline compute_permeability(s::HazenPermeability, args) = s(; args...) + function show(io::IO, g::HazenPermeability) return print(io, "Hazen permeability: k = C * D10^2; C=$(g.C); D10=$(g.D10)") end # Power-law Permeability -@with_kw_noshow struct PowerLawPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} - c::GeoUnit{_T,U1} = 1.0 # Power-law constant - k0::GeoUnit{_T,U1} = 1e-12m^2 # reference permeability - n::GeoUnit{_T,U3} = 3.0 # exponent +@with_kw_noshow struct PowerLawPermeability{_T,U1,U2,U3, U4} <: AbstractPermeability{_T} + c::GeoUnit{_T,U1} = 1.0 * NoUnits # Power-law constant + k0::GeoUnit{_T,U2} = 1e-12 * m^2 # reference permeability + ϕ::GeoUnit{_T,U3} = 1e-2 * NoUnits # reference porosity + n::GeoUnit{_T,U4} = 3.0 * NoUnits # exponent end PowerLawPermeability(args...) = PowerLawPermeability(convert.(GeoUnit, args)...) isdimensional(s::PowerLawPermeability) = isdimensional(s.k0) function param_info(s::PowerLawPermeability) - return MaterialParamsInfo(; Equation = L"k = c * k_0 * (\phi^n)") + return MaterialParamsInfo(; Equation = L"k = c \cdot k_0 \cdot \phi^n") end function (s::PowerLawPermeability{_T})(; ϕ=0e0, kwargs...) where {_T} @@ -120,12 +122,12 @@ end # Carman-Kozeny Permeability @with_kw_noshow struct CarmanKozenyPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} - c::GeoUnit{_T,U1} = 1.0 # Carman-Kozeny constant - ϕ0::GeoUnit{_T,U2} = 0.01 # reference porosity - n::GeoUnit{_T,U3} = 3.0 # exponent + c::GeoUnit{_T,U1} = 1.0 * NoUnits # Carman-Kozeny constant + ϕ0::GeoUnit{_T,U2} = 0.01 * NoUnits # reference porosity + n::GeoUnit{_T,U3} = 3.0 * NoUnits # exponent end CarmanKozenyPermeability(args...) = CarmanKozenyPermeability(convert.(GeoUnit, args)...) -isdimensional(s::CarmanKozenyPermeability) = isdimensional(s.c) +# isdimensional(s::CarmanKozenyPermeability) = isdimensional(s.c) function param_info(s::CarmanKozenyPermeability) return MaterialParamsInfo(; Equation = L"k = c \left(\frac{\phi}{\phi_0}\right)^n") diff --git a/src/aliases.jl b/src/aliases.jl index 612ba50b..20282e7e 100644 --- a/src/aliases.jl +++ b/src/aliases.jl @@ -8,6 +8,7 @@ const VALID_KWARGS = ( :latent_heat, :radioactive_heat, :shearheating, + :permeability, :pwave_velocity, :swave_velocity, :meltfraction, diff --git a/test/test_Permeability.jl b/test/test_Permeability.jl new file mode 100644 index 00000000..34fefb96 --- /dev/null +++ b/test/test_Permeability.jl @@ -0,0 +1,79 @@ +using Test, GeoParams, Unitful, StaticArrays, LaTeXStrings + +@testset "Permeability.jl" begin + + # Set alias for permeability function + if !isdefined(Main, :GeoParamsAliases) + eval(:(@use GeoParamsAliases permeability = k)) + end + + # Make sure that structs are isbits + x = ConstantPermeability() + @test isbits(x) + @test param_info(x).Equation === L"k = cst" + @test isdimensional(x) === true + + x = HazenPermeability() + @test isbits(x) + @test param_info(x).Equation === L"k = C \cdot D_{10}^2" + @test isdimensional(x) === true + + x = PowerLawPermeability() + @test isbits(x) + @test param_info(x).Equation === L"k = c \cdot k_0 \cdot \phi^n" + @test isdimensional(x) === true + + x = CarmanKozenyPermeability() + @test isbits(x) + @test param_info(x).Equation === L"k = c \left(\frac{\phi}{\phi_0}\right)^n" + + # Test the permeability calculations with units + x1 = ConstantPermeability(; k=1e-12m^2) + @test x1.k.val == 1e-12 + @test GeoParams.get_k(x1) == 1e-12 + + x2 = HazenPermeability(; C=1.0, D10=1e-4m) + args = (;ϕ=0.4) + @test compute_permeability(x2, args) ≈ 1.0 * (0.1e-3)^2 + @test x2() ≈ 1.0 * (0.1e-3)^2 + + x3 = PowerLawPermeability(; c=1.0, k0=1e-12m^2, n=3.0) + args = (;ϕ=0.4) + @test compute_permeability(x3, args) ≈ 1.0 * 1.0e-12 * (0.4)^3 + @test x3(args) ≈ 1.0 * 1.0e-12 * (0.4)^3 + + x4 = CarmanKozenyPermeability(; c=1.0, ϕ0=0.3, n=3.0) + args = (;ϕ=0.4) + @test compute_permeability(x4, args) ≈ 1.0 * (0.4 / 0.3)^3 + @test x4(args) ≈ 1.0 * (0.4 / 0.3)^3 + + # Test the permeability calculations with non-dimensionalized units + CharUnits_GEO = GEO_units(; viscosity=1e19, length=1000km) + x1 = nondimensionalize(x1, CharUnits_GEO) + @test x1.k.val ≈ 1e-24 + + x2 = nondimensionalize(x2, CharUnits_GEO) + @test x2.C.val ≈ 1.0 + @test x2.D10.val ≈ 1e-10 + + x3 = nondimensionalize(x3, CharUnits_GEO) + @test x3.k0.val ≈ 1e-24 + + x4 = nondimensionalize(x4, CharUnits_GEO) + @test x4.c.val ≈ 1.0 + + # # Test allocations + # k = [0.0] + # ϕ = 0.4 + # args = (ϕ=ϕ) + + # # Test allocations using k alias + # k!(k, x3, args) + # num_alloc = @allocated k!(k, x3, args) + # @test num_alloc == 0 + + # k!(k, x4, args) + # num_alloc = @allocated k!(k, x4, args) + # @test num_alloc == 0 + +end From aad2443aae3063f231eaf5cf38968aa056ced592 Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Sat, 12 Oct 2024 12:47:42 +0200 Subject: [PATCH 04/11] update --- src/GeoParams.jl | 4 +- src/Permeability/Permeability.jl | 116 +++++++++++++++++++++++++++++-- src/Viscosity/BulkViscosity.jl | 20 ++++++ test/test_Permeability.jl | 4 +- 4 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 src/Viscosity/BulkViscosity.jl diff --git a/src/GeoParams.jl b/src/GeoParams.jl index aadc4929..116674b8 100644 --- a/src/GeoParams.jl +++ b/src/GeoParams.jl @@ -344,7 +344,9 @@ export compute_permeability, ConstantPermeability, HazenPermeability, PowerLawPermeability, - CarmanKozenyPermeability + CarmanKozenyPermeability, + BiotWillis, + SkemptonCoeff include("Traits/rheology.jl") export RheologyTrait diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl index 1fbfa662..0d565266 100644 --- a/src/Permeability/Permeability.jl +++ b/src/Permeability/Permeability.jl @@ -4,6 +4,7 @@ using Parameters, Unitful, LaTeXStrings, MuladdMacro using ..Units using ..PhaseDiagrams using GeoParams: AbstractMaterialParam, AbstractMaterialParamsStruct, @extractors, add_extractor_functions +using GeoParams: fastpow, pow_check, @pow import ..Units: isdimensional using ..MaterialParameters: No_MaterialParam, MaterialParamsInfo import Base.show, GeoParams.param_info @@ -19,7 +20,9 @@ export compute_permeability, # calculation routines ConstantPermeability, # constant HazenPermeability, # Hazen equation PowerLawPermeability, # Power-law permeability - CarmanKozenyPermeability # Carman-Kozeny permeability + CarmanKozenyPermeability, # Carman-Kozeny permeability + BiotWillis, # Biot-Willis coefficient + SkemptonCoeff # Skempton coefficient # Define "empty" computational routines in case nothing is defined function compute_permeability!( @@ -32,6 +35,25 @@ function compute_permeability(s::No_MaterialParam{_T}; ϕ::_T=zero(_T)) where {_ end # Constant Permeability +""" + ConstantPermeability(k = 1e-12m^2) + +Defines a constant permeability value for a given material. + +# Arguments +- `k::Float64`: The permeability value in square meters (m^2). Default is `1e-12 m^2`. + +# Example +```julia +rheology = SetMaterialParams(; + Phase=1, + CreepLaws=(PowerlawViscous(), LinearViscous(; η=1e21Pa * s)), + Gravity=ConstantGravity(; g=9.81.0m / s^2), + Density= MeltDependent_Density(), + Permeability = ConstantPermeability(; k=1e-12m^2), + ) +``` +""" @with_kw_noshow struct ConstantPermeability{_T,U} <: AbstractPermeability{_T} k::GeoUnit{_T,U} = 1e-12m^2 # permeability end @@ -78,7 +100,7 @@ function (s::HazenPermeability{_T})(; kwargs...) where {_T} @unpack_val C, D10 = s end - return C * D10^2 + return @pow C * D10^2 end @inline (s::HazenPermeability)(args) = s(; args...) @@ -94,7 +116,7 @@ end c::GeoUnit{_T,U1} = 1.0 * NoUnits # Power-law constant k0::GeoUnit{_T,U2} = 1e-12 * m^2 # reference permeability ϕ::GeoUnit{_T,U3} = 1e-2 * NoUnits # reference porosity - n::GeoUnit{_T,U4} = 3.0 * NoUnits # exponent + n::GeoUnit{_T,U4} = 3 * NoUnits # exponent end PowerLawPermeability(args...) = PowerLawPermeability(convert.(GeoUnit, args)...) isdimensional(s::PowerLawPermeability) = isdimensional(s.k0) @@ -110,7 +132,7 @@ function (s::PowerLawPermeability{_T})(; ϕ=0e0, kwargs...) where {_T} @unpack_val c, k0, n = s end - return c * k0 * ϕ^n + return @pow c * k0 * ϕ^n end @inline (s::PowerLawPermeability)(args) = s(; args...) @@ -122,9 +144,9 @@ end # Carman-Kozeny Permeability @with_kw_noshow struct CarmanKozenyPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} - c::GeoUnit{_T,U1} = 1.0 * NoUnits # Carman-Kozeny constant + c::GeoUnit{_T,U1} = 1.0 * m^2 # Carman-Kozeny constant ϕ0::GeoUnit{_T,U2} = 0.01 * NoUnits # reference porosity - n::GeoUnit{_T,U3} = 3.0 * NoUnits # exponent + n::GeoUnit{_T,U3} = 3 * NoUnits # exponent end CarmanKozenyPermeability(args...) = CarmanKozenyPermeability(convert.(GeoUnit, args)...) # isdimensional(s::CarmanKozenyPermeability) = isdimensional(s.c) @@ -140,7 +162,7 @@ function (s::CarmanKozenyPermeability{_T})(; ϕ=1e-2, kwargs...) where {_T} @unpack_val c, ϕ0, n = s end - return c * (ϕ / ϕ0)^n + return @pow c * (ϕ / ϕ0)^n end @inline (s::CarmanKozenyPermeability)(args) = s(; args...) @@ -150,6 +172,86 @@ function show(io::IO, g::CarmanKozenyPermeability) return print(io, "Carman-Kozeny permeability: k = c * (ϕ / ϕ0)^n; c=$(g.c); ϕ0=$(g.ϕ0); n=$(g.n)") end +# ----------------------------------------------- +# This implements the methods described by Yarushina and Podladchikov, 2015 +""" +Biot-Willis coefficient +""" +@with_kw_noshow struct BiotWillis{_T,U} <: AbstractPermeability{_T} + Kd::GeoUnit{_T,U} = 1.0 * Pa # Drained bulk modulus + Ks::GeoUnit{_T,U} = 1.0 * Pa # Solid grain bulk modulus + α::GeoUnit{_T,U} = 1.0 * NoUnits # Biot-Willis coefficient to keep track of dimensionality +end + +BiotWillis(args...) = BiotWillis(convert.(GeoUnit, args)...) +isdimensional(s::BiotWillis) = isdimensional(s.Kd) + +function param_info(s::BiotWillis) + return MaterialParamsInfo(; Equation = L"\alpha = 1 - \frac{K_d}{K_s}") +end + +function (bw::BiotWillis{_T})(; kwargs...) where {_T} + if kwargs isa Quantity + @unpack_units Kd, Ks, α = bw + else + @unpack_val Kd, Ks, α = bw + end + + return 1 - (Kd * inv(Ks)) +end + +@inline (s::BiotWillis)(args) = s(; args...) +@inline compute_biot_willis(s::BiotWillis, args) = s(args) + +function show(io::IO, g::BiotWillis) + return print(io, "Biot-Willis coefficient: α = 1 - (Kd / Ks); Kd=$(g.Kd); Ks=$(g.Ks)") +end + +""" +Skempton coefficient +""" +@with_kw_noshow struct SkemptonCoeff{_T,U} <: AbstractPermeability{_T} + Kd::GeoUnit{_T,U} = 1.0 * Pa # Drained bulk modulus + Ks::GeoUnit{_T,U} = 1.0 * Pa # Solid grain bulk modulus + Kf::GeoUnit{_T,U} = 1.0 * Pa # Fluid bulk modulus + ϕ::GeoUnit{_T,U} = 1.0 * NoUnits # Porosity + B::GeoUnit{_T,U} = 1.0 * Pa # Skempton coefficient to keep track of dimensionality +end + +SkemptonCoeff(args...) = SkemptonCoeff(convert.(GeoUnit, args)...) +isdimensional(s::SkemptonCoeff) = isdimensional(s.Kd) + +function param_info(s::SkemptonCoeff) + return MaterialParamsInfo(; Equation = L"B = \frac{(1/K_d - 1/K_s)}{(1/K_d - 1/K_s) + \phi (1/K_f - 1/K_s)}") +end + +function (sc::SkemptonCoeff{_T})(; kwargs...) where {_T} + if kwargs isa Quantity + @unpack_units Kd, Ks, Kf, ϕ, B = sc + else + @unpack_val Kd, Ks, Kf, ϕ, B = sc + end + + return (inv(Kd) - inv(Ks)) * inv(inv(Kd) - inv(Ks) + ϕ * (inv(Kf) - inv(Ks))) +end + +@inline (s::SkemptonCoeff)(args) = s(; args...) +@inline compute_skempton_coeff(s::SkemptonCoeff, args) = s(args) + +function show(io::IO, g::SkemptonCoeff) + return print(io, "Skempton Coefficient: B = (1/Kd - 1/Ks) / ((1/Kd - 1/Ks) + ϕ * (1/Kf - 1/Ks)); Kd=$(g.Kd); Ks=$(g.Ks); Kf=$(g.Kf); ϕ=$(g.ϕ)") +end + +""" + compute_permeability!(k::AbstractArray{_T, N}, MatParam::NTuple{K,AbstractMaterialParamsStruct}, PhaseRatios::AbstractArray{_T, M}, P=nothing, T=nothing) + +In-place computation of permeability `k` for the whole domain and all phases, in case a vector with phase properties `MatParam` is provided, along with `P` and `T` arrays. +This assumes that the `PhaseRatio` of every point is specified as an Integer in the `PhaseRatios` array, which has one dimension more than the data arrays (and has a phase fraction between 0-1) +""" +@inline compute_permeability!(args::Vararg{Any, N}) where N = compute_param!(compute_permeability, args...) +@inline compute_permeability(args::Vararg{Any, N}) where N = compute_param(compute_permeability, args...) +@inline compute_permeability_ratio(args::Vararg{Any, N}) where N = compute_param_times_frac(compute_permeability, args...) + # extractor methods for type in (ConstantPermeability, HazenPermeability, PowerLawPermeability, CarmanKozenyPermeability) @extractors(type, :Permeability) diff --git a/src/Viscosity/BulkViscosity.jl b/src/Viscosity/BulkViscosity.jl new file mode 100644 index 00000000..7774c389 --- /dev/null +++ b/src/Viscosity/BulkViscosity.jl @@ -0,0 +1,20 @@ +""" +bulk_viscosity(η_shear, ϕ, C, R, λ, P_eff) + +# η_shear: shear viscosity +# ϕ: porosity +# C: shear viscosity ratio (value, dimensionless) +# R: compaction strength ratio (value, dimensionless) +# λ: effective pressure transition zone +# P_eff: effective Pressure +""" +function bulk_viscosity(η_shear, ϕ, C, R, λ, P_eff) + + η_bulk = η_shear / ϕ * C * (1.0 + 0.5 * (inv(R) - 1.0) * (1.0 + tanh(-P_eff * inv(λ)))) + + return η_bulk +end + + +### Georg Adjoint 2 pahse paper, +### Ludo's 2019 paper has it quite nicely also with a calc for R diff --git a/test/test_Permeability.jl b/test/test_Permeability.jl index 34fefb96..7704389e 100644 --- a/test/test_Permeability.jl +++ b/test/test_Permeability.jl @@ -37,12 +37,12 @@ using Test, GeoParams, Unitful, StaticArrays, LaTeXStrings @test compute_permeability(x2, args) ≈ 1.0 * (0.1e-3)^2 @test x2() ≈ 1.0 * (0.1e-3)^2 - x3 = PowerLawPermeability(; c=1.0, k0=1e-12m^2, n=3.0) + x3 = PowerLawPermeability(; c=1.0, k0=1e-12m^2, n=3) args = (;ϕ=0.4) @test compute_permeability(x3, args) ≈ 1.0 * 1.0e-12 * (0.4)^3 @test x3(args) ≈ 1.0 * 1.0e-12 * (0.4)^3 - x4 = CarmanKozenyPermeability(; c=1.0, ϕ0=0.3, n=3.0) + x4 = CarmanKozenyPermeability(; c=1.0, ϕ0=0.3, n=3) args = (;ϕ=0.4) @test compute_permeability(x4, args) ≈ 1.0 * (0.4 / 0.3)^3 @test x4(args) ≈ 1.0 * (0.4 / 0.3)^3 From e8d5668a7f72cb0e4c1669dcc44747a9aadf62a1 Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Thu, 17 Oct 2024 17:28:52 +0200 Subject: [PATCH 05/11] update to working tests --- src/GeoParams.jl | 1 + src/Permeability/Permeability.jl | 84 +++++--------------------------- test/test_Permeability.jl | 52 +++++++++++++++----- 3 files changed, 52 insertions(+), 85 deletions(-) diff --git a/src/GeoParams.jl b/src/GeoParams.jl index 116674b8..eb9fda4e 100644 --- a/src/GeoParams.jl +++ b/src/GeoParams.jl @@ -339,6 +339,7 @@ export compute_meltfraction, using .MaterialParameters.Permeability export compute_permeability, compute_permeability!, + compute_permeability_ratio, param_info, AbstractPermeability, ConstantPermeability, diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl index 0d565266..878ebe30 100644 --- a/src/Permeability/Permeability.jl +++ b/src/Permeability/Permeability.jl @@ -15,14 +15,13 @@ abstract type AbstractPermeability{T} <: AbstractMaterialParam end export compute_permeability, # calculation routines compute_permeability!, # in place calculation + compute_permeability_ratio, # calculation with phase ratios param_info, # info about the parameters AbstractPermeability, ConstantPermeability, # constant HazenPermeability, # Hazen equation PowerLawPermeability, # Power-law permeability - CarmanKozenyPermeability, # Carman-Kozeny permeability - BiotWillis, # Biot-Willis coefficient - SkemptonCoeff # Skempton coefficient + CarmanKozenyPermeability # Carman-Kozeny permeability # Define "empty" computational routines in case nothing is defined function compute_permeability!( @@ -60,6 +59,8 @@ end ConstantPermeability(args...) = ConstantPermeability(convert.(GeoUnit, args)...) isdimensional(s::ConstantPermeability) = isdimensional(s.k) +@inline (s::ConstantPermeability)(; args...) = s.k.val +@inline (s::ConstantPermeability)(args) = s(; args...) @inline compute_permeability(s::ConstantPermeability{_T}, args) where {_T} = s(; args...) @inline compute_permeability(s::ConstantPermeability{_T}) where {_T} = s() @@ -104,7 +105,7 @@ function (s::HazenPermeability{_T})(; kwargs...) where {_T} end @inline (s::HazenPermeability)(args) = s(; args...) -@inline compute_permeability(s::HazenPermeability, args) = s(; args...) +@inline compute_permeability(s::HazenPermeability, args) = s(args) function show(io::IO, g::HazenPermeability) @@ -125,7 +126,7 @@ function param_info(s::PowerLawPermeability) return MaterialParamsInfo(; Equation = L"k = c \cdot k_0 \cdot \phi^n") end -function (s::PowerLawPermeability{_T})(; ϕ=0e0, kwargs...) where {_T} +function (s::PowerLawPermeability{_T})(; ϕ=1e-2, kwargs...) where {_T} if ϕ isa Quantity @unpack_units c, k0, n = s else @@ -172,75 +173,12 @@ function show(io::IO, g::CarmanKozenyPermeability) return print(io, "Carman-Kozeny permeability: k = c * (ϕ / ϕ0)^n; c=$(g.c); ϕ0=$(g.ϕ0); n=$(g.n)") end -# ----------------------------------------------- -# This implements the methods described by Yarushina and Podladchikov, 2015 -""" -Biot-Willis coefficient -""" -@with_kw_noshow struct BiotWillis{_T,U} <: AbstractPermeability{_T} - Kd::GeoUnit{_T,U} = 1.0 * Pa # Drained bulk modulus - Ks::GeoUnit{_T,U} = 1.0 * Pa # Solid grain bulk modulus - α::GeoUnit{_T,U} = 1.0 * NoUnits # Biot-Willis coefficient to keep track of dimensionality -end - -BiotWillis(args...) = BiotWillis(convert.(GeoUnit, args)...) -isdimensional(s::BiotWillis) = isdimensional(s.Kd) - -function param_info(s::BiotWillis) - return MaterialParamsInfo(; Equation = L"\alpha = 1 - \frac{K_d}{K_s}") -end - -function (bw::BiotWillis{_T})(; kwargs...) where {_T} - if kwargs isa Quantity - @unpack_units Kd, Ks, α = bw - else - @unpack_val Kd, Ks, α = bw - end - - return 1 - (Kd * inv(Ks)) -end - -@inline (s::BiotWillis)(args) = s(; args...) -@inline compute_biot_willis(s::BiotWillis, args) = s(args) - -function show(io::IO, g::BiotWillis) - return print(io, "Biot-Willis coefficient: α = 1 - (Kd / Ks); Kd=$(g.Kd); Ks=$(g.Ks)") -end - -""" -Skempton coefficient -""" -@with_kw_noshow struct SkemptonCoeff{_T,U} <: AbstractPermeability{_T} - Kd::GeoUnit{_T,U} = 1.0 * Pa # Drained bulk modulus - Ks::GeoUnit{_T,U} = 1.0 * Pa # Solid grain bulk modulus - Kf::GeoUnit{_T,U} = 1.0 * Pa # Fluid bulk modulus - ϕ::GeoUnit{_T,U} = 1.0 * NoUnits # Porosity - B::GeoUnit{_T,U} = 1.0 * Pa # Skempton coefficient to keep track of dimensionality -end - -SkemptonCoeff(args...) = SkemptonCoeff(convert.(GeoUnit, args)...) -isdimensional(s::SkemptonCoeff) = isdimensional(s.Kd) - -function param_info(s::SkemptonCoeff) - return MaterialParamsInfo(; Equation = L"B = \frac{(1/K_d - 1/K_s)}{(1/K_d - 1/K_s) + \phi (1/K_f - 1/K_s)}") -end - -function (sc::SkemptonCoeff{_T})(; kwargs...) where {_T} - if kwargs isa Quantity - @unpack_units Kd, Ks, Kf, ϕ, B = sc - else - @unpack_val Kd, Ks, Kf, ϕ, B = sc - end - - return (inv(Kd) - inv(Ks)) * inv(inv(Kd) - inv(Ks) + ϕ * (inv(Kf) - inv(Ks))) -end - -@inline (s::SkemptonCoeff)(args) = s(; args...) -@inline compute_skempton_coeff(s::SkemptonCoeff, args) = s(args) - -function show(io::IO, g::SkemptonCoeff) - return print(io, "Skempton Coefficient: B = (1/Kd - 1/Ks) / ((1/Kd - 1/Ks) + ϕ * (1/Kf - 1/Ks)); Kd=$(g.Kd); Ks=$(g.Ks); Kf=$(g.Kf); ϕ=$(g.ϕ)") +#------------------------------------------------------------------------------------------------------------------# +# Computational routines needed for computations with the MaterialParams structure +function compute_permeability(s::AbstractMaterialParamsStruct, args) + return compute_permeability(s.Permeability[1], args) end +#------------------------------------------------------------------------------------------------------------- """ compute_permeability!(k::AbstractArray{_T, N}, MatParam::NTuple{K,AbstractMaterialParamsStruct}, PhaseRatios::AbstractArray{_T, M}, P=nothing, T=nothing) diff --git a/test/test_Permeability.jl b/test/test_Permeability.jl index 7704389e..bca04325 100644 --- a/test/test_Permeability.jl +++ b/test/test_Permeability.jl @@ -31,6 +31,7 @@ using Test, GeoParams, Unitful, StaticArrays, LaTeXStrings x1 = ConstantPermeability(; k=1e-12m^2) @test x1.k.val == 1e-12 @test GeoParams.get_k(x1) == 1e-12 + @test compute_permeability(x1) ≈ 1e-12 x2 = HazenPermeability(; C=1.0, D10=1e-4m) args = (;ϕ=0.4) @@ -62,18 +63,45 @@ using Test, GeoParams, Unitful, StaticArrays, LaTeXStrings x4 = nondimensionalize(x4, CharUnits_GEO) @test x4.c.val ≈ 1.0 - # # Test allocations - # k = [0.0] - # ϕ = 0.4 - # args = (ϕ=ϕ) - # # Test allocations using k alias - # k!(k, x3, args) - # num_alloc = @allocated k!(k, x3, args) - # @test num_alloc == 0 - - # k!(k, x4, args) - # num_alloc = @allocated k!(k, x4, args) - # @test num_alloc == 0 + # Define material parameters with different permeability parameterizations + Mat_tup = ( + SetMaterialParams(; + Name="Mantle", Phase=1, Permeability=ConstantPermeability(; k=1e-12m^2) + ), + SetMaterialParams(; Name="Crust", Phase=2, Permeability=HazenPermeability(; C=1.0, D10=1e-4m)), + SetMaterialParams(; + Name="UpperCrust", + Phase=3, + Permeability=PowerLawPermeability(; c=1.0, k0=1e-12m^2, n=3, ϕ=0.1), + Density=PT_Density(), + ), + SetMaterialParams(; Name="LowerCrust", Phase=4, Permeability=CarmanKozenyPermeability(; c=1.0, ϕ0=0.3, n=3), Density=PT_Density()), + ) + + n = 100 + Phases = ones(Int64, n, n, n) + Phases[:, :, 20:end] .= 2 + Phases[:, :, 50:end] .= 3 + Phases[:, :, 70:end] .= 4 + + ϕ = fill(1e-2, size(Phases)) + T = ones(size(Phases)) * (800 + 273.15) + P = ones(size(Phases)) * 10 + args = (P=P, T=T) + + @test compute_permeability(Mat_tup, Phases[1], args) == 1e-12 + + compute_permeability!(ϕ, Mat_tup, Phases, args) + + @test sum(ϕ) / n^3 ≈ 1.1484481671481687e-5 # Adjust this value based on expected results + + # Test PhaseRatio and StaticArrays PhaseRatios as input + args = (P=0.0, T=1000.0 + 273.15) + PhaseRatio = (0.25, 0.25, 0.25, 0.25) + @test compute_permeability_ratio(PhaseRatio, Mat_tup, args) == 9.26175950925951e-6 # Adjust this value based on expected results + + SvPhaseRatio = SA[0.25,0.25,0.25,0.25] + @test compute_permeability_ratio(SvPhaseRatio, Mat_tup, args) == 9.26175950925951e-6 # Adjust this value based on expected results end From eb2b85aa8f21b100a3b0be04b0a722689de5ae0a Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Thu, 17 Oct 2024 17:42:13 +0200 Subject: [PATCH 06/11] delete obsolete code --- src/GeoParams.jl | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/GeoParams.jl b/src/GeoParams.jl index eb9fda4e..98f33e7d 100644 --- a/src/GeoParams.jl +++ b/src/GeoParams.jl @@ -345,9 +345,7 @@ export compute_permeability, ConstantPermeability, HazenPermeability, PowerLawPermeability, - CarmanKozenyPermeability, - BiotWillis, - SkemptonCoeff + CarmanKozenyPermeability include("Traits/rheology.jl") export RheologyTrait From 58bb9e7514335690897d0bf72098747721be6e85 Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Thu, 17 Oct 2024 17:58:44 +0200 Subject: [PATCH 07/11] rm Unitful --- test/test_Permeability.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_Permeability.jl b/test/test_Permeability.jl index bca04325..316cd6ee 100644 --- a/test/test_Permeability.jl +++ b/test/test_Permeability.jl @@ -1,4 +1,4 @@ -using Test, GeoParams, Unitful, StaticArrays, LaTeXStrings +using Test, GeoParams, StaticArrays, LaTeXStrings @testset "Permeability.jl" begin From 43ad526c5bf555195d922b12821a504f4f7a012d Mon Sep 17 00:00:00 2001 From: Pascal Aellig <93140290+aelligp@users.noreply.github.com> Date: Fri, 18 Oct 2024 16:18:02 +0200 Subject: [PATCH 08/11] Apply suggestions pt 1 Co-authored-by: Albert de Montserrat <58044444+albert-de-montserrat@users.noreply.github.com> --- src/Permeability/Permeability.jl | 20 ++++++++++---------- test/test_Permeability.jl | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl index 878ebe30..ef746746 100644 --- a/src/Permeability/Permeability.jl +++ b/src/Permeability/Permeability.jl @@ -84,8 +84,8 @@ end # Hazen Permeability @with_kw_noshow struct HazenPermeability{_T,U1,U2} <: AbstractPermeability{_T} - C::GeoUnit{_T,U1} = 1.0 * NoUnits # Hazen constant - D10::GeoUnit{_T,U2} = 1e-4 * m # Effective grain size + C::GeoUnit{_T,U1} = 1.0 * NoUnits # Hazen constant + D10::GeoUnit{_T,U2} = 1e-4 * m # Effective grain size end HazenPermeability(args...) = HazenPermeability(convert.(GeoUnit, args)...) isdimensional(s::HazenPermeability) = isdimensional(s.D10) @@ -101,7 +101,7 @@ function (s::HazenPermeability{_T})(; kwargs...) where {_T} @unpack_val C, D10 = s end - return @pow C * D10^2 + return C * D10^2 end @inline (s::HazenPermeability)(args) = s(; args...) @@ -114,10 +114,10 @@ end # Power-law Permeability @with_kw_noshow struct PowerLawPermeability{_T,U1,U2,U3, U4} <: AbstractPermeability{_T} - c::GeoUnit{_T,U1} = 1.0 * NoUnits # Power-law constant - k0::GeoUnit{_T,U2} = 1e-12 * m^2 # reference permeability - ϕ::GeoUnit{_T,U3} = 1e-2 * NoUnits # reference porosity - n::GeoUnit{_T,U4} = 3 * NoUnits # exponent + c::GeoUnit{_T,U1} = 1.0 * NoUnits # Power-law constant + k0::GeoUnit{_T,U2} = 1e-12 * m^2 # reference permeability + ϕ::GeoUnit{_T,U3} = 1e-2 * NoUnits # reference porosity + n::GeoUnit{_T,U4} = 3 * NoUnits # exponent end PowerLawPermeability(args...) = PowerLawPermeability(convert.(GeoUnit, args)...) isdimensional(s::PowerLawPermeability) = isdimensional(s.k0) @@ -146,8 +146,8 @@ end # Carman-Kozeny Permeability @with_kw_noshow struct CarmanKozenyPermeability{_T,U1,U2,U3} <: AbstractPermeability{_T} c::GeoUnit{_T,U1} = 1.0 * m^2 # Carman-Kozeny constant - ϕ0::GeoUnit{_T,U2} = 0.01 * NoUnits # reference porosity - n::GeoUnit{_T,U3} = 3 * NoUnits # exponent + ϕ0::GeoUnit{_T,U2} = 0.01 * NoUnits # reference porosity + n::GeoUnit{_T,U3} = 3 * NoUnits # exponent end CarmanKozenyPermeability(args...) = CarmanKozenyPermeability(convert.(GeoUnit, args)...) # isdimensional(s::CarmanKozenyPermeability) = isdimensional(s.c) @@ -166,7 +166,7 @@ function (s::CarmanKozenyPermeability{_T})(; ϕ=1e-2, kwargs...) where {_T} return @pow c * (ϕ / ϕ0)^n end -@inline (s::CarmanKozenyPermeability)(args) = s(; args...) +@inline (s::CarmanKozenyPermeability)(args) = s(; args...) @inline compute_permeability(s::CarmanKozenyPermeability, args) = s(args) function show(io::IO, g::CarmanKozenyPermeability) diff --git a/test/test_Permeability.jl b/test/test_Permeability.jl index 316cd6ee..ca27c20a 100644 --- a/test/test_Permeability.jl +++ b/test/test_Permeability.jl @@ -86,8 +86,8 @@ using Test, GeoParams, StaticArrays, LaTeXStrings Phases[:, :, 70:end] .= 4 ϕ = fill(1e-2, size(Phases)) - T = ones(size(Phases)) * (800 + 273.15) - P = ones(size(Phases)) * 10 + T = fill((800 + 273.15), size(Phases)) + P = fill(10, size(Phases)) args = (P=P, T=T) @test compute_permeability(Mat_tup, Phases[1], args) == 1e-12 From 6d679e20cef9950d17796cd87a56bfb98840e72a Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Fri, 18 Oct 2024 16:20:49 +0200 Subject: [PATCH 09/11] address suggestions pt 2 --- src/Permeability/Permeability.jl | 4 ++-- test/test_Permeability.jl | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl index ef746746..53c45db2 100644 --- a/src/Permeability/Permeability.jl +++ b/src/Permeability/Permeability.jl @@ -4,7 +4,7 @@ using Parameters, Unitful, LaTeXStrings, MuladdMacro using ..Units using ..PhaseDiagrams using GeoParams: AbstractMaterialParam, AbstractMaterialParamsStruct, @extractors, add_extractor_functions -using GeoParams: fastpow, pow_check, @pow +using GeoParams: fastpow, pow_check, @pow, @fastpow import ..Units: isdimensional using ..MaterialParameters: No_MaterialParam, MaterialParamsInfo import Base.show, GeoParams.param_info @@ -133,7 +133,7 @@ function (s::PowerLawPermeability{_T})(; ϕ=1e-2, kwargs...) where {_T} @unpack_val c, k0, n = s end - return @pow c * k0 * ϕ^n + return @fastpow c * k0 * ϕ^n end @inline (s::PowerLawPermeability)(args) = s(; args...) diff --git a/test/test_Permeability.jl b/test/test_Permeability.jl index ca27c20a..068eb75a 100644 --- a/test/test_Permeability.jl +++ b/test/test_Permeability.jl @@ -2,11 +2,6 @@ using Test, GeoParams, StaticArrays, LaTeXStrings @testset "Permeability.jl" begin - # Set alias for permeability function - if !isdefined(Main, :GeoParamsAliases) - eval(:(@use GeoParamsAliases permeability = k)) - end - # Make sure that structs are isbits x = ConstantPermeability() @test isbits(x) From 035fe071e7e5dd129e664b5812caa70064db5662 Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Fri, 18 Oct 2024 16:33:09 +0200 Subject: [PATCH 10/11] correct syntax --- src/Permeability/Permeability.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Permeability/Permeability.jl b/src/Permeability/Permeability.jl index 53c45db2..36926553 100644 --- a/src/Permeability/Permeability.jl +++ b/src/Permeability/Permeability.jl @@ -4,7 +4,7 @@ using Parameters, Unitful, LaTeXStrings, MuladdMacro using ..Units using ..PhaseDiagrams using GeoParams: AbstractMaterialParam, AbstractMaterialParamsStruct, @extractors, add_extractor_functions -using GeoParams: fastpow, pow_check, @pow, @fastpow +using GeoParams: fastpow, pow_check, @pow import ..Units: isdimensional using ..MaterialParameters: No_MaterialParam, MaterialParamsInfo import Base.show, GeoParams.param_info @@ -133,7 +133,7 @@ function (s::PowerLawPermeability{_T})(; ϕ=1e-2, kwargs...) where {_T} @unpack_val c, k0, n = s end - return @fastpow c * k0 * ϕ^n + return c * k0 * fastpow(ϕ,n) end @inline (s::PowerLawPermeability)(args) = s(; args...) From ebfe9cfa6e71c125751314a684c8a4f67a86eb81 Mon Sep 17 00:00:00 2001 From: Pascal Aellig Date: Fri, 18 Oct 2024 16:52:01 +0200 Subject: [PATCH 11/11] delete bulkviscosity file that slipped in --- src/Viscosity/BulkViscosity.jl | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/Viscosity/BulkViscosity.jl diff --git a/src/Viscosity/BulkViscosity.jl b/src/Viscosity/BulkViscosity.jl deleted file mode 100644 index 7774c389..00000000 --- a/src/Viscosity/BulkViscosity.jl +++ /dev/null @@ -1,20 +0,0 @@ -""" -bulk_viscosity(η_shear, ϕ, C, R, λ, P_eff) - -# η_shear: shear viscosity -# ϕ: porosity -# C: shear viscosity ratio (value, dimensionless) -# R: compaction strength ratio (value, dimensionless) -# λ: effective pressure transition zone -# P_eff: effective Pressure -""" -function bulk_viscosity(η_shear, ϕ, C, R, λ, P_eff) - - η_bulk = η_shear / ϕ * C * (1.0 + 0.5 * (inv(R) - 1.0) * (1.0 + tanh(-P_eff * inv(λ)))) - - return η_bulk -end - - -### Georg Adjoint 2 pahse paper, -### Ludo's 2019 paper has it quite nicely also with a calc for R