Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create SingleTPM and BinaryTPM #74

Merged
merged 8 commits into from
Oct 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/AsteroidThermoPhysicalModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ include("shape.jl")
include("facet.jl")
export ShapeModel, load_shape_obj

include("thermophysics.jl")
include("thermo_params.jl")
include("TPM.jl")
include("thermophysics.jl")
include("energy_flux.jl")
include("non_grav.jl")
export thermal_skin_depth, thermal_inertia, init_temperature!, run_TPM!
Expand Down
215 changes: 156 additions & 59 deletions src/TPM.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,95 @@



abstract type ThermoPhysicalModel end


"""
struct SingleTPM <: ThermoPhysicalModel

#Fields
- `shape` : Shape model
- `thermo_params` : Thermophysical parameters

- `flux` : Flux on each face. Matrix of size (Number of faces, 3). Three components are:
- `flux[:, 1]` : F_sun, flux of direct sunlight
- `flux[:, 2]` : F_scat, flux of scattered light
- `flux[:, 3]` : F_rad, flux of thermal emission from surrounding surface
- `temperature` : 3D array in size of (Nz, Ns, Nt). Temperature according to depth cells (Nz), faces (Ns), and time steps in one periodic cycle (Nt).
- ⋅----------⋅
- Nt / /|
- ⋅--- Ns ---⋅ |
- | | |
- Nz | | ⋅
- | |/
- ⋅----------⋅

- `face_forces` : Thermal force on each face
- `force` : Thermal recoil force at body-fixed frame (Yarkovsky effect)
- `torque` : Thermal recoil torque at body-fixed frame (YORP effect)

- `SELF_SHADOWING` : Flag to consider self-shadowing
- `SELF_HEATING` : Flag to consider self-heating

# TO DO:
- 同時に time step と depth step に関するベクトルをもつのが良いかもしれない
- roughness_maps ::ShapeModel[]
"""
struct SingleTPM <: ThermoPhysicalModel
shape ::ShapeModel
thermo_params ::Union{UniformThermoParams, NonUniformThermoParams}

flux ::Matrix{Float64} # (Ns, 3)
temperature ::Array{Float64, 3} # (Nz, Ns, Nt)

face_forces ::Vector{SVector{3, Float64}}
force ::MVector{3, Float64}
torque ::MVector{3, Float64}

SELF_SHADOWING ::Bool
SELF_HEATING ::Bool
end


function SingleTPM(shape, thermo_params, SELF_SHADOWING, SELF_HEATING)

Nz = thermo_params.Nz
Ns = length(shape.faces)
Nt = thermo_params.Nt

flux = zeros(Ns, 3)
temperature = zeros(Nz, Ns, Nt)

face_forces = [zero(SVector{3, Float64}) for _ in shape.faces]
force = zero(MVector{3, Float64})
torque = zero(MVector{3, Float64})

SingleTPM(shape, thermo_params, flux, temperature, face_forces, force, torque, SELF_SHADOWING, SELF_HEATING)
end


"""
struct BinaryTPM <: ThermoPhysicalModel

#Fields
- `pri` : TPM for the primary
- `sec` : TPM for the secondary
- `MUTUAL_SHADOWING` : Flag to consider mutual shadowing
- `MUTUAL_HEATING` : Flag to consider mutual heating
"""
struct BinaryTPM <: ThermoPhysicalModel
pri ::SingleTPM
sec ::SingleTPM

MUTUAL_SHADOWING ::Bool
MUTUAL_HEATING ::Bool
end


surface_temperature(stpm::SingleTPM, nₜ::Integer) = stpm.temperature[begin, :, nₜ]
surface_temperature(stpm::SingleTPM) = stpm.temperature[begin, :, end]


# ****************************************************************
# Initialize temperatures
# ****************************************************************
Expand All @@ -23,40 +112,31 @@ end


"""
init_temperature_zero!(shape::ShapeModel, params::AbstractThermoParams)
init_temperature!(stpm::SingleTPM, T₀::Real)

Initialize all temperature cells at 0 K.
Initialize all temperature cells at the given temperature `T₀`
"""
function init_temperature_zero!(shape::ShapeModel, params::AbstractThermoParams)
Nz = params.Nz
Ns = length(shape.faces)
Nt = params.Nt

if size(shape.temperature) == (0, 0, 0)
shape.temperature = zeros(Nz, Ns, Nt)
elseif size(shape.temperature) == (Nz, Ns, Nt)
shape.temperature .= 0.
else
error("ShapeModel.temperature has a wrong size.")
end
function init_temperature!(stpm::SingleTPM, T₀::Real)
stpm.temperature[:, :, :] .= T₀
end


"""
init_temperature!(shape::ShapeModel, params::AbstractThermoParams, T₀::Real)
init_temperature!(btpm::BinaryTPM, T₀::Real)

Initialize all temperature cells at the given temperature `T₀`
"""
function init_temperature!(shape::ShapeModel, params::AbstractThermoParams, T₀::Real)
init_temperature_zero!(shape, params)
shape.temperature[:, :, :] .= T₀
function init_temperature!(btpm::BinaryTPM, T₀::Real)
btpm.pri.temperature[:, :, :] .= T₀
btpm.sec.temperature[:, :, :] .= T₀
end


# ****************************************************************
# Thermophysical modeling
# ****************************************************************


# """
# """
# function run_TPM!(shape::ShapeModel, orbit::OrbitalElements, spin::SpinParams, thermo_params::AbstractThermoParams, savepath="tmp.jld2")
Expand Down Expand Up @@ -101,17 +181,20 @@ end
# end

"""
- `shape` : Shape model
- `et_range` : Range of ephemeris times to run
- `sun` : Sun's position in the body-fixed frame at epochs (Not normalized)
- `thermo_params` : Thermophysical parametes
- `savepath` : Path to save data file
- `save_range` : Indices in `et_range` to be saved
run_TPM!(stpm::SingleTPM, ephem, savepath)

Run TPM for a single asteroid.

# Arguments
- `stpm` : Thermophysical model for a single asteroid
- `ephem` : Ephemerides
- `ephem.time` : Ephemeris times
- `ephem.sun` : Sun's position in the asteroid-fixed frame (Not normalized)
- `savepath` : Path to save data file
"""
function run_TPM!(shape::ShapeModel, thermo_params::AbstractThermoParams, ephem, savepath)
function run_TPM!(stpm::SingleTPM, ephem, savepath)

surf_temps = zeros(length(shape.faces), length(ephem.time))
surf_temps = zeros(length(stpm.shape.faces), length(ephem.time))
forces = [zeros(3) for _ in eachindex(ephem.time)]
torques = [zeros(3) for _ in eachindex(ephem.time)]

Expand All @@ -120,44 +203,52 @@ function run_TPM!(shape::ShapeModel, thermo_params::AbstractThermoParams, ephem,
ProgressMeter.ijulia_behavior(:clear)

for nₜ in eachindex(ephem.time)
et = ephem.time[nₜ]
r☉ = ephem.sun[nₜ]

update_flux!(shape, r☉, thermo_params, nₜ)
update_thermal_force!(shape, thermo_params, nₜ)
update_flux_sun!(stpm, r☉)
update_flux_scat_single!(stpm)
update_flux_rad_single!(stpm, nₜ)

update_thermal_force!(stpm, nₜ)

## Save data
surf_temps[:, nₜ] .= surface_temperature(shape, nₜ)
forces[nₜ] .= shape.force # Body-fixed frame
torques[nₜ] .= shape.torque # Body-fixed frame

E_in, E_out, E_cons = energy_io(shape, thermo_params, nₜ)
surf_temps[:, nₜ] .= surface_temperature(stpm, nₜ)
forces[nₜ] .= stpm.force # Body-fixed frame
torques[nₜ] .= stpm.torque # Body-fixed frame

## Energy input/output
E_in, E_out, E_cons = energy_io(stpm, nₜ)

## Update the progress meter
showvalues = [("Timestep", nₜ), ("E_cons = E_out / E_in", E_cons)]
ProgressMeter.next!(p; showvalues)

nₜ == length(ephem.time) && break # Stop to update the temperature at the final step
update_temperature!(shape, thermo_params, nₜ)
update_temperature!(stpm, nₜ)
end
jldsave(savepath; shape, thermo_params, ephem, surf_temps, forces, torques)

jldsave(savepath; stpm, ephem, surf_temps, forces, torques)
end

"""
run_TPM!
run_TPM!(btpm::BinaryTPM, ephem, savepath)

Run TPM for a binary asteroid.

- shapes
- ephemerides
- thermo_params
- savepath
- savevalues
# Arguments
- `stpm` : Thermophysical model for a binary asteroid
- `ephem` : Ephemerides
- `time` : Ephemeris times
- `sun1` : Sun's position in the primary's frame
- `sun2` : Sun's position in the secondary's frame
- `sec` : Secondary's position in the primary's frame
- `P2S` : Rotation matrix from primary to secondary frames
- `S2P` : Rotation matrix from secondary to primary frames
- `savepath` : Path to save data file
"""
function run_TPM!(shapes::Tuple, thermo_params::AbstractThermoParams, ephem, savepath)
function run_TPM!(btpm::BinaryTPM, ephem, savepath)

surf_temps = zeros(length(shapes[1].faces), length(ephem.time)), zeros(length(shapes[2].faces), length(ephem.time))
surf_temps = zeros(length(btpm.pri.shape.faces), length(ephem.time)), zeros(length(btpm.sec.shape.faces), length(ephem.time))
forces = [zeros(3) for _ in eachindex(ephem.time)], [zeros(3) for _ in eachindex(ephem.time)]
torques = [zeros(3) for _ in eachindex(ephem.time)], [zeros(3) for _ in eachindex(ephem.time)]

Expand All @@ -172,36 +263,42 @@ function run_TPM!(shapes::Tuple, thermo_params::AbstractThermoParams, ephem, sav
R₂₁ = ephem.S2P[nₜ]

## Update enegey flux
update_flux!(shapes[1], r☉₁, thermo_params, nₜ)
update_flux!(shapes[2], r☉₂, thermo_params, nₜ)
find_eclipse!(shapes, r☉₁, sec_from_pri, R₂₁) # Mutual-shadowing
update_flux_sun!(btpm, r☉₁, r☉₂)
update_flux_scat_single!(btpm)
update_flux_rad_single!(btpm, nₜ)

## Mutual-shadowing
find_eclipse!(btpm, r☉₁, sec_from_pri, R₂₁)

## Mutual-heating
#
#

for (idx_shape, shape) in enumerate(shapes)
update_thermal_force!(shape, thermo_params, nₜ)
update_thermal_force!(btpm, nₜ)

## Save data for primary
surf_temps[1][:, nₜ] .= surface_temperature(btpm.pri, nₜ)
forces[1][nₜ] .= btpm.pri.force # Body-fixed frame
torques[1][nₜ] .= btpm.pri.torque # Body-fixed frame

surf_temps[idx_shape][:, nₜ] .= surface_temperature(shape, nₜ)
forces[idx_shape][nₜ] .= shape.force # Body-fixed frame
torques[idx_shape][nₜ] .= shape.torque # Body-fixed frame
end
## Save data for secondary
surf_temps[2][:, nₜ] .= surface_temperature(btpm.sec, nₜ)
forces[2][nₜ] .= btpm.sec.force # Body-fixed frame
torques[2][nₜ] .= btpm.sec.torque # Body-fixed frame

## Energy input/output
E_cons_pri = energy_io(shapes[1], thermo_params, nₜ)[3]
E_cons_sec = energy_io(shapes[2], thermo_params, nₜ)[3]
E_cons_pri = energy_io(btpm.pri, nₜ)[3]
E_cons_sec = energy_io(btpm.sec, nₜ)[3]

## Update the progress meter
showvalues = [("Timestep", nₜ), ("E_cons for primary", E_cons_pri), ("E_cons for secondary", E_cons_sec)]
ProgressMeter.next!(p; showvalues)

## Update temperature distribution
nₜ == length(ephem.time) && break # Stop to update the temperature at the final step
update_temperature!(shapes[1], thermo_params, nₜ)
update_temperature!(shapes[2], thermo_params, nₜ)
update_temperature!(btpm, nₜ)
end

jldsave(savepath; shapes, thermo_params, ephem, surf_temps, forces, torques)
jldsave(savepath; btpm, ephem, surf_temps, forces, torques)
end

Loading
Loading