├── CNAME
├── TidalPy
├── Material
│ ├── __init__.py
│ └── eos
│ │ ├── __init__.py
│ │ ├── methods
│ │ ├── __init__.py
│ │ ├── __init__.pxd
│ │ └── interpolate.pxd
│ │ ├── eos_solution.pyx
│ │ ├── __init__.pxd
│ │ ├── ode.pxd
│ │ └── solver.pxd
├── utilities
│ ├── __init__.py
│ ├── io
│ │ ├── __init__.py
│ │ └── pathing.py
│ ├── arrays
│ │ ├── __init__.py
│ │ ├── interp.pyx
│ │ ├── interp.pxd
│ │ └── interp_.hpp
│ ├── math
│ │ ├── __init__.py
│ │ ├── special.pxd
│ │ ├── numerics.pxd
│ │ ├── __init__.pxd
│ │ ├── numerics.pyx
│ │ ├── complex.pxd
│ │ └── numba_special.py
│ ├── dimensions
│ │ ├── __init__.py
│ │ ├── nondimensional_.hpp
│ │ └── nondimensional.pxd
│ ├── graphics
│ │ ├── multilayer
│ │ │ └── __init__.py
│ │ └── __init__.py
│ ├── types_x.pxd
│ ├── performance
│ │ ├── special
│ │ │ ├── __init__.py
│ │ │ └── factorial.py
│ │ ├── __init__.py
│ │ ├── memory.py
│ │ └── numba.py
│ ├── exoplanets
│ │ └── __init__.py
│ ├── classes
│ │ ├── model
│ │ │ └── __init__.py
│ │ ├── base_x.pxd
│ │ ├── config
│ │ │ └── __init__.py
│ │ ├── __init__.py
│ │ ├── base.py
│ │ └── base_x.pyx
│ ├── types_x.pyx
│ ├── string_helper
│ │ └── __init__.py
│ ├── numpy_helper
│ │ └── __init__.py
│ ├── spherical_helper
│ │ └── __init__.py
│ ├── conversions
│ │ ├── __init__.py
│ │ ├── conversions_x.pxd
│ │ └── timing.py
│ ├── multiprocessing
│ │ └── __init__.py
│ ├── integration
│ │ ├── scipy_helper.py
│ │ ├── numbalsoda_helper.py
│ │ └── cyrk_helper.py
│ └── types.py
├── structures
│ ├── helpers
│ │ └── __init__.py
│ ├── world_builder
│ │ └── __init__.py
│ ├── __init__.py
│ ├── orbit
│ │ └── __init__.py
│ ├── layers
│ │ ├── __init__.py
│ │ └── gas.py
│ └── world_types
│ │ ├── __init__.py
│ │ └── gas.py
├── RadialSolver
│ ├── boundaries
│ │ ├── __init__.py
│ │ ├── surface_bc.pxd
│ │ └── boundaries.pxd
│ ├── collapse
│ │ ├── __init__.py
│ │ └── collapse.pxd
│ ├── interfaces
│ │ ├── __init__.py
│ │ ├── interfaces.pxd
│ │ └── reversed.pxd
│ ├── starting
│ │ ├── __init__.py
│ │ ├── saito.pxd
│ │ ├── common.pxd
│ │ ├── driver.pxd
│ │ ├── takeuchi.pxd
│ │ ├── kamata.pxd
│ │ └── saito.pyx
│ ├── derivatives
│ │ ├── __init__.py
│ │ └── odes.pxd
│ ├── constants.pxd
│ ├── matrix_types
│ │ ├── __init__.py
│ │ └── solid_matrix.pxd
│ ├── __init__.pxd
│ ├── love.pxd
│ ├── love_.hpp
│ ├── __init__.py
│ ├── constants.pyx
│ ├── matrix.pxd
│ ├── shooting.pxd
│ ├── love.pyx
│ ├── solver.pxd
│ ├── love_.cpp
│ └── rs_solution_.hpp
├── Extending
│ ├── burnman
│ │ ├── material
│ │ │ ├── __init__.py
│ │ │ └── custom
│ │ │ │ ├── __init__.py
│ │ │ │ └── pyrite.py
│ │ ├── defaults.py
│ │ ├── __init__.py
│ │ ├── conversion.py
│ │ ├── burnman_defaultc.py
│ │ └── package.py
│ └── __init__.py
├── WorldPack
│ ├── WorldPack.zip
│ ├── 55cnc.toml
│ ├── sol.toml
│ ├── neptune.toml
│ ├── jupiter.toml
│ ├── trappist1.toml
│ ├── triton_simple.toml
│ ├── io_simple.toml
│ ├── nereid_dev.toml
│ ├── 55cnce_simple.toml
│ ├── charon.toml
│ ├── pluto.toml
│ ├── earth_simple.toml
│ ├── io.toml
│ ├── triton.toml
│ ├── luna.toml
│ ├── trappist1e.toml
│ ├── trappist1g.toml
│ ├── trappist1c.toml
│ ├── trappist1d.toml
│ ├── trappist1f.toml
│ ├── trappist1h.toml
│ ├── 55cnce.toml
│ ├── trappist1b.toml
│ ├── europa.toml
│ ├── earth.toml
│ └── mercury.toml
├── numba_scipy
│ ├── special
│ │ ├── __init__.py
│ │ └── overloads.py
│ ├── __init__.py
│ └── TODO_DeletePackage.md
├── tides
│ ├── modes
│ │ ├── __init__.py
│ │ └── mode_calc_helper
│ │ │ ├── inclin_calc_orderl2.py
│ │ │ ├── inclin_calc_orderl3.py
│ │ │ ├── inclin_calc_orderl4.py
│ │ │ ├── inclin_calc_orderl5.py
│ │ │ ├── inclin_calc_orderl6.py
│ │ │ └── inclin_calc_orderl7.py
│ ├── methods
│ │ └── __init__.py
│ ├── ctl_funcs
│ │ ├── __init__.py
│ │ └── ctl_funcs.py
│ ├── multilayer
│ │ ├── heating.pxd
│ │ ├── __init__.py
│ │ └── sensitivity.pxd
│ ├── __init__.py
│ ├── potential
│ │ └── __init__.py
│ ├── dissipation.py
│ ├── inclination_funcs
│ │ ├── orderl2.py
│ │ └── orderl3.py
│ ├── universal_coeffs.py
│ └── heating.py
├── toolbox
│ └── __init__.py
├── orbit
│ └── __init__.py
├── radiogenics
│ └── __init__.py
├── rheology
│ ├── __init__.py
│ ├── complex_compliance
│ │ └── __init__.py
│ ├── viscosity
│ │ └── __init__.py
│ ├── base.pxd
│ ├── partial_melt
│ │ └── __init__.py
│ └── models.pxd
├── cooling
│ └── __init__.py
├── stellar
│ ├── __init__.py
│ └── stellar.py
├── dynamics
│ └── __init__.py
├── output.py
├── constants.pxd
├── __init__.py
└── cache.py
├── Documentation
├── Overview
│ ├── 0_Readme.md
│ └── index.md
├── _static
│ ├── images
│ │ └── 2025-11-28_Logo_2-4.png
│ └── custom.css
├── RadialSolver
│ ├── Starting Radius Table.xlsx
│ ├── 4_RadialSolver_Cython_API.md
│ └── index.md
├── API
│ └── index.md
├── Dynamics
│ ├── 1_Dynamics.md
│ └── index.md
├── Style Templates
│ ├── docstring - module.txt
│ ├── docstring - class.txt
│ └── docstring - function or method.txt
├── Rheology
│ └── index.md
└── index.md
├── Papers
└── 2025-JOSS
│ ├── paper.pdf
│ └── figures
│ ├── bbg
│ ├── io_rheology_comparison.png
│ ├── stacked_images_set_0.png
│ ├── dynamic_vs_static_tides.png
│ ├── spin_orbit_resonance_ledges.png
│ ├── compressibility_effects_venus.png
│ ├── trappist1e_2d_heating_15deg_obliquity.png
│ ├── trappist1e_2d_heating_tidally_locked.png
│ ├── trappist1e_2d_heating_2-1_sor_15deg_obliquity.png
│ ├── trappist1e_2d_heating_2-1_spin-orbit_resonance.png
│ ├── trappist1e_2d_heating_3-2_sor_15deg_obliquity.png
│ └── trappist1e_2d_heating_3-2_spin-orbit_resonance.png
│ ├── wbg
│ ├── io_rheology_comparison.png
│ ├── stacked_images_set_0.png
│ ├── dynamic_vs_static_tides.png
│ ├── spin_orbit_resonance_ledges.png
│ ├── compressibility_effects_venus.png
│ ├── trappist1e_2d_heating_15deg_obliquity.png
│ ├── trappist1e_2d_heating_tidally_locked.png
│ ├── trappist1e_2d_heating_2-1_sor_15deg_obliquity.png
│ ├── trappist1e_2d_heating_2-1_spin-orbit_resonance.png
│ ├── trappist1e_2d_heating_3-2_sor_15deg_obliquity.png
│ └── trappist1e_2d_heating_3-2_spin-orbit_resonance.png
│ └── trappist1e-bm.toml
├── Benchmarks
├── RadialSolver
│ ├── Guo+2004.npy
│ └── Farrell1972.npy
└── Performance
│ ├── tides
│ └── Previous Runs
│ │ ├── RunTimePlot_0.2.1dev.pdf
│ │ ├── RunTimePlot_0.2.1.dev7.pdf
│ │ ├── CompileTimePlot_0.2.1dev.pdf
│ │ └── CompileTimePlot_0.2.1.dev7.pdf
│ └── performance suite
│ ├── performance_build_world.py
│ ├── run_suite.py
│ └── performance_complex_compliance_func.py
├── Tests
├── Test_Old
│ ├── Test_SetA_Package
│ │ ├── test_a_version.py
│ │ ├── test_tidalpy_config.py
│ │ └── test_io.py
│ ├── Test_SetS_Tides
│ │ └── Test_Heating
│ │ │ └── test_heating.py
│ ├── Test_SetB_Package
│ │ ├── test_c_tools_timing.py
│ │ ├── test_i_spherical_mass.py
│ │ ├── test_b_utilities_numpy.py
│ │ └── test_g_math_special_funcs.py
│ ├── Test_SetE_Functional
│ │ └── test_a_performance_funcs.py
│ └── Test_SetO_OOP_Calcs
│ │ └── test_oop_rheology.py
├── Test_RadialSolver
│ ├── Test_PropMatrix
│ │ ├── solid_derivative_matrix.npy
│ │ ├── solid_derivative_matrix_l3.npy
│ │ ├── solid_fundamental_matrix.npy
│ │ ├── solid_fundamental_matrix_l3.npy
│ │ ├── solid_inverse_fundamental_matrix.npy
│ │ └── solid_inverse_fundamental_matrix_l3.npy
│ └── test_a_boundary_conditions.py
├── Test_Math
│ ├── test_utilities_special.py
│ └── test_utilities_numerics.py
├── Test_Utilities
│ ├── Test_Exoplanets
│ │ └── test_exoplanet_download.py
│ └── Test_Dimensions
│ │ └── test_nondimensional.py
└── Test_Package
│ └── test_configs.py
├── index.html
├── readthedocs.yml
├── NOTICE
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
└── workflows
│ ├── make_joss_pdf.yml
│ ├── push_tests_win.yml
│ └── push_tests_ubun.yml
├── .vscode
└── tasks.json
├── MANIFEST.in
├── citation.cff
├── meta.yaml
└── setup.py
/CNAME:
--------------------------------------------------------------------------------
1 | tidalpy.info
--------------------------------------------------------------------------------
/TidalPy/Material/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/Material/eos/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/utilities/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/utilities/io/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/structures/helpers/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/utilities/arrays/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/utilities/math/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/Material/eos/methods/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/boundaries/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/collapse/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/interfaces/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/starting/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/utilities/dimensions/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/material/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/derivatives/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/TidalPy/utilities/graphics/multilayer/__init__.py:
--------------------------------------------------------------------------------
1 | from .yplot import yplot as yplot
2 |
--------------------------------------------------------------------------------
/TidalPy/utilities/math/special.pxd:
--------------------------------------------------------------------------------
1 | cdef double cf_double_factorial(int n) noexcept nogil
2 |
--------------------------------------------------------------------------------
/Documentation/Overview/0_Readme.md:
--------------------------------------------------------------------------------
1 |
2 | ```{include} Readme.md
3 | :start-after: Overview
4 | ```
--------------------------------------------------------------------------------
/TidalPy/utilities/types_x.pxd:
--------------------------------------------------------------------------------
1 | ctypedef fused double_numeric:
2 | double
3 | double complex
--------------------------------------------------------------------------------
/Papers/2025-JOSS/paper.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/paper.pdf
--------------------------------------------------------------------------------
/TidalPy/utilities/performance/special/__init__.py:
--------------------------------------------------------------------------------
1 | from .factorial import find_factorial as find_factorial
--------------------------------------------------------------------------------
/TidalPy/utilities/exoplanets/__init__.py:
--------------------------------------------------------------------------------
1 | from .data_download import get_exoplanet_data as get_exoplanet_data
2 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/constants.pxd:
--------------------------------------------------------------------------------
1 | cdef size_t MAX_NUM_Y
2 | cdef size_t MAX_NUM_Y_REAL
3 | cdef size_t MAX_NUM_SOL
--------------------------------------------------------------------------------
/TidalPy/WorldPack/WorldPack.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/TidalPy/WorldPack/WorldPack.zip
--------------------------------------------------------------------------------
/TidalPy/numba_scipy/special/__init__.py:
--------------------------------------------------------------------------------
1 | from . import overloads as _overloads
2 |
3 | _overloads.add_overloads()
4 |
--------------------------------------------------------------------------------
/Benchmarks/RadialSolver/Guo+2004.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Benchmarks/RadialSolver/Guo+2004.npy
--------------------------------------------------------------------------------
/Benchmarks/RadialSolver/Farrell1972.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Benchmarks/RadialSolver/Farrell1972.npy
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/matrix_types/__init__.py:
--------------------------------------------------------------------------------
1 | from TidalPy.RadialSolver.matrix_types.solid_matrix import fundamental_matrix as fundamental_matrix
--------------------------------------------------------------------------------
/TidalPy/utilities/classes/model/__init__.py:
--------------------------------------------------------------------------------
1 | from .model import LayerModelHolder as LayerModelHolder
2 | from .model import ModelHolder as ModelHolder
3 |
--------------------------------------------------------------------------------
/Documentation/_static/images/2025-11-28_Logo_2-4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Documentation/_static/images/2025-11-28_Logo_2-4.png
--------------------------------------------------------------------------------
/Documentation/RadialSolver/Starting Radius Table.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Documentation/RadialSolver/Starting Radius Table.xlsx
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/io_rheology_comparison.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/io_rheology_comparison.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/stacked_images_set_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/stacked_images_set_0.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/io_rheology_comparison.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/io_rheology_comparison.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/stacked_images_set_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/stacked_images_set_0.png
--------------------------------------------------------------------------------
/TidalPy/Material/eos/methods/__init__.pxd:
--------------------------------------------------------------------------------
1 | from TidalPy.Material.eos.methods.interpolate cimport EOS_INTERPOLATE_METHOD_INT, preeval_interpolate, InterpolateEOSInput
--------------------------------------------------------------------------------
/TidalPy/utilities/types_x.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/dynamic_vs_static_tides.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/dynamic_vs_static_tides.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/dynamic_vs_static_tides.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/dynamic_vs_static_tides.png
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/__init__.pxd:
--------------------------------------------------------------------------------
1 | from TidalPy.RadialSolver.rs_solution cimport RadialSolverSolution
2 | from TidalPy.RadialSolver.solver cimport cf_radial_solver
3 |
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/spin_orbit_resonance_ledges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/spin_orbit_resonance_ledges.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/spin_orbit_resonance_ledges.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/spin_orbit_resonance_ledges.png
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetA_Package/test_a_version.py:
--------------------------------------------------------------------------------
1 | def test_version():
2 | # Test Load
3 | from TidalPy import version
4 |
5 | assert version is not None
6 |
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/compressibility_effects_venus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/compressibility_effects_venus.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/compressibility_effects_venus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/compressibility_effects_venus.png
--------------------------------------------------------------------------------
/TidalPy/Material/eos/eos_solution.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
3 |
--------------------------------------------------------------------------------
/TidalPy/utilities/arrays/interp.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
3 |
--------------------------------------------------------------------------------
/TidalPy/utilities/classes/base_x.pxd:
--------------------------------------------------------------------------------
1 | cdef class TidalPyBaseExtensionClass:
2 |
3 | cdef str name_prefix
4 | cdef public str class_name
5 | cdef bint debug_mode
6 |
--------------------------------------------------------------------------------
/Documentation/RadialSolver/4_RadialSolver_Cython_API.md:
--------------------------------------------------------------------------------
1 | # RadialSolver Cython API
2 | TBD: The cython hooks to the radial solver are present and ready for use but not yet documented!
--------------------------------------------------------------------------------
/Benchmarks/Performance/tides/Previous Runs/RunTimePlot_0.2.1dev.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Benchmarks/Performance/tides/Previous Runs/RunTimePlot_0.2.1dev.pdf
--------------------------------------------------------------------------------
/Tests/Test_RadialSolver/Test_PropMatrix/solid_derivative_matrix.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Tests/Test_RadialSolver/Test_PropMatrix/solid_derivative_matrix.npy
--------------------------------------------------------------------------------
/TidalPy/utilities/string_helper/__init__.py:
--------------------------------------------------------------------------------
1 | from .string_helper import convert_time_to_hhmmss as convert_time_to_hhmmss
2 | from .string_helper import timestamped_str as timestamped_str
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Benchmarks/Performance/tides/Previous Runs/RunTimePlot_0.2.1.dev7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Benchmarks/Performance/tides/Previous Runs/RunTimePlot_0.2.1.dev7.pdf
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_15deg_obliquity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_15deg_obliquity.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_tidally_locked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_tidally_locked.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_15deg_obliquity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_15deg_obliquity.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_tidally_locked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_tidally_locked.png
--------------------------------------------------------------------------------
/Tests/Test_RadialSolver/Test_PropMatrix/solid_derivative_matrix_l3.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Tests/Test_RadialSolver/Test_PropMatrix/solid_derivative_matrix_l3.npy
--------------------------------------------------------------------------------
/Tests/Test_RadialSolver/Test_PropMatrix/solid_fundamental_matrix.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Tests/Test_RadialSolver/Test_PropMatrix/solid_fundamental_matrix.npy
--------------------------------------------------------------------------------
/TidalPy/tides/modes/__init__.py:
--------------------------------------------------------------------------------
1 | from .modes import find_unique_frequency_list as find_unique_frequency_list
2 | from .modes import find_unique_frequency_dict as find_unique_frequency_dict
3 |
--------------------------------------------------------------------------------
/Benchmarks/Performance/tides/Previous Runs/CompileTimePlot_0.2.1dev.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Benchmarks/Performance/tides/Previous Runs/CompileTimePlot_0.2.1dev.pdf
--------------------------------------------------------------------------------
/Tests/Test_RadialSolver/Test_PropMatrix/solid_fundamental_matrix_l3.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Tests/Test_RadialSolver/Test_PropMatrix/solid_fundamental_matrix_l3.npy
--------------------------------------------------------------------------------
/Benchmarks/Performance/tides/Previous Runs/CompileTimePlot_0.2.1.dev7.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Benchmarks/Performance/tides/Previous Runs/CompileTimePlot_0.2.1.dev7.pdf
--------------------------------------------------------------------------------
/TidalPy/tides/methods/__init__.py:
--------------------------------------------------------------------------------
1 | from .base import TidesBase as TidesBase
2 | from .global_approx import GlobalApproxTides as GlobalApproxTides
3 | from .layered import LayeredTides as LayeredTides
4 |
--------------------------------------------------------------------------------
/Tests/Test_RadialSolver/Test_PropMatrix/solid_inverse_fundamental_matrix.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Tests/Test_RadialSolver/Test_PropMatrix/solid_inverse_fundamental_matrix.npy
--------------------------------------------------------------------------------
/TidalPy/toolbox/__init__.py:
--------------------------------------------------------------------------------
1 | from .quick_tides import quick_dual_body_tidal_dissipation as quick_dual_body_tidal_dissipation
2 | from .quick_tides import quick_tidal_dissipation as quick_tidal_dissipation
3 |
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_2-1_sor_15deg_obliquity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_2-1_sor_15deg_obliquity.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_2-1_spin-orbit_resonance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_2-1_spin-orbit_resonance.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_3-2_sor_15deg_obliquity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_3-2_sor_15deg_obliquity.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_3-2_spin-orbit_resonance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/bbg/trappist1e_2d_heating_3-2_spin-orbit_resonance.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_2-1_sor_15deg_obliquity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_2-1_sor_15deg_obliquity.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_2-1_spin-orbit_resonance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_2-1_spin-orbit_resonance.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_3-2_sor_15deg_obliquity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_3-2_sor_15deg_obliquity.png
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_3-2_spin-orbit_resonance.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Papers/2025-JOSS/figures/wbg/trappist1e_2d_heating_3-2_spin-orbit_resonance.png
--------------------------------------------------------------------------------
/Tests/Test_RadialSolver/Test_PropMatrix/solid_inverse_fundamental_matrix_l3.npy:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jrenaud90/TidalPy/HEAD/Tests/Test_RadialSolver/Test_PropMatrix/solid_inverse_fundamental_matrix_l3.npy
--------------------------------------------------------------------------------
/TidalPy/utilities/math/numerics.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 |
3 | cdef cpp_bool cf_isclose(
4 | double a,
5 | double b,
6 | double rtol = *,
7 | double atol = *
8 | ) noexcept nogil
--------------------------------------------------------------------------------
/TidalPy/utilities/classes/config/__init__.py:
--------------------------------------------------------------------------------
1 | from .config import ConfigHolder as ConfigHolder
2 | from .config import WorldConfigHolder as WorldConfigHolder
3 | from .config import LayerConfigHolder as LayerConfigHolder
4 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/love.pxd:
--------------------------------------------------------------------------------
1 | cdef extern from "love_.cpp" nogil:
2 |
3 | void find_love_cf(
4 | double* complex_love_numbers_ptr,
5 | double* surface_solutions_ptr,
6 | double surface_gravity)
7 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/55cnc.toml:
--------------------------------------------------------------------------------
1 | name = "55-Cancri"
2 | type = "star"
3 | radius = 667900000.0
4 | mass = 1.91e+30
5 | luminosity = 2.266e+26
6 | tides_on = false
7 |
8 | [tides]
9 | model = "global_approx"
10 | fixed_q = 100.0
11 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/sol.toml:
--------------------------------------------------------------------------------
1 | name = "Sol"
2 | type = "star"
3 | radius = 695700000.0
4 | mass = 1.988435e+30
5 | luminosity = 3.848e+26
6 | tides_on = false
7 |
8 | [tides]
9 | model = "global_approx"
10 | fixed_q = 100.0
11 |
--------------------------------------------------------------------------------
/TidalPy/numba_scipy/__init__.py:
--------------------------------------------------------------------------------
1 | def _init_extension():
2 | '''Register SciPy functions with Numba.
3 |
4 | This entry_point is called by Numba when it initializes.
5 | '''
6 |
7 | from . import special as special
8 |
--------------------------------------------------------------------------------
/TidalPy/structures/world_builder/__init__.py:
--------------------------------------------------------------------------------
1 | from .world_builder import build_from_world as build_from_world
2 | from .world_builder import build_world as build_world
3 | from .world_builder import scale_from_world as scale_from_world
4 |
--------------------------------------------------------------------------------
/TidalPy/utilities/numpy_helper/__init__.py:
--------------------------------------------------------------------------------
1 | from .array_other import find_nearest as find_nearest
2 | from .array_other import neg_array_for_log_plot as neg_array_for_log_plot
3 | from .array_shape import reshape_help as reshape_help
4 |
--------------------------------------------------------------------------------
/Documentation/API/index.md:
--------------------------------------------------------------------------------
1 | # TidalPy API Reference
2 |
3 | This API reference manual is autogenerated from docstrings in the code.
4 |
5 | ```{autosummary}
6 | :toctree: generated
7 | :recursive:
8 |
9 | TidalPy
10 | ```
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/starting/saito.pxd:
--------------------------------------------------------------------------------
1 | cdef void cf_saito_liquid_static_incompressible(
2 | double radius,
3 | int degree_l,
4 | size_t num_ys,
5 | double complex* starting_conditions_ptr
6 | ) noexcept nogil
7 |
--------------------------------------------------------------------------------
/TidalPy/structures/__init__.py:
--------------------------------------------------------------------------------
1 | from .physical import PhysicalObjSpherical
2 |
3 | # Physical must be imported before the following are imported.
4 | from .orbit import PhysicsOrbit as Orbit
5 | from .world_builder import build_from_world, build_world, scale_from_world
6 |
--------------------------------------------------------------------------------
/TidalPy/structures/orbit/__init__.py:
--------------------------------------------------------------------------------
1 | from .base import OrbitBase as OrbitBase
2 | from .physics import PhysicsOrbit as PhysicsOrbit
3 |
4 | # User will almost always want the Physics version of the orbit, so it is aliased as just `Orbit` here
5 | Orbit = PhysicsOrbit
6 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/neptune.toml:
--------------------------------------------------------------------------------
1 | name = "Neptune"
2 | type = "gas_giant"
3 | radius = 24622000.0
4 | mass = 1.02413e+26
5 | semi_major_axis = 30.07
6 | semi_major_axis_in_au = true
7 | eccentricity = 0.008678
8 | tides_on = true
9 |
10 | [tides]
11 | fixed_q = 9000.0
12 |
--------------------------------------------------------------------------------
/TidalPy/numba_scipy/TODO_DeletePackage.md:
--------------------------------------------------------------------------------
1 | # TODO: Right now numba-scipy is limiting the scipy version (<1.7.0) allowed. Once that has been updated then remove
2 | # these files in favor of using the third party package.
3 | # See: https://github.com/numba/numba-scipy/pull/90
4 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/love_.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 |
4 | void find_love_cf(
5 | double* complex_love_numbers_ptr, // These are double pointers that pointer to a double complex array.
6 | double* surface_solutions_ptr, // Same as above
7 | double surface_gravity);
8 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/jupiter.toml:
--------------------------------------------------------------------------------
1 | name = "Jupiter"
2 | type = "gas_giant"
3 | radius = 69911000.0
4 | mass = 1.898e+27
5 | semi_major_axis = 5.20336301
6 | semi_major_axis_in_au = true
7 | eccentricity = 0.04839266
8 | tides_on = false
9 |
10 | [tides]
11 | fixed_q = 8000.0
12 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/boundaries/surface_bc.pxd:
--------------------------------------------------------------------------------
1 | cdef int cf_get_surface_bc(
2 | double* boundary_conditions_ptr,
3 | int* bc_model_ptr,
4 | size_t num_bcs,
5 | double radius_to_use,
6 | double bulk_density_to_use,
7 | double degree_l_dbl,
8 | ) noexcept nogil
9 |
--------------------------------------------------------------------------------
/TidalPy/utilities/spherical_helper/__init__.py:
--------------------------------------------------------------------------------
1 | from .volume import calculate_voxel_volumes as calculate_voxel_volumes
2 | from .volume import calculate_voxel_volumes_npy as calculate_voxel_volumes_npy
3 |
4 | from .mass import calculate_mass_gravity_arrays as calculate_mass_gravity_arrays
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/defaults.py:
--------------------------------------------------------------------------------
1 | default_burnman_layer_params = {
2 | 'material_source' : None,
3 | 'temperature_mode' : 'adiabatic',
4 | 'fixed_temperature' : None,
5 | 'top_temperature' : None,
6 | 'interp_lookup_method': 'mid',
7 | 'slices' : 50
8 | }
9 |
--------------------------------------------------------------------------------
/TidalPy/orbit/__init__.py:
--------------------------------------------------------------------------------
1 | from .averaging import orbit_average as orbit_average
2 | from .averaging import orbit_average_3d as orbit_average_3d
3 | from .averaging import orbit_average_3d_multiarray as orbit_average_3d_multiarray
4 | from .averaging import orbit_average_4d_multiarray as orbit_average_4d_multiarray
5 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/__init__.py:
--------------------------------------------------------------------------------
1 | from TidalPy.RadialSolver.solver import radial_solver as radial_solver
2 |
3 | from TidalPy.RadialSolver.helpers import build_rs_input_homogeneous_layers as build_rs_input_homogeneous_layers
4 | from TidalPy.RadialSolver.helpers import build_rs_input_from_data as build_rs_input_from_data
5 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/constants.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
3 |
4 | # Maximum size for array building
5 | cdef size_t MAX_NUM_Y = 6
6 | cdef size_t MAX_NUM_Y_REAL = 2 * MAX_NUM_Y
7 | cdef size_t MAX_NUM_SOL = 3
8 |
--------------------------------------------------------------------------------
/readthedocs.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | build:
4 | os: "ubuntu-lts-latest"
5 | tools:
6 | python: "3.12"
7 |
8 | jobs:
9 | pre_build:
10 | - doxygen DoxyFile
11 |
12 | sphinx:
13 | configuration: Documentation/conf.py
14 |
15 | python:
16 | install:
17 | - method: pip
18 | path: .[docs]
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1.toml:
--------------------------------------------------------------------------------
1 | # From Delrez+2018 and Kane2018
2 | # Updated using Agol+2020, Mass from Mann+2019, Luminosity from Ducrot+2020
3 |
4 | name = "TRAPPIST-1"
5 | type = "star"
6 | radius = 82927000.0
7 | mass = 1.786e+29
8 | luminosity = 2.11799e+23
9 | tides_on = false
10 |
11 | [tides]
12 | model = "global_approx"
13 | fixed_q = 5000.0
14 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/starting/common.pxd:
--------------------------------------------------------------------------------
1 | cdef double complex cf_z_calc(
2 | double complex x_squared,
3 | int degree_l
4 | ) noexcept nogil
5 |
6 | cdef void cf_takeuchi_phi_psi(
7 | double complex z,
8 | int degree_l,
9 | double complex* phi_ptr,
10 | double complex* phi_lplus1_ptr,
11 | double complex* psi_ptr,
12 | ) noexcept nogil
--------------------------------------------------------------------------------
/TidalPy/utilities/dimensions/nondimensional_.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | class NonDimensionalScalesCC
4 | {
5 | public:
6 | double second2_conversion;
7 | double second_conversion;
8 | double length_conversion;
9 | double length3_conversion;
10 | double density_conversion;
11 | double mass_conversion;
12 | double pascal_conversion;
13 | };
14 |
--------------------------------------------------------------------------------
/TidalPy/utilities/classes/__init__.py:
--------------------------------------------------------------------------------
1 | from .base import TidalPyClass as TidalPyClass
2 |
3 | from .config import ConfigHolder as ConfigHolder
4 | from .config import LayerConfigHolder as LayerConfigHolder
5 | from .config import WorldConfigHolder as WorldConfigHolder
6 |
7 | from .model import LayerModelHolder as LayerModelHolder
8 | from .model import ModelHolder as ModelHolder
9 |
--------------------------------------------------------------------------------
/Documentation/Overview/index.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | ```{toctree}
4 | :maxdepth: 2
5 | :caption: Contents
6 |
7 | General <0_Readme.md>
8 | Getting Started <1_Getting_Started.md>
9 | Configurations <2_TidalPy_Configurations.md>
10 | Contributing
11 | Code of Conduct
12 | License
13 | Additional License Notice
14 | ```
--------------------------------------------------------------------------------
/TidalPy/utilities/classes/base.py:
--------------------------------------------------------------------------------
1 | from TidalPy import version
2 |
3 |
4 | class TidalPyClass:
5 | """ All functional methods used in TidalPy inherit from this base class.
6 |
7 | Class Attributes
8 | ----------------
9 | tidalpy_version : str
10 | Stores the TidalPy version text at the time of import
11 |
12 | """
13 |
14 | tidalpy_version = version
15 |
--------------------------------------------------------------------------------
/TidalPy/tides/ctl_funcs/__init__.py:
--------------------------------------------------------------------------------
1 | from .ctl_funcs import linear_dt, linear_dt_with_q
2 |
3 | known_ctl_methods = {
4 | 'linear_simple' : linear_dt,
5 | 'linear_simple_with_q': linear_dt_with_q
6 | }
7 |
8 | ctl_method_input_getters = {
9 | 'linear_simple' : (('tides', 'fixed_dt'),),
10 | 'linear_simple_with_q': (('tides', 'fixed_dt'), ('tides', 'fixed_q'))
11 | }
12 |
--------------------------------------------------------------------------------
/TidalPy/Material/eos/__init__.pxd:
--------------------------------------------------------------------------------
1 | # Common functions and structures
2 | from TidalPy.Material.eos.eos_solution cimport EOSSolutionCC
3 | from TidalPy.Material.eos.ode cimport EOS_ODEInput, eos_diffeq
4 | from TidalPy.Material.eos.solver cimport solve_eos
5 |
6 | # Specific EOS functions and structures
7 | # Interpolate
8 | from TidalPy.Material.eos.methods.interpolate cimport InterpolateEOSInput, preeval_interpolate
9 |
--------------------------------------------------------------------------------
/Tests/Test_Math/test_utilities_special.py:
--------------------------------------------------------------------------------
1 | from math import isclose
2 | from scipy.special import factorial2
3 |
4 | import pytest
5 |
6 | from TidalPy.utilities.math.special import double_factorial
7 |
8 | @pytest.mark.parametrize('l', (0, 2, 3, 4, 5, 10, 20, 100))
9 | def test_double_factorial(l):
10 |
11 | tpy_value = double_factorial(l)
12 | ref_value = factorial2(l)
13 |
14 | assert isclose(tpy_value, ref_value)
15 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/triton_simple.toml:
--------------------------------------------------------------------------------
1 | name = "Triton_Simple"
2 | type = "simple_tidal"
3 | radius = 1353000.0
4 | mass = 2.139e+22
5 | semi_major_axis = 354760000.0
6 | semi_major_axis_in_au = false
7 | eccentricity = 1.6e-5
8 | spin_period = -5.876854
9 | albedo = 0.55
10 | force_spin_sync = false
11 |
12 | [tides]
13 | use_ctl = false
14 | ctl_calc_method = "linear_simple_with_q"
15 | fixed_q = 100.0
16 | static_k2 = 0.1
17 | fixed_dt = 507800.0
18 |
--------------------------------------------------------------------------------
/TidalPy/utilities/math/__init__.pxd:
--------------------------------------------------------------------------------
1 | from TidalPy.utilities.math.complex cimport (
2 | cmplx_NAN, cmplx_zero, SQRT2, LOGE2, SQRT2_INV, THRESH, DBL_MAX_4,
3 | SCALED_CEXP_K_F, SCALED_CEXP_K_D, SCALED_CEXP_K_LD, SCALED_K_LOGE2_D, SCALED_CEXP_LOWERF, SCALED_CEXP_UPPERF,
4 | SCALED_CEXP_LOWER, SCALED_CEXP_UPPER, SCALED_CEXP_LOWERL, SCALED_CEXP_UPPERL,
5 | cf_build_dblcmplx, cf_cinv, cf_hypot, cf_csqrt, cf_scaled_cexp, cf_cexp, cf_clog, cf_cpow, cf_cipow)
6 |
--------------------------------------------------------------------------------
/Documentation/Dynamics/1_Dynamics.md:
--------------------------------------------------------------------------------
1 | # TidalPy Dynamics
2 |
3 | TidalPy's dynamics API is currently undergoing changes, this documentation will be updated once it is complete. For the
4 | time being please take a look at the autogenerated API documentation.
5 |
6 | As of TidalPy v0.7.0, the dynamics functionality is spread between `TidalPy.dynamics` and `TidalPy.tides` modules. This
7 | will be refactored into a new `TidalPy.Dynamics` module (with a capital).
8 |
--------------------------------------------------------------------------------
/TidalPy/Extending/__init__.py:
--------------------------------------------------------------------------------
1 | extended_configs = dict()
2 |
3 | from TidalPy.utilities.dictionary_utils import nested_merge
4 | from TidalPy.Extending.burnman import burnman_installed
5 |
6 | # Add any extension configs to the extended config dict which will be added to the tidalpy configs
7 | if burnman_installed:
8 | from TidalPy.Extending.burnman.burnman_defaultc import default_burnman_configs
9 | extended_configs = nested_merge(extended_configs, default_burnman_configs)
--------------------------------------------------------------------------------
/TidalPy/WorldPack/io_simple.toml:
--------------------------------------------------------------------------------
1 | name = "Io_Simple"
2 | type = "layered"
3 | radius = 1821490.0
4 | orbital_period = 1.769
5 | eccentricity = 0.0041
6 | spin_period = 1.769
7 | albedo = 0.63
8 | force_spin_sync = true
9 |
10 | [layers.Core]
11 | type = "iron"
12 | is_tidal = false
13 | radius = 810000.0
14 | density = 5200.0
15 |
16 | [layers.Mantle]
17 | type = "rock"
18 | is_tidal = true
19 | radius = 1821490.0
20 | surface_temperature = 100.0
21 | density = 3200.0
22 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/nereid_dev.toml:
--------------------------------------------------------------------------------
1 | name = "Nereid"
2 | type = "layered"
3 | radius = 180000.0
4 | mass = 3.1e+19
5 | semi_major_axis = 5513940000.0
6 | semi_major_axis_in_au = false
7 | eccentricity = 0.7417482
8 | spin_period = 0.48308333333
9 | albedo = 0.24
10 | force_spin_sync = false
11 |
12 | [layers.Core]
13 | type = "rock"
14 | is_tidal = true
15 | density_bulk = 1500.0
16 | radius = 180000.0
17 |
18 | [layers.Core.rheology.complex_compliance]
19 | model = "sundberg"
20 |
--------------------------------------------------------------------------------
/TidalPy/structures/layers/__init__.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 | from .basic import LayerBase
4 | from .gas import GasLayer
5 | from .physics import PhysicsLayer
6 |
7 | LayerType = Union[PhysicsLayer, LayerBase, GasLayer]
8 | PhysicalLayerType = PhysicsLayer
9 |
10 | known_layer_classes = {
11 | 'gas' : GasLayer,
12 | 'physics': PhysicsLayer
13 | }
14 |
15 | layers_class_by_world_class = {
16 | 'layered' : PhysicsLayer,
17 | 'gas_giant_layered': GasLayer,
18 | }
19 |
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/material/custom/__init__.py:
--------------------------------------------------------------------------------
1 | from .ice import LowPressureIceConst as LowPressureIceConst
2 | from .ice import HighPressureIceConst as HighPressureIceConst
3 | from .ice import UnterbornIce as UnterbornIce
4 | from .ice import Water as Water
5 | from .ice import HighPressureIce as HighPressureIce
6 | from .ice import IceX_Fu2010 as IceX_Fu2010
7 | from .ice import IceVII_Fu2010 as IceVII_Fu2010
8 | from .ice import IceIh_Fu2010 as IceIh_Fu2010
9 |
10 | from .pyrite import Pyrite as Pyrite
11 |
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetA_Package/test_tidalpy_config.py:
--------------------------------------------------------------------------------
1 | from TidalPy import config
2 |
3 |
4 | def test_load_configs():
5 | # Load configurations and make sure they have all the needed parameters
6 | assert type(config) == dict
7 |
8 | config_headers = [
9 | 'pathing',
10 | 'debug',
11 | 'logging',
12 | 'configs',
13 | 'numba',
14 | 'worlds',
15 | 'tides'
16 | ]
17 |
18 | for header in config_headers:
19 | assert header in config
20 |
--------------------------------------------------------------------------------
/TidalPy/radiogenics/__init__.py:
--------------------------------------------------------------------------------
1 | from TidalPy.utilities.classes.model.model_utils import build_model_default_inputs, find_all_models
2 |
3 | from . import radiogenic_models
4 |
5 | known_models, known_model_const_args, known_model_live_args = find_all_models(radiogenic_models)
6 |
7 |
8 | def get_radiogenic_model_default_inputs(layer_type: str):
9 | return build_model_default_inputs(known_model_const_args, radiogenic_models, inner_keys=layer_type)
10 |
11 | from .radiogenics import Radiogenics as Radiogenics
12 |
--------------------------------------------------------------------------------
/Documentation/Style Templates/docstring - module.txt:
--------------------------------------------------------------------------------
1 | """Docstring for the example.py module.
2 |
3 | Modules names should have short, all-lowercase names. The module name may
4 | have underscores if this improves readability.
5 |
6 | Every module should have a docstring at the very top of the file. The
7 | module's docstring may extend over multiple lines. If your docstring does
8 | extend over multiple lines, the closing three quotation marks must be on
9 | a line by itself, preferably preceded by a blank line.
10 |
11 | """
--------------------------------------------------------------------------------
/TidalPy/utilities/conversions/__init__.py:
--------------------------------------------------------------------------------
1 | from .conversions import days2rads as days2rads
2 | from .conversions import rads2days as rads2days
3 | from .conversions import Au2m as Au2m
4 | from .conversions import m2Au as m2Au
5 | from .conversions import orbital_motion2semi_a as orbital_motion2semi_a
6 | from .conversions import semi_a2orbital_motion as semi_a2orbital_motion
7 | from .conversions import myr2sec as myr2sec
8 | from .conversions import sec2myr as sec2myr
9 |
10 | from .timing import convert_to_hms as convert_to_hms
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/matrix_types/solid_matrix.pxd:
--------------------------------------------------------------------------------
1 | cdef void cf_fundamental_matrix(
2 | Py_ssize_t first_slice_index,
3 | Py_ssize_t num_radial_slices,
4 | double* radius_array_ptr,
5 | double* density_array_ptr,
6 | double* gravity_array_ptr,
7 | double complex* complex_shear_array_ptr,
8 | double complex* fundamental_mtx_ptr,
9 | double complex* inverse_fundamental_mtx_ptr,
10 | double complex* derivative_mtx_ptr,
11 | int degree_l = *,
12 | double G_to_use = *
13 | ) noexcept nogil
14 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/boundaries/boundaries.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 |
3 |
4 | cdef void cf_apply_surface_bc(
5 | double complex* constant_vector_ptr,
6 | int* bc_solution_info,
7 | double* bc_pointer,
8 | double complex* uppermost_y_per_solution_ptr,
9 | double surface_gravity,
10 | double G_to_use,
11 | size_t num_sols,
12 | size_t max_num_y,
13 | size_t ytype_i,
14 | int layer_type,
15 | cpp_bool layer_is_static,
16 | cpp_bool layer_is_incomp
17 | ) noexcept nogil
18 |
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/__init__.py:
--------------------------------------------------------------------------------
1 | from .package import burnman as burnman
2 | from .package import Material as Material
3 | from .package import Mineral as Mineral
4 | from .package import material_property as material_property
5 | from .package import dictionarize_formula as dictionarize_formula
6 | from .package import formula_mass as formula_mass
7 | from .package import burnman_installed as burnman_installed
8 |
9 | from .build import build_burnman_world as build_burnman_world
10 | from .burnman_world import BurnManWorld as BurnManWorld
11 |
--------------------------------------------------------------------------------
/Documentation/Rheology/index.md:
--------------------------------------------------------------------------------
1 | # TidalPy.Rheology Documentation
2 |
3 | **TidalPy's Rheology Module**
4 |
5 | [Auto Generated API](https://tidalpy.readthedocs.io/en/latest/API/generated/TidalPy.rheology.html)
6 |
7 | TidalPy's Rheology Module handles converting from static viscosities and moduli to a complex moduli based on a
8 | the requested rheology. These complex moduli can then be used to find Love numbers.
9 | found below.
10 |
11 | ```{toctree}
12 | :maxdepth: 2
13 | :caption: Contents
14 |
15 | Rheology <1_Rheology.md>
16 | ```
--------------------------------------------------------------------------------
/Documentation/Dynamics/index.md:
--------------------------------------------------------------------------------
1 | # TidalPy.Dynamics Documentation
2 |
3 | **TidalPy's Dynamics Module**
4 |
5 | [Auto Generated API](https://tidalpy.readthedocs.io/en/latest/API/generated/TidalPy.dynamics.html)
6 |
7 | TidalPy's Dynamics Module contains functionality to determine dominate tidal forcing modes (determined from the world's
8 | orbit and rotation) and how these modes translate to dissipation within both the target world and host.
9 |
10 | ```{toctree}
11 | :maxdepth: 2
12 | :caption: Contents
13 |
14 | Dynamics <1_Dynamics.md>
15 | ```
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | # TidalPy - Additional License Notice
2 | _Copyright 2025 Joe P. Renaud_
3 |
4 | Licensed under the Apache License, Version 2.0 (the "License");
5 | you may not use this file except in compliance with the License.
6 | You may obtain a copy of the License at
7 |
8 | [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
9 |
10 | This product includes software developed as part of the TidalPy project.
11 |
12 | **If used in published research, please cite the project as described in the citation.cff file.**
13 |
--------------------------------------------------------------------------------
/TidalPy/utilities/graphics/__init__.py:
--------------------------------------------------------------------------------
1 | # Cartopy is usually not installed during testing which is fine. But this module will throw an error when tests are run
2 | # and Cartopy is not installed. So check if it is installed before bringing these packages up.
3 | import importlib.util
4 |
5 | from .grid_plot import GridPlot as GridPlot
6 | from .planet_plot import planet_plot as planet_plot
7 |
8 | if importlib.util.find_spec('cartopy') is not None:
9 | spec = importlib.util.find_spec('cartopy')
10 | from .global_map import projection_map as projection_map
11 |
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/conversion.py:
--------------------------------------------------------------------------------
1 | """ Common conversions between TidalPy and BurnMan """
2 |
3 | burnman_property_name_conversion = {
4 | 'thermal_expansion': 'thermal_expansivity',
5 | # 'grueneisen': 'grueneisen_parameter', # FIXME: remove the comment here once ice EOS in place.
6 | 'bulk_modulus' : 'isothermal_bulk_modulus_reuss',
7 | 'specific_heat' : 'molar_heat_capacity_p',
8 | }
9 |
10 | burnman_property_value_conversion = {
11 | # Need to change BurnMan's molar heat capacity to specific
12 | 'specific_heat': 'molar'
13 | }
14 |
--------------------------------------------------------------------------------
/TidalPy/tides/multilayer/heating.pxd:
--------------------------------------------------------------------------------
1 |
2 | cdef void cf_calc_radial_volumetric_tidal_heating(
3 | double* volumetric_tidal_heating_arr_ptr,
4 | size_t total_slices,
5 | double eccentricity,
6 | double orbital_frequency,
7 | double semi_major_axis,
8 | double host_mass,
9 | double* radius_arr_ptr,
10 | double* radial_sensitivity_to_shear_arr_ptr,
11 | double complex* complex_shear_modulus_arr_ptr,
12 | double* radial_sensitivity_to_bulk_arr_ptr,
13 | double complex* complex_bulk_modulus_arr_ptr,
14 | int degree_l,
15 | double G_to_use
16 | ) noexcept nogil
17 |
--------------------------------------------------------------------------------
/TidalPy/utilities/dimensions/nondimensional.pxd:
--------------------------------------------------------------------------------
1 |
2 | cdef extern from "nondimensional_.hpp" nogil:
3 | cdef cppclass NonDimensionalScalesCC:
4 | double second2_conversion
5 | double second_conversion
6 | double length_conversion
7 | double length3_conversion
8 | double density_conversion
9 | double mass_conversion
10 | double pascal_conversion
11 |
12 |
13 | cdef void cf_build_nondimensional_scales(
14 | NonDimensionalScalesCC* non_dim_scales_ptr,
15 | double frequency,
16 | double mean_radius,
17 | double bulk_density
18 | ) noexcept nogil
19 |
--------------------------------------------------------------------------------
/TidalPy/Material/eos/ode.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 |
3 | from CyRK cimport PreEvalFunc
4 |
5 | cdef struct EOSOutput:
6 | double density
7 | double complex bulk_modulus
8 | double complex shear_modulus
9 |
10 | cdef struct EOS_ODEInput:
11 | double G_to_use
12 | double planet_radius
13 | char* eos_input_ptr
14 | cpp_bool final_solve
15 | cpp_bool update_bulk
16 | cpp_bool update_shear
17 |
18 | cdef void eos_diffeq(
19 | double* dy_ptr,
20 | double radius,
21 | double* y_ptr,
22 | char* input_args,
23 | PreEvalFunc eos_function) noexcept nogil
24 |
25 |
--------------------------------------------------------------------------------
/TidalPy/rheology/__init__.py:
--------------------------------------------------------------------------------
1 | # Rheology Imports
2 | from .rheology import Rheology as Rheology
3 |
4 | from TidalPy.rheology.models import find_rheology as find_rheology
5 | from TidalPy.rheology.models import Elastic as Elastic
6 | from TidalPy.rheology.models import Newton as Newton
7 | from TidalPy.rheology.models import Maxwell as Maxwell
8 | from TidalPy.rheology.models import Voigt as Voigt
9 | from TidalPy.rheology.models import Burgers as Burgers
10 | from TidalPy.rheology.models import Andrade as Andrade
11 | from TidalPy.rheology.models import SundbergCooper as SundbergCooper
12 |
13 | # Alias rheologies
14 | Sundberg = SundbergCooper
15 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/55cnce_simple.toml:
--------------------------------------------------------------------------------
1 | # Very roughly pulled from some analysis by Dorn+ (A&A 2017)
2 |
3 | name = "55-Cancri-e"
4 | type = "layered"
5 | radius = 11950000.0
6 | semi_major_axis = 0.01544
7 | semi_major_axis_in_au = true
8 | eccentricity = 0.02
9 | spin_period = 1.0
10 | force_spin_sync = true
11 |
12 | [layers.Core]
13 | type = "iron"
14 | is_tidal = false
15 | radius = 4000000.0
16 | density = 14000.0
17 |
18 | [layers.Lower_Mantle]
19 | type = "rock"
20 | is_tidal = false
21 | radius = 8959000.0
22 | density = 5000.0
23 |
24 | [layers.Upper_Mantle]
25 | type = "rock"
26 | is_tidal = true
27 | radius = 11950000.0
28 | density = 3300.0
29 |
--------------------------------------------------------------------------------
/Documentation/RadialSolver/index.md:
--------------------------------------------------------------------------------
1 | # TidalPy.RadialSolver Documentation
2 |
3 | **Welcome to the RadialSolver's documentation!**
4 |
5 | [Auto Generated API](https://tidalpy.readthedocs.io/en/latest/API/generated/TidalPy.RadialSolver.html)
6 |
7 | TidalPy's RadialSolver Module handles calculating Love numbers for planets. Details about how to use it can be
8 | found below.
9 |
10 | ```{toctree}
11 | :maxdepth: 2
12 | :caption: Contents
13 |
14 | Calculating Love Numbers <1_Calculating_Love_Numbers.md>
15 | Solution Class <2_RadialSolver_Solution_Class.md>
16 | Helper Functions <3_RadialSolver_Helpers.md>
17 | Cython API <4_RadialSolver_Cython_API.md>
18 | ```
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetS_Tides/Test_Heating/test_heating.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import numpy as np
4 |
5 |
6 | def test_volumetric_heating():
7 | """ Test the volumetric heating function. """
8 |
9 | # Ensure imports work
10 | from TidalPy.tides import calculate_volumetric_heating
11 |
12 | stress = (10. + 0.1j) * np.ones((6, 10, 12), dtype=np.complex128)
13 | strain = (5. - 0.1j) * np.ones((6, 10, 12), dtype=np.complex128)
14 |
15 | volumetric_heating = calculate_volumetric_heating(stress, strain)
16 |
17 | assert volumetric_heating.shape == (10, 12)
18 | assert volumetric_heating.dtype == np.float64
19 | assert np.all(volumetric_heating >= 0.)
20 |
--------------------------------------------------------------------------------
/TidalPy/tides/multilayer/__init__.py:
--------------------------------------------------------------------------------
1 | from .displacements import calculate_displacements as calculate_displacements
2 | from TidalPy.tides.multilayer.heating import calc_radial_volumetric_tidal_heating_from_rs_solution as calc_radial_volumetric_tidal_heating_from_rs_solution
3 | from TidalPy.tides.multilayer.heating import calc_radial_volumetric_tidal_heating as calc_radial_volumetric_tidal_heating
4 |
5 | from .stress_strain import calculate_strain_stress as calculate_strain_stress
6 | from TidalPy.tides.multilayer.sensitivity import calc_sensitivity_to_bulk as calc_sensitivity_to_bulk
7 | from TidalPy.tides.multilayer.sensitivity import calc_sensitivity_to_shear as calc_sensitivity_to_shear
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/starting/driver.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 | from libcpp.string cimport string as cpp_string
3 |
4 |
5 | cdef void cf_find_starting_conditions(
6 | cpp_bool* success_ptr,
7 | cpp_string& message,
8 | int layer_type,
9 | bint is_static,
10 | bint is_incompressible,
11 | cpp_bool use_kamata,
12 | double frequency,
13 | double radius,
14 | double density,
15 | double complex bulk_modulus,
16 | double complex shear_modulus,
17 | int degree_l,
18 | double G_to_use,
19 | size_t num_ys,
20 | double complex* starting_conditions_ptr,
21 | cpp_bool run_y_checks = *
22 | ) noexcept nogil
23 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/charon.toml:
--------------------------------------------------------------------------------
1 | name = "Charon"
2 | type = "burnman"
3 | radius = 606016.07
4 | orbital_period = 6.3872304
5 | eccentricity = 0.0002
6 | spin_period = 6.3872304
7 | albedo = 0.3
8 | force_spin_sync = false
9 |
10 | [layers.Core]
11 | type = "rock"
12 | is_tidal = true
13 | radius = 437374.8067
14 | material = "forsterite"
15 | material_source = "SLB_2011"
16 | temperature_mode = "adiabatic"
17 | temperature_top = 300.0
18 |
19 | [layers.Crust]
20 | type = "ice"
21 | is_tidal = false
22 | radius = 606000.0
23 | material = "IceIh_Fu2010"
24 | material_source = "TidalPy"
25 | temperature_mode = "user-defined"
26 | surface_temperature = 40.0
27 | temperature_fixed = 40.0
28 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/interfaces/interfaces.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 |
3 | cdef void cf_solve_upper_y_at_interface(
4 | double complex* lower_layer_y_ptr,
5 | double complex* upper_layer_y_ptr,
6 | size_t num_sols_lower,
7 | size_t num_sols_upper,
8 | size_t max_num_y,
9 | int lower_layer_type,
10 | cpp_bool lower_is_static,
11 | cpp_bool lower_is_incompressible,
12 | int upper_layer_type,
13 | cpp_bool upper_is_static,
14 | cpp_bool upper_is_incompressible,
15 | double interface_gravity,
16 | double liquid_density,
17 | double G_to_use
18 | ) noexcept nogil
19 |
--------------------------------------------------------------------------------
/Documentation/Style Templates/docstring - class.txt:
--------------------------------------------------------------------------------
1 |
2 | The class docstring need only include descriptions of attributes and methods that are most likely to be used or ones
3 | that may lead to confusion with the user. Other methods and attributes that are well described elsewhere
4 | (and/or self-explanatory) can be left out of the class docstring.
5 |
6 | """
7 | Array with associated photographic information.
8 |
9 | ...
10 |
11 | Attributes
12 | ----------
13 | exposure : float
14 | Exposure in seconds.
15 |
16 | Methods
17 | -------
18 | colorspace(c='rgb')
19 | Represent the photo in the given colorspace.
20 | gamma(n=1.0)
21 | Change the photo's gamma exposure.
22 |
23 | """
--------------------------------------------------------------------------------
/TidalPy/WorldPack/pluto.toml:
--------------------------------------------------------------------------------
1 | name = "Pluto"
2 | type = "burnman"
3 | radius = 1189900.0
4 | semi_major_axis = 39.48
5 | semi_major_axis_in_au = true
6 | eccentricity = 0.2488
7 | spin_period = 6.3872304
8 | albedo = 0.55
9 | force_spin_sync = false
10 |
11 | [layers.Core]
12 | type = "rock"
13 | is_tidal = true
14 | radius = 910903.0
15 | material = "forsterite"
16 | material_source = "SLB_2011"
17 | temperature_mode = "adiabatic"
18 | temperature_top = 300.0
19 |
20 | [layers.Crust]
21 | type = "ice"
22 | is_tidal = false
23 | radius = 1189900.0
24 | material = "IceIh_Fu2010"
25 | material_source = "TidalPy"
26 | temperature_mode = "user-defined"
27 | surface_temperature = 40.0
28 | temperature_fixed = 40.0
29 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for TidalPy
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Example: I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/collapse/collapse.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 |
3 |
4 | cdef void cf_collapse_layer_solution(
5 | double complex* solution_ptr,
6 | double complex* constant_vector_ptr,
7 | double complex** storage_by_solution,
8 | double* layer_radius_ptr,
9 | double* layer_density_ptr,
10 | double* layer_gravity_ptr,
11 | double frequency_to_use,
12 | size_t layer_start_index,
13 | size_t num_layer_slices,
14 | size_t num_sols,
15 | size_t max_num_y,
16 | size_t num_ys,
17 | size_t num_output_ys,
18 | size_t ytype_i,
19 | int layer_type,
20 | cpp_bool layer_is_static,
21 | cpp_bool layer_is_incomp
22 | ) noexcept nogil
23 |
--------------------------------------------------------------------------------
/TidalPy/Material/eos/methods/interpolate.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 |
3 | from TidalPy.Material.eos.ode cimport EOS_ODEInput
4 |
5 | cdef int EOS_INTERPOLATE_METHOD_INT = 0
6 |
7 | cdef struct InterpolateEOSInput:
8 | size_t num_slices
9 | double* radius_array_ptr
10 | double* density_array_ptr
11 | double complex* bulk_modulus_array_ptr
12 | double complex* shear_modulus_array_ptr
13 |
14 | cdef void preeval_interpolate(
15 | # Values that will be updated by the function
16 | char* preeval_output,
17 | # Input that is used by the pre-eval
18 | double radius,
19 | double* radial_solutions,
20 | char* preeval_input
21 | ) noexcept nogil
22 |
--------------------------------------------------------------------------------
/TidalPy/utilities/arrays/interp.pxd:
--------------------------------------------------------------------------------
1 | cdef extern from "interp_.cpp" nogil:
2 | size_t cf_binary_search_with_guess(
3 | double key,
4 | double* array,
5 | size_t length,
6 | size_t guess
7 | )
8 |
9 | void cf_interp(
10 | double* desired_x_ptr,
11 | double* x_domain_ptr,
12 | double* dependent_values_ptr,
13 | size_t len_x,
14 | size_t* provided_j_ptr,
15 | double* result_ptr
16 | )
17 |
18 | void cf_interp_complex(
19 | double desired_x,
20 | double* x_domain_ptr,
21 | double* dependent_values_ptr,
22 | size_t len_x,
23 | size_t* provided_j_ptr,
24 | double* result_ptr
25 | )
26 |
--------------------------------------------------------------------------------
/TidalPy/utilities/arrays/interp_.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | static const double EPS = std::numeric_limits::epsilon();
6 |
7 | size_t cf_binary_search_with_guess(
8 | double key,
9 | double* array,
10 | size_t length,
11 | size_t guess
12 | );
13 |
14 | void cf_interp(
15 | double* desired_x_ptr,
16 | double* x_domain_ptr,
17 | double* dependent_values_ptr,
18 | size_t len_x,
19 | size_t* provided_j_ptr,
20 | double* result_ptr
21 | );
22 |
23 | void cf_interp_complex(
24 | double desired_x,
25 | double* x_domain_ptr,
26 | double* dependent_values_ptr,
27 | size_t len_x,
28 | size_t* provided_j_ptr,
29 | double* result_ptr
30 | );
31 |
--------------------------------------------------------------------------------
/TidalPy/cooling/__init__.py:
--------------------------------------------------------------------------------
1 | from TidalPy.utilities.classes.model.model_utils import build_model_default_inputs, find_all_models
2 |
3 | import TidalPy
4 | from . import cooling_models
5 |
6 |
7 | parameter_info_loc = ('cooling',)
8 |
9 | known_models, known_model_const_args, known_model_live_args = find_all_models(cooling_models)
10 |
11 |
12 | def get_cooling_model_default_inputs(layer_type: str):
13 | return build_model_default_inputs(known_model_const_args,
14 | TidalPy.config['layers'],
15 | inner_keys=(layer_type, 'cooling'))
16 |
17 |
18 | from .cooling import CoolingModel as CoolingModel
19 | from .cooling_models import CoolingOutputType as CoolingOutputType
20 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/earth_simple.toml:
--------------------------------------------------------------------------------
1 | name = "Earth_Simple"
2 | type = "layered"
3 | radius = 6371000.0
4 | semi_major_axis = 1.0
5 | semi_major_axis_in_au = true
6 | eccentricity = 0.01671022
7 | spin_period = 1.0
8 | tides_on = true
9 |
10 | [tides]
11 | model = "global_approx"
12 | fixed_q = 100.0
13 |
14 | [layers.Inner_Core]
15 | type = "iron"
16 | is_tidal = false
17 | radius = 1220000.0
18 | density = 17000.0
19 |
20 | [layers.Outer_Core]
21 | type = "iron"
22 | is_tidal = false
23 | radius = 3480000.0
24 | density = 12000.0
25 |
26 | [layers.Lower_Mantle]
27 | type = "rock"
28 | is_tidal = false
29 | radius = 5711000.0
30 | density = 5000.0
31 |
32 | [layers.Upper_Mantle]
33 | type = "rock"
34 | is_tidal = true
35 | radius = 6371000.0
36 | density = 3300.0
37 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/interfaces/reversed.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 | from libcpp.complex cimport complex as cpp_complex
3 |
4 |
5 | cdef void cf_top_to_bottom_interface_bc(
6 | double complex* constant_vector_ptr,
7 | double complex* layer_above_constant_vector_ptr,
8 | double complex* uppermost_y_per_solution_ptr,
9 | double gravity_upper,
10 | double layer_above_lower_gravity,
11 | double density_upper,
12 | double layer_above_lower_density,
13 | int layer_type,
14 | int layer_above_type,
15 | cpp_bool layer_is_static,
16 | cpp_bool layer_above_is_static,
17 | cpp_bool layer_is_incomp,
18 | cpp_bool layer_above_is_incomp,
19 | size_t num_sols,
20 | size_t max_num_y
21 | ) noexcept nogil
22 |
--------------------------------------------------------------------------------
/TidalPy/utilities/performance/__init__.py:
--------------------------------------------------------------------------------
1 | from .numba import njit as njit
2 | from .numba import use_numba as use_numba
3 | from .numba import bool_ as bool_
4 | from .numba import float64 as float64
5 | from .numba import int64 as int64
6 | from .numba import int32 as int32
7 | from .numba import int16 as int16
8 | from .numba import int8 as int8
9 | from .numba import uint64 as uint64
10 | from .numba import uint32 as uint32
11 | from .numba import uint16 as uint16
12 | from .numba import uint8 as uint8
13 | from .numba import complex128 as complex128
14 | from .numba import nbDict as nbDict
15 | from .numba import nbList as nbList
16 | from .numba import nbUnicode as nbUnicode
17 | from .numba import prange as prange
18 |
19 | from .special import find_factorial as find_factorial
--------------------------------------------------------------------------------
/TidalPy/utilities/performance/special/factorial.py:
--------------------------------------------------------------------------------
1 | """ Special math functions are defined here.
2 | """
3 |
4 | from scipy import special
5 | from numba import njit
6 |
7 |
8 | @njit(cache=False)
9 | def find_factorial(number: float) -> float:
10 | """ Find's the factorial of a number based on SciPy's Gamma function.
11 |
12 | Notes
13 | -----
14 | This uses the numba-scipy package to register overloads for scipy's special functions. This allows Numba to njit
15 | these functions, including gamma.
16 |
17 | Parameters
18 | ----------
19 | number : float
20 | Number to be factorialized.
21 |
22 | Returns
23 | -------
24 | factorial : float
25 | Factorial of 'number'
26 | """
27 |
28 | return special.gamma(number + 1.)
29 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/io.toml:
--------------------------------------------------------------------------------
1 | name = "Io"
2 | type = "burnman"
3 | radius = 1821490.0
4 | orbital_period = 1.769
5 | eccentricity = 0.0041
6 | spin_period = 1.769
7 | albedo = 0.63
8 | force_spin_sync = true
9 |
10 | [layers.Core]
11 | type = "iron"
12 | is_tidal = false
13 | radius = 810000.0
14 | material = [ "Pyrite", "Fe_Dewaele",]
15 | material_source = [ "TidalPy", "other",]
16 | material_fractions = [ 0.5, 0.5,]
17 | temperature_mode = "user-defined"
18 | temperature_fixed = 1800.0
19 |
20 | [layers.Mantle]
21 | type = "rock"
22 | is_tidal = true
23 | radius = 1821490.0
24 | material = [ "forsterite", "mg_perovskite",]
25 | material_source = [ "SLB_2011", "SLB_2011",]
26 | material_fractions = [ 0.65, 0.35,]
27 | temperature_mode = "adiabatic"
28 | temperature_top = 1800.0
29 | surface_temperature = 100.0
30 |
--------------------------------------------------------------------------------
/TidalPy/rheology/complex_compliance/__init__.py:
--------------------------------------------------------------------------------
1 | from TidalPy.utilities.classes.model.model_utils import build_model_default_inputs, find_all_models
2 |
3 | import TidalPy
4 | from . import compliance_models as complex_compliances
5 | from .compliance_models import find_factorial
6 |
7 | known_models, known_model_const_args, known_model_live_args = \
8 | find_all_models(complex_compliances, ignore_functional_types=(find_factorial,))
9 |
10 |
11 | def get_complex_comp_model_default_inputs(layer_type: str):
12 | return build_model_default_inputs(known_model_const_args,
13 | TidalPy.config['layers'],
14 | inner_keys=(layer_type, 'rheology'))
15 |
16 |
17 | from .complex_compliance import ComplexCompliance as ComplexCompliance
18 |
--------------------------------------------------------------------------------
/TidalPy/tides/multilayer/sensitivity.pxd:
--------------------------------------------------------------------------------
1 | cdef void cf_calc_sensitivity_to_shear(
2 | double* radial_sensitivity_to_shear_ptr,
3 | double complex* radial_solutions_ptr,
4 | double* radius_array_ptr,
5 | double complex* shear_modulus_array_ptr,
6 | double complex* bulk_modulus_array_ptr,
7 | size_t total_slices,
8 | size_t num_ytypes,
9 | int degree_l
10 | ) noexcept nogil
11 |
12 | cdef void cf_calc_sensitivity_to_bulk(
13 | double* radial_sensitivity_to_bulk_ptr,
14 | double complex* radial_solutions_ptr,
15 | double* radius_array_ptr,
16 | double complex* shear_modulus_array_ptr,
17 | double complex* bulk_modulus_array_ptr,
18 | size_t total_slices,
19 | size_t num_ytypes,
20 | int degree_l
21 | ) noexcept nogil
22 |
--------------------------------------------------------------------------------
/Benchmarks/Performance/performance suite/performance_build_world.py:
--------------------------------------------------------------------------------
1 | import TidalPy
2 |
3 | TidalPy.config['stream_level'] = 'WARNING'
4 | TidalPy.reinit()
5 |
6 | from TidalPy.structures import build_world
7 |
8 |
9 | from performance_base import PerformanceTrackBase
10 |
11 | class BuildWorldPerformance(PerformanceTrackBase):
12 |
13 | def run_perform_build_star(self):
14 | self.record_performance('Build World - Star', build_world,
15 | inputs=('55cnc',), repeats=3, number=10)
16 |
17 | def run_perform_build_simple_layered(self):
18 | self.record_performance('Build World - Layered', build_world,
19 | inputs=('io_simple',), repeats=3, number=10)
20 |
21 |
22 | if __name__ == '__main__':
23 | performance_tracker = BuildWorldPerformance()
--------------------------------------------------------------------------------
/TidalPy/numba_scipy/special/overloads.py:
--------------------------------------------------------------------------------
1 | import numba
2 | import scipy.special as sc
3 |
4 | from . import signatures
5 |
6 |
7 | def choose_kernel(name, all_signatures):
8 |
9 | def choice_function(*args):
10 | for signature in all_signatures:
11 | if args == signature:
12 | f = signatures.name_and_types_to_pointer[(name, *signature)]
13 | return lambda *args: f(*args)
14 |
15 | return choice_function
16 |
17 |
18 | def add_overloads():
19 | # print('!!TPY: Adding Numba-Scipy Overloads...')
20 | for name, all_signatures in signatures.name_to_numba_signatures.items():
21 | sc_function = getattr(sc, name)
22 | numba.extending.overload(sc_function)(
23 | choose_kernel(name, all_signatures)
24 | )
25 | # print('!!TPY: Done.')
26 |
--------------------------------------------------------------------------------
/Benchmarks/Performance/performance suite/run_suite.py:
--------------------------------------------------------------------------------
1 | from performance_build_world import BuildWorldPerformance
2 | from performance_complex_compliance_func import ComplexCompliancePerformance
3 | from performance_eccentricity_func import EccentricityFuncPerformance
4 | from performance_tides import TideCalcPerformance
5 | from performance_quick_calcs import QuickCalcPerformance
6 | from multilayer_radial_solver import TidalYPerformance
7 | from multimode_solver import MultilayerModeNumbaPerformance, MultilayerModePerformance
8 |
9 | if __name__ == '__main__':
10 | BuildWorldPerformance()
11 | ComplexCompliancePerformance()
12 | EccentricityFuncPerformance()
13 | TideCalcPerformance()
14 | QuickCalcPerformance()
15 | TidalYPerformance()
16 | MultilayerModeNumbaPerformance()
17 | MultilayerModePerformance()
18 |
--------------------------------------------------------------------------------
/TidalPy/utilities/multiprocessing/__init__.py:
--------------------------------------------------------------------------------
1 | psutil_installed = False
2 | try:
3 | import psutil as psutil
4 | psutil_installed = True
5 | except ImportError:
6 |
7 | # Build fake class for type checking
8 | class psutil:
9 | def virtual_memory(self):
10 | pass
11 | def cpu_count(self):
12 | pass
13 |
14 | pathos_installed = False
15 | try:
16 | from pathos import multiprocessing as pathos_mp
17 | pathos_installed = True
18 | except ImportError:
19 | # Pathos is not installed. Use Python's multiprocessing instead.
20 | pathos_mp = None
21 |
22 | from .multiprocessing import multiprocessing_run as multiprocessing_run
23 | from .multiprocessing import MultiprocessingInput as MultiprocessingInput
24 | from .multiprocessing import MultiprocessingOutput as MultiprocessingOutput
--------------------------------------------------------------------------------
/TidalPy/Material/eos/solver.pxd:
--------------------------------------------------------------------------------
1 | from libcpp.vector cimport vector
2 | from libcpp.memory cimport unique_ptr
3 | from libcpp cimport bool as cpp_bool
4 |
5 | from CyRK cimport PreEvalFunc, CySolveOutput, ODEMethod
6 |
7 | from TidalPy.Material.eos.ode cimport EOS_ODEInput
8 | from TidalPy.Material.eos.eos_solution cimport EOSSolutionCC, EOS_DY_VALUES
9 |
10 | cdef void solve_eos(
11 | EOSSolutionCC* eos_solution_ptr,
12 | vector[PreEvalFunc] eos_function_bylayer_ptr_vec,
13 | vector[EOS_ODEInput] eos_input_bylayer_vec,
14 | double planet_bulk_density,
15 | double surface_pressure = *,
16 | double G_to_use = *,
17 | ODEMethod integration_method = *,
18 | double rtol = *,
19 | double atol = *,
20 | double pressure_tol = *,
21 | size_t max_iters = *,
22 | cpp_bool verbose = *
23 | ) noexcept nogil
24 |
--------------------------------------------------------------------------------
/TidalPy/stellar/__init__.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 | from .insolation import calc_equilibrium_temperature as calc_equilibrium_temperature
4 | from .insolation import equilibrium_insolation_mendez as equilibrium_insolation_mendez
5 | from .insolation import equilibrium_insolation_no_eccentricity as equilibrium_insolation_no_eccentricity
6 | from .insolation import equilibrium_insolation_williams as equilibrium_insolation_williams
7 |
8 | EquilibFuncType = Union[type(equilibrium_insolation_mendez), type(equilibrium_insolation_no_eccentricity),
9 | type(equilibrium_insolation_williams)]
10 |
11 | equilibrium_insolation_functions = {
12 | 'no_eccentricity': equilibrium_insolation_no_eccentricity,
13 | 'williams' : equilibrium_insolation_williams,
14 | 'mendez' : equilibrium_insolation_mendez
15 | }
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve TidalPy
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Versions (please complete the following information, where applicable):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - TidalPy Version [e.g. 22]
30 |
31 | **Additional context**
32 | Add any other context about the problem here.
33 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/triton.toml:
--------------------------------------------------------------------------------
1 | name = "Triton"
2 | type = "burnman"
3 | radius = 1353000.0
4 | semi_major_axis = 354760000.0
5 | semi_major_axis_in_au = false
6 | eccentricity = 1.6e-5
7 | spin_period = 5.876854
8 | albedo = 0.55
9 | force_spin_sync = false
10 |
11 | [layers.Core]
12 | type = "rock"
13 | is_tidal = true
14 | radius = 1064000.0
15 | material = "forsterite"
16 | material_source = "SLB_2011"
17 | temperature_mode = "adiabatic"
18 | temperature_top = 273.15
19 |
20 | [layers.Crust]
21 | type = "ice"
22 | is_tidal = true
23 | radius = 1353000.0
24 | material = "IceIh_Fu2010"
25 | material_source = "TidalPy"
26 | temperature_mode = "user-defined"
27 | surface_temperature = 35.0
28 | temperature_fixed = 35.0
29 |
30 | [layers.Core.rheology.complex_compliance]
31 | model = "sundberg"
32 |
33 | [layers.Crust.rheology.complex_compliance]
34 | model = "sundberg"
35 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": [
3 | {
4 | "type": "cppbuild",
5 | "label": "C/C++: gcc.exe build active file",
6 | "command": "C:\\Software\\mingw64\\bin\\gcc.exe",
7 | "args": [
8 | "-fdiagnostics-color=always",
9 | "-g",
10 | "${file}",
11 | "-o",
12 | "${fileDirname}\\${fileBasenameNoExtension}.exe"
13 | ],
14 | "options": {
15 | "cwd": "${fileDirname}"
16 | },
17 | "problemMatcher": [
18 | "$gcc"
19 | ],
20 | "group": {
21 | "kind": "build",
22 | "isDefault": true
23 | },
24 | "detail": "Task generated by Debugger."
25 | }
26 | ],
27 | "version": "2.0.0"
28 | }
--------------------------------------------------------------------------------
/TidalPy/WorldPack/luna.toml:
--------------------------------------------------------------------------------
1 | name = "Luna"
2 | type = "burnman"
3 | radius = 1737400.0
4 | orbital_period = 27.322
5 | eccentricity = 0.0554
6 | spin_period = 27.322
7 | albedo = 0.12
8 | force_spin_sync = true
9 |
10 | [layers.Inner_Core]
11 | type = "iron"
12 | is_tidal = false
13 | radius = 160000.0
14 | material = "Fe_Dewaele"
15 | material_source = "other"
16 | temperature_mode = "user-defined"
17 | temperature_fixed = 300.0
18 |
19 | [layers.Outer_Core]
20 | type = "iron"
21 | is_tidal = false
22 | radius = 350000.0
23 | material = "Liquid_Fe_Anderson"
24 | material_source = "other"
25 | temperature_mode = "user-defined"
26 | temperature_fixed = 300.0
27 |
28 | [layers.Mantle]
29 | type = "rock"
30 | is_tidal = false
31 | radius = 1737400.0
32 | material = "forsterite"
33 | material_source = "SLB_2011"
34 | temperature_mode = "adiabatic"
35 | temperature_top = 350.0
36 | surface_temperature = 300.0
37 |
--------------------------------------------------------------------------------
/TidalPy/utilities/conversions/conversions_x.pxd:
--------------------------------------------------------------------------------
1 | cdef double cf_m2Au(
2 | double meters
3 | ) noexcept nogil
4 |
5 | cdef double cf_Au2m(
6 | double astronomical_units
7 | ) noexcept nogil
8 |
9 | cdef double cf_rads2days(
10 | double radians_per_second
11 | ) noexcept nogil
12 |
13 | cdef double cf_days2rads(
14 | double days
15 | ) noexcept nogil
16 |
17 | cdef double cf_sec2myr(
18 | double seconds
19 | ) noexcept nogil
20 |
21 | cdef double cf_myr2sec(
22 | double myrs
23 | ) noexcept nogil
24 |
25 | cdef double cf_orbital_motion2semi_a(
26 | double orbital_motion,
27 | double host_mass,
28 | double target_mass = *,
29 | double G_to_use = *
30 | ) noexcept nogil
31 |
32 | cdef double cf_semi_a2orbital_motion(
33 | double semi_major_axis,
34 | double host_mass,
35 | double target_mass = *,
36 | double G_to_use = *
37 | ) noexcept nogil
38 |
--------------------------------------------------------------------------------
/TidalPy/utilities/conversions/timing.py:
--------------------------------------------------------------------------------
1 | from typing import Tuple
2 |
3 | from TidalPy.utilities.performance.numba import njit
4 |
5 |
6 | @njit(cacheable=True)
7 | def convert_to_hms(seconds: float) -> Tuple[int, int, int, float]:
8 | """ Convert seconds to a tuple of days, hours, minutes, seconds
9 |
10 | Parameters
11 | ----------
12 | seconds : float
13 | Time in seconds
14 |
15 | Returns
16 | -------
17 | days : int
18 | Days
19 | hours : int
20 | Hours
21 | minutes : int
22 | Minutes
23 | seconds : float
24 | Remaining seconds after conversion
25 | """
26 |
27 | days = int(seconds / (24. * 3600.))
28 | seconds = seconds % (24. * 3600.)
29 | hours = int(seconds / 3600.)
30 | seconds = seconds % 3600.
31 | minutes = int(seconds / 60.)
32 | seconds = seconds % 60.
33 |
34 | return days, hours, minutes, seconds
35 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1e.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein.
7 |
8 | name = "TRAPPIST-1e"
9 | type = "simple_tidal"
10 | radius = 5868000.0
11 | radius_error_pos = 82000.0
12 | radius_error_neg = 75000.0
13 | mass = 2.316e+24
14 | mass_error_pos = 1.3e+23
15 | mass_error_neg = 1.3e+23
16 | semi_major_axis = 4376000000.0
17 | semi_major_axis_error_pos = 37000000.0
18 | semi_major_axis_error_neg = 37000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.00447
21 | eccentricity_error_pos = 0.00014
22 | eccentricity_error_neg = 0.00014
23 | force_spin_sync = true
24 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1g.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein.
7 |
8 | name = "TRAPPIST-1g"
9 | type = "simple_tidal"
10 | radius = 7204000.0
11 | radius_error_pos = 94000.0
12 | radius_error_neg = 85000.0
13 | mass = 7.89e+24
14 | mass_error_pos = 2.26e+23
15 | mass_error_neg = 2.26e+23
16 | semi_major_axis = 7006000000.0
17 | semi_major_axis_error_pos = 60000000.0
18 | semi_major_axis_error_neg = 60000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.00254
21 | eccentricity_error_pos = 0.00126
22 | eccentricity_error_neg = 0.00126
23 | force_spin_sync = true
24 |
--------------------------------------------------------------------------------
/Tests/Test_Math/test_utilities_numerics.py:
--------------------------------------------------------------------------------
1 | import pytest
2 |
3 | from math import isclose as py_isclose
4 | from math import nan
5 |
6 | from TidalPy.utilities.math.numerics import isclose
7 |
8 |
9 | @pytest.mark.parametrize('a', (0.0, -55.222226, 10., 1.0e200, -1.0e200, 1.0e-9, 1.0e-5, -1.0e-9, -1.0e-5, 1.4562221e34, 1.0e-14, 0.98e-14))
10 | @pytest.mark.parametrize('b', (0.0, -55.222222, 10., 1.0e200, -1.0e200, 1.0e-9, 1.0e-5, -1.0e-9, -1.0e-5, 1.4582221e34, 1.0e-14, 0.98e-14))
11 | @pytest.mark.parametrize('rtol', (3.0, 1.0e-9, 1.0e-3))
12 | @pytest.mark.parametrize('atol', (3.0, 1.0e-3, 0.0))
13 | def test_math_isclose(a, b, rtol, atol):
14 |
15 | pyresult = py_isclose(a, b, rel_tol=rtol, abs_tol=atol)
16 | tpyresult = isclose(a, b, rtol, atol)
17 |
18 | assert pyresult == tpyresult
19 |
20 | def test_math_isclose_nans():
21 |
22 | assert isclose(nan, 10.0) == False
23 | assert isclose(10.0, nan) == False
24 |
25 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1c.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein.
7 |
8 | name = "TRAPPIST-1c"
9 | type = "simple_tidal"
10 | radius = 6995000.0
11 | radius_error_pos = 86000.0
12 | radius_error_neg = 77000.0
13 | mass = 7.814e+24
14 | mass_error_pos = 3.35e+23
15 | mass_error_neg = 3.35e+23
16 | semi_major_axis = 2364000000.0
17 | semi_major_axis_error_pos = 20000000.0
18 | semi_major_axis_error_neg = 20000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.00028
21 | eccentricity_error_pos = 0.00027
22 | eccentricity_error_neg = 0.00027
23 | force_spin_sync = true
24 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1d.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein.
7 |
8 | name = "TRAPPIST-1d"
9 | type = "simple_tidal"
10 | radius = 5026000.0
11 | radius_error_pos = 71000.0
12 | radius_error_neg = 66000.0
13 | mass = 2.316e+24
14 | mass_error_pos = 7.4e+22
15 | mass_error_neg = 7.4e+22
16 | semi_major_axis = 3331000000.0
17 | semi_major_axis_error_pos = 28000000.0
18 | semi_major_axis_error_neg = 28000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.003815
21 | eccentricity_error_pos = 0.001145
22 | eccentricity_error_neg = 0.001145
23 | force_spin_sync = true
24 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1f.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein.
7 |
8 | name = "TRAPPIST-1f"
9 | type = "simple_tidal"
10 | radius = 6664000.0
11 | radius_error_pos = 85000.0
12 | radius_error_neg = 77000.0
13 | mass = 6.205e+24
14 | mass_error_pos = 1.84e+23
15 | mass_error_neg = 1.84e+23
16 | semi_major_axis = 5758000000.0
17 | semi_major_axis_error_pos = 49000000.0
18 | semi_major_axis_error_neg = 49000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.004455
21 | eccentricity_error_pos = 0.003945
22 | eccentricity_error_neg = 0.003945
23 | force_spin_sync = true
24 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1h.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein.
7 |
8 | name = "TRAPPIST-1h"
9 | type = "simple_tidal"
10 | radius = 4817000.0
11 | radius_error_pos = 91000.0
12 | radius_error_neg = 88000.0
13 | mass = 1.945e+24
14 | mass_error_pos = 1.22e+23
15 | mass_error_neg = 1.22e+23
16 | semi_major_axis = 9259000000.0
17 | semi_major_axis_error_pos = 79000000.0
18 | semi_major_axis_error_neg = 79000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.001835
21 | eccentricity_error_pos = 0.001815
22 | eccentricity_error_neg = 0.001815
23 | force_spin_sync = true
24 |
--------------------------------------------------------------------------------
/TidalPy/utilities/math/numerics.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
3 |
4 | from libc.math cimport fabs, fmax, isnan
5 |
6 |
7 | cdef cpp_bool cf_isclose(
8 | double a,
9 | double b,
10 | double rtol = 1.0e-9,
11 | double atol = 0.0
12 | ) noexcept nogil:
13 |
14 | if isnan(a):
15 | return False
16 |
17 | if isnan(b):
18 | return False
19 |
20 | # Check for pure equivalence
21 | if a == b:
22 | return True
23 |
24 | # Check for closeness
25 | cdef double lhs = fabs(a - b)
26 | cdef double rhs = fmax(rtol * fmax(fabs(a), fabs(b)), atol)
27 |
28 | return lhs <= rhs
29 |
30 |
31 | def isclose(
32 | double a,
33 | double b,
34 | double rtol = 1.0e-9,
35 | double atol = 0.0):
36 |
37 | return cf_isclose(a, b, rtol, atol)
38 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/matrix.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 | from libcpp.memory cimport shared_ptr
3 | from libcpp.vector cimport vector
4 |
5 | from TidalPy.RadialSolver.rs_solution cimport RadialSolutionStorageCC
6 |
7 | cdef int cf_matrix_propagate(
8 | RadialSolutionStorageCC* solution_storage_ptr,
9 | double frequency,
10 | double planet_bulk_density,
11 | # TODO: In the future the propagation matrix should take in layer types and multiple layers
12 | # int* layer_types_ptr,
13 | # int* is_static_by_layer_ptr,
14 | # int* is_incompressible_by_layer_ptr,
15 | vector[size_t] first_slice_index_by_layer_vec,
16 | vector[size_t] num_slices_by_layer_vec,
17 | size_t num_bc_models,
18 | int* bc_models_ptr,
19 | double G_to_use,
20 | int degree_l,
21 | double starting_radius,
22 | double start_radius_tolerance,
23 | int core_model,
24 | cpp_bool verbose
25 | ) noexcept nogil
26 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/55cnce.toml:
--------------------------------------------------------------------------------
1 | # Very roughly pulled from some analysis by Dorn+ (A&A 2017)
2 |
3 | name = "55-Cancri-e"
4 | type = "burnman"
5 | radius = 11950000.0
6 | semi_major_axis = 0.01544
7 | semi_major_axis_in_au = true
8 | eccentricity = 0.02
9 | spin_period = 1.0
10 | force_spin_sync = true
11 |
12 | [layers.Core]
13 | type = "iron"
14 | is_tidal = false
15 | radius = 4000000.0
16 | material = "Fe_Dewaele"
17 | material_source = "other"
18 | temperature_mode = "user-defined"
19 | temperature_fixed = 300.0
20 |
21 | [layers.Lower_Mantle]
22 | type = "rock"
23 | is_tidal = false
24 | radius = 8959000.0
25 | material = "mg_bridgmanite"
26 | material_source = "SLB_2011"
27 | temperature_mode = "adiabatic"
28 |
29 | [layers.Upper_Mantle]
30 | type = "rock"
31 | is_tidal = true
32 | radius = 11950000.0
33 | material = "forsterite"
34 | material_source = "SLB_2011"
35 | temperature_mode = "adiabatic"
36 | temperature_top = 1200.0
37 | surface_temperature = 300.0
38 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/trappist1b.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein. Eccentricities are from Grimm+2018
7 |
8 | name = "TRAPPIST-1b"
9 | type = "simple_tidal"
10 | radius = 7119000.0
11 | radius_error_pos = 87000.0
12 | radius_error_neg = 77000.0
13 | mass = 8.311e+24
14 | mass_error_pos = 4.12e+23
15 | mass_error_neg = 4.12e+23
16 | semi_major_axis = 1726000000.0
17 | semi_major_axis_error_pos = 15000000.0
18 | semi_major_axis_error_neg = 15000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.00216
21 | eccentricity_error_pos = 1e-5
22 | eccentricity_error_neg = 1e-5
23 | force_spin_sync = true
24 |
--------------------------------------------------------------------------------
/TidalPy/utilities/classes/base_x.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
3 |
4 | from TidalPy import config
5 |
6 | cdef bint DEBUG_MODE
7 | DEBUG_MODE = config['debug']['extensive_checks']
8 |
9 | cdef class TidalPyBaseExtensionClass:
10 | """
11 | TidalPy's base extension class used as a basis for most other cython extension types used throughout TidalPy.
12 | """
13 |
14 |
15 | def __init__(
16 | self,
17 | str class_name = 'TidalPyBaseExtensionClass',
18 | str name_prefix = '',
19 | bint debug_mode = DEBUG_MODE
20 | ):
21 |
22 | # Store base class properties
23 | self.class_name = class_name
24 | self.name_prefix = name_prefix
25 | self.debug_mode = debug_mode
26 |
27 |
28 | def __str__(self):
29 | return f'{self.name_prefix}::[!{self.class_name}].'
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetB_Package/test_c_tools_timing.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 |
4 |
5 | from TidalPy.utilities.conversions.timing import convert_to_hms
6 |
7 | def test_convert_hms():
8 | """ Test the convert_to_hms function """
9 |
10 | result = convert_to_hms(60.)
11 | assert type(result) == tuple
12 |
13 | day, hour, minute, second = result
14 | assert type(day) in [int, np.int32]
15 | assert type(hour) in [int, np.int32]
16 | assert type(minute) in [int, np.int32]
17 | assert type(second) in [float, np.float64]
18 |
19 | assert day == 0
20 | assert hour == 0
21 | assert minute == 1
22 | assert second == 0.
23 |
24 | day, hour, minute, second = convert_to_hms(198000.)
25 | assert day == 2
26 | assert hour == 7
27 | assert minute == 0
28 | assert second == 0.
29 |
30 | day, hour, minute, second = convert_to_hms(198025.5)
31 | assert day == 2
32 | assert hour == 7
33 | assert minute == 0
34 | assert second == 25.5
35 |
--------------------------------------------------------------------------------
/TidalPy/rheology/viscosity/__init__.py:
--------------------------------------------------------------------------------
1 | from TidalPy.utilities.classes.model.model_utils import build_model_default_inputs, find_all_models
2 |
3 | import TidalPy
4 | from . import viscosity_models
5 |
6 | known_models, known_model_const_args, known_model_live_args = find_all_models(viscosity_models)
7 |
8 |
9 | def get_solid_viscosity_model_default_inputs(layer_type: str):
10 | return build_model_default_inputs(known_model_const_args,
11 | TidalPy.config['layers'],
12 | inner_keys=(layer_type, 'solid_viscosity'))
13 |
14 |
15 | def get_liquid_viscosity_model_default_inputs(layer_type: str):
16 | return build_model_default_inputs(known_model_const_args,
17 | TidalPy.config['layers'],
18 | inner_keys=(layer_type, 'liquid_viscosity'))
19 |
20 |
21 | from .viscosity import LiquidViscosity as LiquidViscosity
22 | from .viscosity import SolidViscosity as SolidViscosity
23 |
--------------------------------------------------------------------------------
/TidalPy/utilities/integration/scipy_helper.py:
--------------------------------------------------------------------------------
1 | """ Helper functions to interface with SciPy's integration suite """
2 |
3 | from typing import Tuple
4 |
5 | import numpy as np
6 |
7 | from . import _solve_ivp
8 |
9 |
10 | def solve_ivp(
11 | diffeq, time_span: Tuple[float, float], initial_condition: np.ndarray, args: Tuple = None,
12 | rtol: float = 1.0e-6, atol: float = 1.0e-8, max_step: float = np.inf,
13 | first_step: float = None, method: str = 'RK45', t_eval: np.ndarray = np.empty((0,), dtype=np.float64)
14 | ):
15 |
16 | # Solve the ode
17 | solution = _solve_ivp(
18 | diffeq, time_span, initial_condition, method=method, t_eval=t_eval, args=args,
19 | first_step=first_step, max_step=max_step, rtol=rtol, atol=atol
20 | )
21 |
22 | # Pull out information from SciPy's solution class
23 | time_domain = solution.t
24 | y_results = solution.y
25 | success = solution.success
26 | message = solution.message
27 |
28 | return time_domain, y_results, success, message
29 |
--------------------------------------------------------------------------------
/TidalPy/rheology/base.pxd:
--------------------------------------------------------------------------------
1 | from TidalPy.utilities.classes.base_x cimport TidalPyBaseExtensionClass
2 |
3 |
4 | cdef class RheologyModelBase(TidalPyBaseExtensionClass):
5 |
6 | # Class attributes
7 | cdef size_t expected_num_args
8 |
9 | # Class methods
10 | cdef double complex _implementation(
11 | self,
12 | double frequency,
13 | double modulus,
14 | double viscosity
15 | ) noexcept nogil
16 |
17 | cdef void _vectorize_frequency(
18 | self,
19 | double* frequency_ptr,
20 | double modulus,
21 | double viscosity,
22 | double complex* output_ptr,
23 | Py_ssize_t n,
24 | ) noexcept nogil
25 |
26 | cdef void _vectorize_modulus_viscosity(
27 | self,
28 | double frequency,
29 | double* modulus_ptr,
30 | double* viscosity_ptr,
31 | double complex* output_ptr,
32 | Py_ssize_t n,
33 | ) noexcept nogil
34 |
--------------------------------------------------------------------------------
/TidalPy/dynamics/__init__.py:
--------------------------------------------------------------------------------
1 | from .dual_dissipation import eccentricity_derivative as eccentricity_derivative_dual_
2 | from .dual_dissipation import semi_major_axis_derivative as semi_major_axis_derivative_dual_
3 | from .dual_dissipation import semia_eccen_derivatives as semia_eccen_derivatives_dual_
4 |
5 | from .single_dissipation import eccentricity_derivative as eccentricity_derivative_
6 | from .single_dissipation import semi_major_axis_derivative as semi_major_axis_derivative_
7 | from .single_dissipation import semia_eccen_derivatives as semia_eccen_derivatives_
8 | from .single_dissipation import spin_rate_derivative as spin_rate_derivative
9 |
10 | eccentricity_derivative_dual = eccentricity_derivative_dual_
11 | semi_major_axis_derivative_dual = semi_major_axis_derivative_dual_
12 | semia_eccen_derivatives_dual = semia_eccen_derivatives_dual_
13 | eccentricity_derivative = eccentricity_derivative_
14 | semi_major_axis_derivative = semi_major_axis_derivative_
15 | semia_eccen_derivatives = semia_eccen_derivatives_
16 |
--------------------------------------------------------------------------------
/TidalPy/output.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 |
3 | import TidalPy
4 | from TidalPy.logger import get_logger
5 |
6 | log = get_logger("TidalPy")
7 |
8 | def set_output_dir(new_output_dir: str) -> str:
9 | """Sets new output directory for TidalPy data and logs.
10 |
11 | Parameters
12 | ----------
13 | new_output_dir : str
14 | New output directory. TidalPy will create a new directory if it does not exist.
15 |
16 | Returns
17 | -------
18 | str
19 | New output directory.
20 | """
21 |
22 | assert type(new_output_dir) is str
23 | log.debug(f'TidalPy output directory changing to {new_output_dir}.')
24 | TidalPy._output_path = new_output_dir
25 | return new_output_dir
26 |
27 | def create_output_dir() -> str:
28 | """Creates an output directory for TidalPy data.
29 |
30 | Returns
31 | -------
32 | str
33 | Path to output directory.
34 | """
35 |
36 | Path(TidalPy._output_path).mkdir(parents=True, exist_ok=True)
37 | return TidalPy._output_path
38 |
39 |
--------------------------------------------------------------------------------
/TidalPy/rheology/partial_melt/__init__.py:
--------------------------------------------------------------------------------
1 | from TidalPy.utilities.classes.model.model_utils import build_model_default_inputs, find_all_models
2 |
3 | import TidalPy
4 | from . import melting_models as partial_melting_models
5 |
6 | known_models, known_model_const_args, known_model_live_args = find_all_models(partial_melting_models)
7 |
8 |
9 | def get_partial_melt_model_default_inputs(layer_type: str):
10 | return build_model_default_inputs(known_model_const_args,
11 | TidalPy.config['layers'],
12 | inner_keys=(layer_type, 'partial_melting'))
13 |
14 |
15 | from .partialmelt import PartialMelt as PartialMelt
16 | from .partialmelt import calculate_melt_fraction as calculate_melt_fraction
17 | from .partialmelt import calculate_temperature_frommelt as calculate_temperature_frommelt
18 | from .partialmelt import calculate_temperature_frommelt_array as calculate_temperature_frommelt_array
19 | from .partialmelt import calculate_melt_fraction_array as calculate_melt_fraction_array
20 |
--------------------------------------------------------------------------------
/TidalPy/tides/__init__.py:
--------------------------------------------------------------------------------
1 | from .love1d import complex_love
2 | from .love1d import complex_love_general
3 | from .love1d import effective_rigidity
4 | from .love1d import effective_rigidity_general
5 | from .love1d import static_love
6 | from .love1d import static_love_general
7 |
8 | from .methods import TidesBase as TidesBase
9 | from .methods import GlobalApproxTides as GlobalApproxTides
10 | from .methods import LayeredTides as LayeredTides
11 |
12 | from .dissipation import calc_tidal_susceptibility as calc_tidal_susceptibility
13 | from .dissipation import calc_tidal_susceptibility_reduced as calc_tidal_susceptibility_reduced
14 |
15 | from .heating import calculate_volumetric_heating as calculate_volumetric_heating
16 | # Alias functions
17 |
18 | calc_complex_love = complex_love
19 | calc_complex_love_general = complex_love_general
20 | calc_effective_rigidity = effective_rigidity
21 | calc_static_love = static_love
22 | calc_static_love_general = static_love_general
23 | calc_effective_rigidity_general = effective_rigidity_general
24 |
--------------------------------------------------------------------------------
/TidalPy/utilities/types.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 | import numpy as np
4 |
5 | # General helpers
6 | NoneType = type(None)
7 |
8 | # Numpy and Array type lists
9 | float_like = [float, np.float64]
10 | floatarray_like = [float, np.float64, np.ndarray]
11 | int_like = [int, np.int32, np.int64]
12 |
13 | numpy_float_info = np.finfo(dtype=np.float64)
14 | float_eps = numpy_float_info.eps
15 | float_max = numpy_float_info.max
16 | float_min = numpy_float_info.min
17 | float_log10_max = np.log10(float_max)
18 | float_lognat_max = np.log(float_max)
19 |
20 | # Other type lists
21 | list_like = [list, tuple, set]
22 |
23 | # Type-annotation helpers
24 | NumericalType = Union[float, int, complex, np.float64, np.int64]
25 | FloatArray = Union[float, np.float64, np.ndarray]
26 | ComplexArray = Union[complex, np.complex128, np.ndarray]
27 | NumArray = Union[FloatArray, ComplexArray]
28 | TupleNone = Union[tuple, NoneType]
29 | ArrayNone = Union[np.ndarray, NoneType]
30 | FloatNone = Union[NoneType, float]
31 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/europa.toml:
--------------------------------------------------------------------------------
1 | name = "Europa"
2 | type = "burnman"
3 | radius = 1561000.0
4 | orbital_period = 3.551181
5 | eccentricity = 0.01
6 | spin_period = 3.551181
7 | albedo = 0.67
8 | force_spin_sync = true
9 |
10 | [layers.Core]
11 | type = "iron"
12 | is_tidal = false
13 | radius = 599000.0
14 | material = [ "Pyrite", "Fe_Dewaele",]
15 | material_source = [ "TidalPy", "other",]
16 | material_fractions = [ 0.5, 0.5,]
17 | temperature_mode = "user-defined"
18 | temperature_fixed = 1800.0
19 |
20 | [layers.Mantle]
21 | type = "rock"
22 | is_tidal = false
23 | radius = 1421000.0
24 | material = [ "forsterite", "mg_perovskite",]
25 | material_source = [ "SLB_2011", "SLB_2011",]
26 | material_fractions = [ 0.65, 0.35,]
27 | temperature_mode = "adiabatic"
28 | temperature_top = 1800.0
29 | surface_temperature = 273.15
30 |
31 | [layers.Crust]
32 | type = "ice"
33 | is_tidal = true
34 | radius = 1561000.0
35 | material = "LowPressureIceConst"
36 | material_source = "TidalPy"
37 | temperature_mode = "user-defined"
38 | surface_temperature = 100.0
39 | temperature_fixed = 100.0
40 |
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetA_Package/test_io.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 |
3 | from TidalPy.paths import timestamped_str, unique_path
4 |
5 |
6 | def test_timestamp():
7 | """ Test the timestamp to string function """
8 |
9 | time_str = timestamped_str()
10 | assert type(time_str) == str
11 |
12 | time_str = timestamped_str(string_to_stamp='', date=False, time=False, second=False)
13 | assert time_str == ''
14 |
15 | time_str = timestamped_str(string_to_stamp='Hello', date=True, time=True, second=True)
16 | assert type(time_str) == str
17 |
18 | now = datetime.now()
19 | time_str = timestamped_str(string_to_stamp='Hello', date=True, time=True, second=True, provided_datetime=now)
20 | assert type(time_str) == str
21 |
22 |
23 | def test_uniquepath():
24 | """ Test the unique path function """
25 |
26 | new_path = unique_path(attempt_path='Test', is_dir=False, make_dir=False)
27 | assert type(new_path) == str
28 |
29 | new_path = unique_path(attempt_path='Test', is_dir=True, make_dir=False)
30 | assert type(new_path) == str
31 |
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/burnman_defaultc.py:
--------------------------------------------------------------------------------
1 | default_burnman_configs = {
2 | 'worlds': {
3 | 'types': {
4 | 'burnman': {
5 | 'name' : 'unknown_world_burnman_type',
6 | 'store_tides_config_in_world' : True,
7 | 'force_spin_sync' : True,
8 | 'equilibrium_insolation_model' : 'williams',
9 | 'fraction_internal_heating_to_surface': 1.0,
10 | 'emissivity' : 0.9,
11 | 'albedo' : 0.3,
12 | 'use_real_moi' : True,
13 | 'tides_on' : True,
14 | 'surface_pressure' : 0.,
15 | 'slices' : None,
16 | 'bm_interpolation_method' : 'mid', # Options: mid, avg, median
17 | 'bm_interpolation_n' : 100
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/earth.toml:
--------------------------------------------------------------------------------
1 | name = "Earth"
2 | type = "burnman"
3 | radius = 6371000.0
4 | semi_major_axis = 1.0
5 | semi_major_axis_in_au = true
6 | eccentricity = 0.01671022
7 | spin_period = 1.0
8 |
9 | [layers.Inner_Core]
10 | type = "iron"
11 | is_tidal = false
12 | radius = 1220000.0
13 | material = "Fe_Dewaele"
14 | material_source = "other"
15 | temperature_mode = "user-defined"
16 | temperature_fixed = 300.0
17 |
18 | [layers.Outer_Core]
19 | type = "iron"
20 | is_tidal = false
21 | radius = 3480000.0
22 | material = "Liquid_Fe_Anderson"
23 | material_source = "other"
24 | temperature_mode = "user-defined"
25 | temperature_fixed = 300.0
26 |
27 | [layers.Lower_Mantle]
28 | type = "rock"
29 | is_tidal = false
30 | radius = 5711000.0
31 | material = "mg_bridgmanite"
32 | material_source = "SLB_2011"
33 | temperature_mode = "adiabatic"
34 |
35 | [layers.Upper_Mantle]
36 | type = "rock"
37 | is_tidal = true
38 | radius = 6371000.0
39 | material = "forsterite"
40 | material_source = "SLB_2011"
41 | temperature_mode = "adiabatic"
42 | temperature_top = 1200.0
43 | surface_temperature = 300.0
44 |
--------------------------------------------------------------------------------
/TidalPy/WorldPack/mercury.toml:
--------------------------------------------------------------------------------
1 | # Pulled from central results of Goossens+2021
2 |
3 | name = "Mercury"
4 | type = "burnman"
5 | radius = 2440000.0
6 | semi_major_axis = 0.38709893
7 | semi_major_axis_in_au = true
8 | eccentricity = 0.20563069
9 | spin_period = 58.6462
10 | force_spin_sync = false
11 |
12 | [layers.Inner_Core]
13 | type = "iron"
14 | is_tidal = false
15 | radius = 1277250.0
16 | material = [ "Pyrite", "Fe_Dewaele",]
17 | material_source = [ "TidalPy", "other",]
18 | material_fractions = [ 0.8, 0.2,]
19 | temperature_mode = "user-defined"
20 | temperature_fixed = 2100.0
21 |
22 | [layers.Outer_Core]
23 | type = "iron"
24 | is_tidal = false
25 | radius = 1965000.0
26 | material = [ "Pyrite", "Fe_Dewaele",]
27 | material_source = [ "TidalPy", "other",]
28 | material_fractions = [ 0.8, 0.2,]
29 | temperature_mode = "adiabatic"
30 | temperature_fixed = 2100.0
31 |
32 | [layers.Mantle]
33 | type = "rock"
34 | is_tidal = true
35 | radius = 2440000.0
36 | material = "forsterite"
37 | material_source = "SLB_2011"
38 | temperature_mode = "adiabatic"
39 | temperature_top = 1200.0
40 | surface_temperature = 452.0
41 |
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetE_Functional/test_a_performance_funcs.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | from scipy.special import gamma
3 |
4 |
5 |
6 |
7 | def test_find_factorial():
8 | # Test Load
9 | from TidalPy.utilities.performance import find_factorial
10 | assert type(find_factorial(1.)) in [float, np.float64]
11 |
12 | # Test Floats
13 | assert find_factorial(0.) == 1.
14 | np.testing.assert_approx_equal(find_factorial(0.1), gamma(0.1 + 1))
15 | np.testing.assert_approx_equal(find_factorial(0.2), gamma(0.2 + 1))
16 | np.testing.assert_approx_equal(find_factorial(0.3), gamma(0.3 + 1))
17 | np.testing.assert_approx_equal(find_factorial(0.45), gamma(0.45 + 1))
18 | np.testing.assert_approx_equal(find_factorial(0.5), gamma(0.5 + 1))
19 | np.testing.assert_approx_equal(find_factorial(0.75), gamma(0.75 + 1))
20 | np.testing.assert_approx_equal(find_factorial(0.9), gamma(0.9 + 1))
21 | np.testing.assert_approx_equal(find_factorial(3.0), gamma(3.0 + 1))
22 | np.testing.assert_approx_equal(find_factorial(-1.0), gamma(-1.0 + 1))
23 | np.testing.assert_approx_equal(find_factorial(-2.0), gamma(-2.0 + 1))
24 | assert find_factorial(1.) == 1.
25 |
--------------------------------------------------------------------------------
/TidalPy/utilities/integration/numbalsoda_helper.py:
--------------------------------------------------------------------------------
1 | from typing import Tuple
2 |
3 | import numpy as np
4 |
5 | from numba import cfunc
6 | import numba as nb
7 |
8 | from . import lsoda_sig, lsoda
9 |
10 |
11 | def numbalsoda_solver(
12 | diffeq, time_span: Tuple[float, float], initial_condition: np.ndarray, args: Tuple = None,
13 | rtol: float = 1.0e-6, atol: float = 1.0e-8, max_step: float = np.inf,
14 | first_step: float = None, method: int = 1, t_eval: np.ndarray = None
15 | ):
16 |
17 | if t_eval is None:
18 | raise ValueError('t_eval required for NumbaLSOSA')
19 |
20 | shape = initial_condition.shape
21 |
22 | @cfunc(lsoda_sig)
23 | def new_diffeq(t, u, du, p):
24 | u_ = nb.carray(u, shape)
25 | out = diffeq(t, u_, *args)
26 | for i in range(u_.size):
27 | du[i] = out[i]
28 |
29 | new_diffeq_pointer = new_diffeq.address
30 |
31 | solution, success = lsoda(new_diffeq_pointer, initial_condition, t_eval, rtol=rtol, atol=atol)
32 |
33 | message = 'None'
34 |
35 | # Convert solution to transpose
36 | solution = solution.T
37 |
38 | return t_eval, solution, success, message
39 |
--------------------------------------------------------------------------------
/Papers/2025-JOSS/figures/trappist1e-bm.toml:
--------------------------------------------------------------------------------
1 | # Radius: Delrez et al., (2018) corrected by Kane et al., (2018)
2 | # Masses: Grimm et al., (2018)
3 | # Gravity: g*mass/(R2)
4 | # Flux: Delrez et al., (2018) corrected by Kane et al., (2018)
5 | # Density (Jontof-Hutter et al., 2014): radii: Delrez et al., (2018) + masses: Grimm e al (2018) corrected by Kane et al., (2018)
6 | # Updated using the analysis done by Agol+2020 and references therein.
7 |
8 | name = "TRAPPIST-1e-bm"
9 | type = "layered"
10 | radius = 5868000.0
11 | radius_error_pos = 82000.0
12 | radius_error_neg = 75000.0
13 | mass = 2.316e+24
14 | mass_error_pos = 1.3e+23
15 | mass_error_neg = 1.3e+23
16 | semi_major_axis = 4376000000.0
17 | semi_major_axis_error_pos = 37000000.0
18 | semi_major_axis_error_neg = 37000000.0
19 | semi_major_axis_in_au = false
20 | eccentricity = 0.00447
21 | eccentricity_error_pos = 0.00014
22 | eccentricity_error_neg = 0.00014
23 | force_spin_sync = true
24 |
25 | [tides]
26 | model = "global_approx"
27 | fixed_q = 100.0
28 |
29 | [layers.Core]
30 | type = "iron"
31 | is_tidal = false
32 | radius = 1760400.0
33 | density = 12000.0
34 |
35 | [layers.Mantle]
36 | type = "rock"
37 | is_tidal = true
38 | radius = 5868000.0
39 | density = 3300.0
40 |
--------------------------------------------------------------------------------
/TidalPy/structures/world_types/__init__.py:
--------------------------------------------------------------------------------
1 | from typing import Union
2 |
3 | from .basic import BaseWorld
4 | from .gas import GasGiantLayeredWorld, GasGiantWorld
5 | from .layered import LayeredWorld
6 | from .stellar import StarWorld
7 | from .tidal import TidalWorld
8 |
9 | AllWorldType = Union[BaseWorld, TidalWorld, GasGiantWorld, StarWorld, LayeredWorld, GasGiantLayeredWorld]
10 | GasStarWorldType = Union[GasGiantWorld, StarWorld]
11 | LayeredWorldType = Union[LayeredWorld, GasGiantLayeredWorld]
12 | TidalWorldType = Union[GasStarWorldType, TidalWorld, LayeredWorld]
13 |
14 | all_world_types = (BaseWorld, TidalWorld, GasGiantWorld, StarWorld, LayeredWorld, GasGiantLayeredWorld)
15 | all_tidal_world_types = (GasGiantWorld, StarWorld, TidalWorld, LayeredWorld, GasGiantLayeredWorld)
16 |
17 | world_types = {
18 | 'star' : StarWorld,
19 | 'gas' : GasGiantWorld,
20 | 'gas_giant' : GasGiantWorld,
21 | 'gas_layered' : GasGiantLayeredWorld,
22 | 'layered_gas_giant': GasGiantLayeredWorld,
23 | 'layered_ice_giant': GasGiantLayeredWorld,
24 | 'ice_giant' : GasGiantWorld,
25 | 'simple_tide' : TidalWorld,
26 | 'simple_tidal' : TidalWorld,
27 | 'layered' : LayeredWorld
28 | }
29 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | # MANIFEST.in
2 |
3 | # Exclude all c++ and c files; we will manually add back in some custom ones.
4 | # This avoids shipping already cythonized c files that need to be cythonized locally.
5 | exclude **/*.c
6 | exclude **/*.cpp
7 | exclude **/*.h
8 | exclude **/*.hpp
9 |
10 | # Include data files used for plotting and benchmarking
11 | include TidalPy/utilities/graphics/multilayer/*.csv
12 |
13 | # Include World Configuration Files
14 | include TidalPy/WorldPack/*.zip
15 |
16 | # Include Cython pyx and pxd files
17 | global-include *.pxd
18 | global-include *.pyx
19 | include cython_extensions.json
20 |
21 | # Include required hpp and cpp files
22 | include TidalPy/utilities/arrays/interp_.cpp
23 | include TidalPy/utilities/arrays/interp_.hpp
24 | include TidalPy/RadialSolver/love_.cpp
25 | include TidalPy/RadialSolver/love_.hpp
26 | include TidalPy/RadialSolver/rs_solution_.cpp
27 | include TidalPy/RadialSolver/rs_solution_.hpp
28 | include TidalPy/Material/eos/eos_solution_.cpp
29 | include TidalPy/Material/eos/eos_solution_.hpp
30 | include TidalPy/utilities/dimensions/nondimensional_.hpp
31 |
32 | # Exclude the whole Tests folder
33 | prune .vscode
34 | prune .idea
35 | prune .github
36 | prune Tests
37 | prune Papers
38 | prune Demos
39 | prune Documentation
40 | prune Benchmarks
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/starting/takeuchi.pxd:
--------------------------------------------------------------------------------
1 | cdef void cf_takeuchi_solid_dynamic_compressible(
2 | double frequency,
3 | double radius,
4 | double density,
5 | double complex bulk_modulus,
6 | double complex shear_modulus,
7 | int degree_l,
8 | double G_to_use,
9 | size_t num_ys,
10 | double complex* starting_conditions_ptr
11 | ) noexcept nogil
12 |
13 | cdef void cf_takeuchi_solid_static_compressible(
14 | double radius,
15 | double density,
16 | double complex bulk_modulus,
17 | double complex shear_modulus,
18 | int degree_l,
19 | double G_to_use,
20 | size_t num_ys,
21 | double complex* starting_conditions_ptr
22 | ) noexcept nogil
23 |
24 | ########################################################################################################################
25 | #### Liquid Layers
26 | ########################################################################################################################
27 |
28 | cdef void cf_takeuchi_liquid_dynamic_compressible(
29 | double frequency,
30 | double radius,
31 | double density,
32 | double complex bulk_modulus,
33 | int degree_l,
34 | double G_to_use,
35 | size_t num_ys,
36 | double complex* starting_conditions_ptr
37 | ) noexcept nogil
--------------------------------------------------------------------------------
/TidalPy/structures/world_types/gas.py:
--------------------------------------------------------------------------------
1 | from TidalPy.exceptions import NotYetImplementedError
2 |
3 | from .layered import LayeredWorld
4 | from .tidal import TidalWorld
5 |
6 |
7 | class GasGiantWorld(TidalWorld):
8 | """ GasGiantWorld
9 | Worlds that are simple gas giants and dissipate tidal energy through the CPL/CTL method (or not at all).
10 |
11 |
12 | See Also
13 | --------
14 | Parent Class:
15 | TidalPy.structures.world_types.TidalWorld
16 | """
17 |
18 | world_class = 'gas_giant'
19 |
20 |
21 | class GasGiantLayeredWorld(LayeredWorld):
22 | """ GasGiantLayeredWorld
23 | Worlds that are gas or ice giants and dissipate tidal energy through either the CPL/CTL method or a more complex
24 | rheology.
25 |
26 | These world types are not implemented as of at lease v0.2.1
27 |
28 |
29 | See Also
30 | --------
31 | Parent Class:
32 | TidalPy.structures.world_types.LayeredWorld
33 | """
34 |
35 | world_class = 'gas_giant_layered'
36 |
37 | def __init__(self, world_config: dict, name: str = None, initialize: bool = True):
38 | raise NotYetImplementedError(
39 | 'Layered Gas Giant world_types are not yet implemented. You could try to hack a regular LayeredWorld instead.'
40 | )
41 |
--------------------------------------------------------------------------------
/TidalPy/tides/potential/__init__.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, Tuple, TYPE_CHECKING
2 |
3 |
4 | from .synchronous_low_e import tidal_potential as tidal_potential_simple
5 | from .nsr_modes_med_eccen_no_obliquity import tidal_potential as tidal_potential_nsr_modes
6 | from .nsr_med_eccen_no_obliquity import tidal_potential as tidal_potential_nsr
7 | from .nsr_med_eccen_med_obliquity import tidal_potential as tidal_potential_obliquity_nsr
8 | from .nsr_med_eccen_gen_obliquity import tidal_potential as tidal_potential_gen_obliquity_nsr
9 | from .nsr_modes_med_eccen_med_obliquity import tidal_potential as tidal_potential_obliquity_nsr_modes
10 | from .nsr_modes_med_eccen_gen_obliquity import tidal_potential as tidal_potential_gen_obliquity_nsr_modes
11 | from .nsr_modes_low_eccen_gen_obliquity import tidal_potential as tidal_potential_gen_obliquity_low_e_nsr_modes
12 |
13 | if TYPE_CHECKING:
14 | from TidalPy.utilities.types import FloatArray
15 |
16 | TidalPotentialOutput = Tuple['FloatArray', 'FloatArray', 'FloatArray', 'FloatArray', 'FloatArray', 'FloatArray']
17 | PotentialTupleModeOutput = Dict[str, Tuple['FloatArray', 'FloatArray', 'FloatArray', 'FloatArray', 'FloatArray', 'FloatArray']]
18 | TidalPotentialModeOutput = Tuple[Dict[str, 'FloatArray'], Dict[str, 'FloatArray'], PotentialTupleModeOutput]
19 |
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetB_Package/test_i_spherical_mass.py:
--------------------------------------------------------------------------------
1 | """ Tests for spherical helper function to calculate the volume of spherical voxels. """
2 |
3 | import numpy as np
4 |
5 |
6 |
7 | from TidalPy.constants import G
8 | from TidalPy.utilities.spherical_helper.mass import calculate_mass_gravity_arrays
9 |
10 | radius = np.linspace(0.01e3, 6378.1e3, 50)
11 | layer_0 = radius < 3483.e3
12 | layer_1 = radius >= 3483.e3
13 | l1_n = len(radius[layer_1])
14 | density = np.zeros_like(radius)
15 | density[layer_0] = 10000.
16 | density[layer_1] = 4500.
17 |
18 |
19 | def test_calculate_mass_gravity_arrays():
20 | """ Test the calculation of volume, mass, and gravity from radius and density arrays. """
21 |
22 | volumes, masses, gravities = calculate_mass_gravity_arrays(radius, density)
23 |
24 | # Check array sizes
25 | assert len(volumes) == len(radius)
26 | assert len(masses) == len(radius)
27 | assert len(gravities) == len(radius)
28 |
29 | # Check values
30 | real_volume = (4. / 3.) * np.pi * radius[-1]**3
31 | np.testing.assert_almost_equal(np.abs(np.sum(volumes) - real_volume)/real_volume, 0.)
32 | mass = np.sum(masses)
33 | real_gravity_surf = G * mass / radius[-1]**2
34 | np.testing.assert_almost_equal(np.abs(gravities[-1] - real_gravity_surf)/real_gravity_surf, 0.)
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/shooting.pxd:
--------------------------------------------------------------------------------
1 | from libcpp cimport bool as cpp_bool
2 | from libcpp.memory cimport shared_ptr
3 | from libcpp.vector cimport vector
4 |
5 | from CyRK cimport ODEMethod
6 |
7 | from TidalPy.RadialSolver.rs_solution cimport RadialSolutionStorageCC
8 |
9 |
10 | cdef size_t cf_find_num_shooting_solutions(
11 | int layer_type,
12 | bint is_static,
13 | bint is_incompressible
14 | ) noexcept nogil
15 |
16 |
17 | cdef int cf_shooting_solver(
18 | RadialSolutionStorageCC* solution_storage_ptr,
19 | double frequency,
20 | double planet_bulk_density,
21 | int* layer_types_ptr,
22 | bint* is_static_by_layer_ptr,
23 | bint* is_incompressible_by_layer_ptr,
24 | vector[size_t] first_slice_index_by_layer_vec,
25 | vector[size_t] num_slices_by_layer_vec,
26 | size_t num_bc_models,
27 | int* bc_models_ptr,
28 | double G_to_use,
29 | int degree_l,
30 | cpp_bool use_kamata,
31 | double starting_radius,
32 | double start_radius_tolerance,
33 | ODEMethod integration_method,
34 | double integration_rtol,
35 | double integration_atol,
36 | cpp_bool scale_rtols_by_layer_type,
37 | size_t max_num_steps,
38 | size_t expected_size,
39 | size_t max_ram_MB,
40 | double max_step,
41 | cpp_bool verbose
42 | ) noexcept nogil
43 |
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/material/custom/pyrite.py:
--------------------------------------------------------------------------------
1 | from TidalPy.Extending.burnman import burnman_installed, Mineral
2 |
3 |
4 | class Pyrite(Mineral):
5 |
6 | def __init__(self):
7 |
8 | if not burnman_installed:
9 | raise ImportError('Burnman package not found.')
10 |
11 | """ Parameters from Thompson et al, 2016 in American Mineralogist Vol 101, Page 1046"""
12 | self.params = {
13 | 'formula' : {'Fe': 1., 'Si': 2.},
14 | 'equation_of_state': 'bm3',
15 | 'K_0' : 140.2e9,
16 | 'Kprime_0' : 5.52,
17 | 'grueneisen_0' : 1.4,
18 | 'Debye_0' : 624.,
19 | 'V_0' : 2.393e-5,
20 | 'q_0' : 2.06,
21 | 'molar_mass' : 119.9750 / 1000.,
22 | 'n' : 3,
23 | # Shear information is from Whitaker & Wang 2010 Journal of Earth Science Vol 21 No 5 p. 792
24 | 'G_0' : 112.3e9, # From Whitaker & Wang 2010 Journal of Earth Science Vol 21 No 5 p. 792
25 | 'Gprime_0' : 3.0,
26 | # Merkel et al (2002) in Physics and Chemistry of Minerals Vol 29 page 1) had slightly higher value (126e9)
27 | }
28 |
29 | Mineral.__init__(self)
30 |
--------------------------------------------------------------------------------
/TidalPy/rheology/models.pxd:
--------------------------------------------------------------------------------
1 | from TidalPy.rheology.base cimport RheologyModelBase
2 |
3 | ########################################################################################################################
4 | ######################################## New Rheological Models Go Below Here! #########################################
5 | ########################################################################################################################
6 |
7 | cdef class Elastic(RheologyModelBase):
8 | pass
9 |
10 | cdef class Newton(RheologyModelBase):
11 | pass
12 |
13 | cdef class Maxwell(RheologyModelBase):
14 | pass
15 |
16 | cdef class Voigt(RheologyModelBase):
17 | cdef double voigt_modulus_scale
18 | cdef double voigt_viscosity_scale
19 |
20 | cdef class Burgers(RheologyModelBase):
21 | cdef double voigt_modulus_scale
22 | cdef double voigt_viscosity_scale
23 |
24 | cdef class Andrade(RheologyModelBase):
25 | cdef double alpha
26 | cdef double alpha_factorial
27 | cdef double zeta
28 | cdef double complex sine_term
29 |
30 | cdef class SundbergCooper(RheologyModelBase):
31 | cdef double voigt_modulus_scale
32 | cdef double voigt_viscosity_scale
33 | cdef double alpha
34 | cdef double alpha_factorial
35 | cdef double zeta
36 | cdef double complex sine_term
37 |
--------------------------------------------------------------------------------
/Documentation/_static/custom.css:
--------------------------------------------------------------------------------
1 | /* Change background behind logo/search area */
2 | .wy-side-nav-search {
3 | background-color: #1f2a44;
4 | /* Other good ones: #655A7C; #1f2a44 */
5 | }
6 |
7 | .version-switch select {
8 | color: white !important;
9 | }
10 |
11 | .wy-menu .caption-text {
12 | color: #8ee2f2;
13 | }
14 |
15 | .document .caption-text {
16 | color: #1f2a44;
17 | }
18 |
19 | /* Fix spacing in directory listing on main page body. */
20 | /* Remove space after headers */
21 | .rst-content h1,
22 | .rst-content h2,
23 | .rst-content h3,
24 | .rst-content h4,
25 | .rst-content h5,
26 | .rst-content h6 {
27 | margin-bottom: 0 !important;
28 | margin-bottom: 10px !important;
29 | }
30 |
31 | .rst-content .toctree-wrapper > p.caption {
32 | margin-top: 0 !important;
33 | margin-bottom: 0 !important;
34 | }
35 |
36 | /* Remove space before/after ul lists */
37 | .rst-content ul {
38 | margin-top: 0 !important;
39 | margin-bottom: 0 !important;
40 | }
41 |
42 | /* If you also want to adjust ol lists */
43 | .rst-content ol {
44 | margin-top: 0 !important;
45 | margin-bottom: 0 !important;
46 | }
47 |
48 | /* Adjust list item spacing if needed */
49 | .rst-content ul li,
50 | .rst-content ol li {
51 | margin-bottom: 0 !important;
52 | }
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/love.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
3 |
4 | def find_love(
5 | double complex[::1] complex_love_numbers_view,
6 | double complex[::1] surface_solutions_view,
7 | double surface_gravity
8 | ):
9 | """
10 | Find the complex Love and Shida numbers given the surface radial solutions for a planet.
11 |
12 | Parameters
13 | ----------
14 | complex_love_numbers_view : double complex[::1], array, output
15 | Array to store complex Love numbers. There must be space for 3 double complex numbers.
16 | surface_solutions_view : double complex[::1], array, input
17 | Array of radial solutions (y_i) values at the surface of a planet.
18 | surface_gravity : double, input
19 | Acceleration due to gravity at the planet's surface [m s-2].
20 | """
21 |
22 | # Create pointers; the c++ functions only work with doubles so we need to cast them to double
23 | cdef double* complex_love_numbers_ptr = &complex_love_numbers_view[0]
24 | cdef double* surface_solutions_ptr = &surface_solutions_view[0]
25 |
26 | return find_love_cf(
27 | complex_love_numbers_ptr,
28 | surface_solutions_ptr,
29 | surface_gravity
30 | )
31 |
--------------------------------------------------------------------------------
/TidalPy/utilities/io/pathing.py:
--------------------------------------------------------------------------------
1 | import os
2 | from typing import Dict, List, Union
3 |
4 |
5 | def get_all_files_of_type(directory_to_search: str, file_extensions: Union[List[str], str]) -> Dict[str, str]:
6 | """ Returns all files with a specified extension(s) in a given directory
7 |
8 | Parameters
9 | ----------
10 | directory_to_search : str
11 | The directory to search for files in.
12 | file_extensions : Union[List[str], str]
13 | Extension, or list of extensions, to search for.
14 |
15 | Returns
16 | -------
17 | files : Dict[str, str]
18 | Dictionary of files stored as file_name: file_path
19 | """
20 |
21 | if type(file_extensions) is str:
22 | file_extensions = list(file_extensions)
23 | # splitext retains the first period, the user may not have expected that
24 | for e_i, extension in enumerate(file_extensions):
25 | if extension[0] != '.':
26 | file_extensions[e_i] = f'.{extension}'
27 |
28 | files = dict()
29 | # Only pull out files, not sub-directories
30 | only_files = [f for f in os.listdir(directory_to_search)
31 | if os.path.isfile(os.path.join(directory_to_search, f))]
32 |
33 | for file_with_extension in only_files:
34 | filename, extension = os.path.splitext(file_with_extension)
35 | if extension in file_extensions:
36 | files[filename] = os.path.join(directory_to_search, file_with_extension)
37 |
38 | return files
39 |
--------------------------------------------------------------------------------
/Tests/Test_Old/Test_SetB_Package/test_b_utilities_numpy.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 |
3 | from TidalPy.utilities.numpy_helper.array_other import neg_array_for_log_plot, normalize_dict
4 |
5 |
6 | def test_normalize_dict():
7 | """ Tests the normalize_dict function """
8 |
9 | # Test with floats
10 | test_dict = {
11 | 'a': 102.0,
12 | 'b': 121.2,
13 | 'c': -12.0
14 | }
15 |
16 | result = normalize_dict(test_dict, pass_negatives=False, new_max=1.0, new_min=0.0)
17 |
18 | assert type(result) == dict
19 | assert type(result['a']) in [float, np.float64]
20 | assert type(result['b']) in [float, np.float64]
21 | assert type(result['c']) in [float, np.float64]
22 |
23 | np.testing.assert_allclose(result['b'], 1.0)
24 | np.testing.assert_allclose(result['c'] + 1.0, 1.0)
25 | assert result['b'] > result['a'] > result['c']
26 |
27 | result = normalize_dict(test_dict, pass_negatives=False, new_max=3.2, new_min=-10.0)
28 |
29 | np.testing.assert_allclose(result['b'], 3.2)
30 | np.testing.assert_allclose(result['c'], -10.0)
31 | assert result['b'] > result['a'] > result['c']
32 |
33 |
34 | def test_neg_array_for_plot():
35 | """ Test function neg_array_for_log_plot """
36 |
37 | x = np.linspace(-10, 10, 10)
38 | y_p, y_n = neg_array_for_log_plot(x)
39 |
40 | assert np.all(y_p[~np.isnan(y_p)] >= 0.0)
41 | assert np.all(y_n[~np.isnan(y_n)] >= 0.0)
42 | assert np.all(np.isnan(y_p[x < 0.0]))
43 | assert np.all(np.isnan(y_n[x >= 0.0]))
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/solver.pxd:
--------------------------------------------------------------------------------
1 |
2 | from libcpp cimport bool as cpp_bool
3 |
4 | from CyRK cimport ODEMethod
5 |
6 | from TidalPy.RadialSolver.rs_solution cimport RadialSolutionStorageCC
7 |
8 |
9 | cdef int cf_radial_solver(
10 | RadialSolutionStorageCC* solution_storage_ptr,
11 | size_t total_slices,
12 | double* radius_array_in_ptr,
13 | double* density_array_in_ptr,
14 | double complex* complex_bulk_modulus_in_ptr,
15 | double complex* complex_shear_modulus_in_ptr,
16 | double frequency,
17 | double planet_bulk_density,
18 | size_t num_layers,
19 | int* layer_types_ptr,
20 | bint* is_static_bylayer_ptr,
21 | bint* is_incompressible_bylayer_ptr,
22 | double surface_pressure,
23 | int degree_l,
24 | size_t num_bc_models,
25 | int* bc_models_ptr,
26 | int core_model,
27 | cpp_bool use_kamata,
28 | double starting_radius,
29 | double start_radius_tolerance,
30 | ODEMethod integration_method_int,
31 | double integration_rtol,
32 | double integration_atol,
33 | cpp_bool scale_rtols_bylayer_type,
34 | size_t max_num_steps,
35 | size_t expected_size,
36 | size_t max_ram_MB,
37 | double max_step,
38 | cpp_bool nondimensionalize,
39 | cpp_bool use_prop_matrix,
40 | int* eos_integration_method_int_bylayer_ptr,
41 | ODEMethod eos_integration_method,
42 | double eos_rtol,
43 | double eos_atol,
44 | double eos_pressure_tol,
45 | int eos_max_iters,
46 | cpp_bool verbose,
47 | cpp_bool warnings
48 | ) noexcept nogil
49 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/love_.cpp:
--------------------------------------------------------------------------------
1 | #include "love_.hpp"
2 |
3 | void find_love_cf(
4 | double* complex_love_numbers_ptr, // These are double pointers that pointer to a double complex array.
5 | double* surface_solutions_ptr, // Same as above
6 | double surface_gravity)
7 | {
8 | const double y1_real = surface_solutions_ptr[0];
9 | const double y1_imag = surface_solutions_ptr[1];
10 | const double y3_real = surface_solutions_ptr[4];
11 | const double y3_imag = surface_solutions_ptr[5];
12 | const double y5_real = surface_solutions_ptr[8];
13 | const double y5_imag = surface_solutions_ptr[9];
14 |
15 | // Calculate Love and Shida numbers
16 | // Note Im(k2) = -Im(y5) (Henning & Hurford 2014 eq. A9), opposite convention of Tobie et al. (2005, eqs. 9 & 36)
17 | // And k2 = |-y5-1| (Roberts & Nimmo 2008 equation A8), not 1-y5 as in Henning & Hurford (2014) equation A9.
18 |
19 | // Okay, some clarification on this. It looks like VS04 that HH14 is based on used a different convention for y5,
20 | // Tobie05's y5 = -y5 of SV; we follow that format here.
21 |
22 | // Love k
23 | complex_love_numbers_ptr[0] = y5_real - 1.0;
24 | complex_love_numbers_ptr[1] = y5_imag;
25 |
26 | // Love h
27 | complex_love_numbers_ptr[2] = y1_real * surface_gravity;
28 | complex_love_numbers_ptr[3] = y1_imag * surface_gravity;
29 |
30 | // Shida l
31 | complex_love_numbers_ptr[4] = y3_real * surface_gravity;
32 | complex_love_numbers_ptr[5] = y3_imag * surface_gravity;
33 | }
34 |
--------------------------------------------------------------------------------
/TidalPy/utilities/math/complex.pxd:
--------------------------------------------------------------------------------
1 | from TidalPy.constants cimport d_DBL_MAX, d_DBL_MIN, d_DBL_MANT_DIG, d_NAN_DBL, d_INF_DBL
2 |
3 | cdef double complex cmplx_NAN
4 | cdef double complex cmplx_zero
5 | cdef double complex cmplx_one
6 | cdef double SQRT2
7 | cdef double LOGE2
8 | cdef double SQRT2_INV
9 | cdef double THRESH
10 | cdef double DBL_MAX_4
11 | cdef int SCALED_CEXP_K_F
12 | cdef int SCALED_CEXP_K_D
13 | cdef int SCALED_CEXP_K_LD
14 | cdef double SCALED_K_LOGE2_D
15 | cdef float SCALED_CEXP_LOWERF
16 | cdef float SCALED_CEXP_UPPERF
17 | cdef double SCALED_CEXP_LOWER
18 | cdef double SCALED_CEXP_UPPER
19 | cdef long double SCALED_CEXP_LOWERL
20 | cdef long double SCALED_CEXP_UPPERL
21 |
22 |
23 | cdef double complex cf_build_dblcmplx(double a, double b) noexcept nogil
24 |
25 | cdef double cf_cabs(double complex z) noexcept nogil
26 |
27 | cdef double cf_cabs2(double complex z) noexcept nogil
28 |
29 | cdef double complex cf_cinv(double complex z) noexcept nogil
30 |
31 | cdef double cf_hypot(const double x, const double y) noexcept nogil
32 |
33 | cdef double complex cf_csqrt(const double complex z) noexcept nogil
34 |
35 | cdef double complex cf_scaled_cexp(const double x, const double y, const int expt) noexcept nogil
36 |
37 | cdef double complex cf_cexp(const double complex z) noexcept nogil
38 |
39 | cdef double complex cf_clog(const double complex z) noexcept nogil
40 |
41 | cdef double complex cf_cpow(const double complex a, const double complex b) noexcept nogil
42 |
43 | cdef double complex cf_cipow(const double complex a, const int b) noexcept nogil
44 |
--------------------------------------------------------------------------------
/TidalPy/utilities/integration/cyrk_helper.py:
--------------------------------------------------------------------------------
1 | """ Helper functions to interface with CyRK's integration suite """
2 |
3 | from typing import Tuple
4 |
5 | import numpy as np
6 |
7 | from TidalPy.utilities.performance import njit
8 |
9 | from . import _cyrk_ode, _nbrk_ode, _nb2cy
10 |
11 |
12 | def cyrk_solver(
13 | diffeq, time_span: Tuple[float, float], initial_condition: np.ndarray, args: Tuple = tuple(),
14 | rtol: float = 1.0e-6, atol: float = 1.0e-8, max_step: float = np.inf,
15 | first_step: float = 0., method: int = 1, t_eval: np.ndarray = np.empty((0,), dtype=np.float64),
16 | convert_func_to_cy: bool = False
17 | ):
18 |
19 | # Change the diffeq to match the desired format
20 | if convert_func_to_cy:
21 | diffeq = _nb2cy(diffeq, use_njit=True, cache_njit=True)
22 |
23 | return _cyrk_ode(
24 | diffeq, time_span, initial_condition, args=args,
25 | rtol=rtol, atol=atol, max_step=max_step, first_step=first_step,
26 | rk_method=method, t_eval=t_eval
27 | )
28 |
29 |
30 | @njit(cacheable=True)
31 | def nbrk_solver(
32 | diffeq, time_span: Tuple[float, float], initial_condition: np.ndarray, args: Tuple = None,
33 | rtol: float = 1.0e-6, atol: float = 1.0e-8, max_step: float = np.inf,
34 | first_step: float = None, method: int = 1, t_eval: np.ndarray = np.empty((0,), dtype=np.float64)
35 | ):
36 |
37 | return _nbrk_ode(
38 | diffeq, time_span, initial_condition, args,
39 | rtol=rtol, atol=atol, max_step=max_step, first_step=first_step,
40 | rk_method=method, t_eval=t_eval
41 | )
42 |
--------------------------------------------------------------------------------
/.github/workflows/make_joss_pdf.yml:
--------------------------------------------------------------------------------
1 | name: Draft PDF
2 |
3 | on:
4 | pull_request:
5 | types: [opened, synchronize, reopened]
6 | workflow_dispatch:
7 | push:
8 | paths:
9 | - Papers/2025-JOSS/**
10 | - .github/workflows/make_joss_pdf.yml
11 |
12 |
13 | jobs:
14 | paper:
15 | runs-on: ubuntu-latest
16 | name: Paper Draft
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 | with:
21 | ref: ${{ github.head_ref }} # ensures a proper branch instead of detached HEAD
22 |
23 | - name: Build draft PDF
24 | uses: openjournals/openjournals-draft-action@master
25 | with:
26 | journal: joss
27 | # This should be the path to the paper within your repo.
28 | paper-path: 'Papers/2025-JOSS/paper.md'
29 |
30 | - name: Upload
31 | uses: actions/upload-artifact@v4
32 | with:
33 | name: paper
34 | # This is the output path where Pandoc will write the compiled
35 | # PDF. Note, this should be the same directory as the input
36 | # paper.md
37 | path: 'Papers/2025-JOSS/paper.pdf'
38 |
39 | - name: Commit PDF to repository
40 | uses: EndBug/add-and-commit@v9
41 | with:
42 | message: '(auto) Paper PDF Draft'
43 | # This should be the path to the paper within your repo.
44 | add: 'Papers/2025-JOSS/*.pdf' # 'paper/*.pdf' to commit all PDFs in the paper directory
45 | push: true
--------------------------------------------------------------------------------
/Documentation/index.md:
--------------------------------------------------------------------------------
1 | # TidalPy Documentation
2 |
3 | ```{include} Overview/Readme.md
4 | :start-after: TidalPy
5 | :end-before: Overview
6 | ```
7 |
8 | Please click on a page below to learn more about the package.
9 |
10 | Also check out the GitHub page to see the code.
11 | [GitHub](https://github.com/jrenaud90/TidalPy)
12 |
13 | ```{toctree}
14 | :maxdepth: 2
15 | :caption: TidalPy
16 |
17 | Overview
18 | ```
19 |
20 | ```{toctree}
21 | :maxdepth: 2
22 | :caption: Modules
23 |
24 | Rheology
25 | RadialSolver (Love Number Calculator)
26 | Exoplanets
27 | Dynamics
28 | ```
29 |
30 | ```{toctree}
31 | :maxdepth: 2
32 | :caption: Demos
33 |
34 | Demos/1 - Build Planets
35 | Demos/2 - Thermal Exploration
36 | Demos/3 - Calculating Love Numbers
37 | Demos/4 - Eccentricity Truncations
38 | Demos/5 - Rheology Exploration
39 | Demos/6 - Multilayer Heating
40 | Demos/7 - Comparison of Tidal Modes
41 | Demos/8 - Love Number Sensitivity
42 | ```
43 |
44 | ```{toctree}
45 | :maxdepth: 2
46 | :caption: Auto Generated API
47 |
48 | TidalPy API
49 | ```
50 |
51 | ```{toctree}
52 | :maxdepth: 2
53 | :caption: Additional Info
54 | :hidden:
55 |
56 | Change Log
57 | ```
--------------------------------------------------------------------------------
/TidalPy/tides/ctl_funcs/ctl_funcs.py:
--------------------------------------------------------------------------------
1 | from typing import TYPE_CHECKING
2 |
3 | from ...utilities.performance import njit
4 |
5 | if TYPE_CHECKING:
6 | from ...utilities.types import FloatArray
7 |
8 |
9 | @njit(cacheable=True)
10 | def linear_dt(frequency: 'FloatArray', fixed_dt: float):
11 | """ Estimates dissipative term of the Love number assuming a function that is inversely linear with frequency.
12 |
13 | Parameters
14 | ----------
15 | frequency : FloatArray
16 | Frequency (the absolute value of the tidal modes)
17 | fixed_dt : float
18 | Inverse proportionality coefficient [s]
19 |
20 | Returns
21 | -------
22 | effective_q : FloatArray
23 | The effective Q for the world
24 | """
25 |
26 | effective_q = frequency * fixed_dt
27 |
28 | return effective_q
29 |
30 |
31 | @njit(cacheable=True)
32 | def linear_dt_with_q(frequency: 'FloatArray', fixed_dt: float, fixed_q: float):
33 | """ Estimates dissipative term of the Love number assuming a function that is linear with frequency. The fixed Q
34 | acts as an additional inverse proportionality constant.
35 |
36 | Parameters
37 | ----------
38 | frequency : FloatArray
39 | Frequency (the absolute value of the tidal modes)
40 | fixed_dt : float
41 | Inverse proportionality coefficient [s]
42 | fixed_q : float
43 | Additional inverse proportionality coefficient
44 |
45 | Returns
46 | -------
47 | effective_q : FloatArray
48 | The effective Q for the world
49 | """
50 |
51 | effective_q = frequency * fixed_dt / fixed_q
52 |
53 | return effective_q
54 |
--------------------------------------------------------------------------------
/TidalPy/constants.pxd:
--------------------------------------------------------------------------------
1 | # Extremes
2 | # Forcing Frequency Extremes
3 | cdef double d_MIN_FREQUENCY
4 | cdef double d_MAX_FREQUENCY
5 |
6 | # Minimum difference between spin and orbital frequency before it is treated as zero.
7 | cdef double d_MIN_SPIN_ORBITAL_DIFF
8 |
9 | # Shear/Bulk Modulus Extremes
10 | cdef double d_MIN_VISCOSITY
11 | cdef double d_MIN_MODULUS
12 |
13 | # Thickness
14 | cdef double d_MIN_THICKNESS
15 |
16 | # Mathematics
17 | cdef double d_ppm
18 | cdef double d_ppb
19 |
20 | cdef double d_PI_DBL
21 | cdef double d_DBL_MAX
22 | cdef double d_DBL_MIN
23 | cdef double d_DBL_MANT_DIG
24 | cdef double d_INF_DBL
25 | cdef double d_EPS_DBL_10
26 | cdef double d_EPS_DBL_100
27 | cdef double d_EPS_DBL
28 | cdef double d_NAN_DBL
29 |
30 | # Sun
31 | cdef double d_mass_solar
32 | cdef double d_radius_solar
33 | cdef double d_luminosity_solar
34 |
35 | # TRAPPIST-1
36 | cdef double d_mass_trap1
37 | cdef double d_radius_trap1
38 | cdef double d_luminosity_trap1
39 |
40 | # Earth
41 | cdef double d_mass_earth
42 | cdef double d_radius_earth
43 |
44 | # Jupiter
45 | cdef double d_mass_jupiter
46 | cdef double d_radius_jupiter
47 |
48 | # Pluto
49 | cdef double d_mass_pluto
50 | cdef double d_radius_pluto
51 |
52 | # Io
53 | cdef double d_mass_io
54 | cdef double d_radius_io
55 |
56 | # Alias Names
57 | cdef double d_G
58 | cdef double d_R
59 | cdef double d_Au
60 | cdef double d_sbc
61 | cdef double d_SBC
62 | cdef double d_newtons_constant
63 |
64 | cdef double d_M_sol
65 | cdef double d_M_earth
66 | cdef double d_M_jup
67 | cdef double d_M_pluto
68 |
69 | cdef double d_R_sol
70 | cdef double d_R_earth
71 | cdef double d_R_jup
72 | cdef double d_R_pluto
73 |
74 | cdef double d_L_sol
75 |
--------------------------------------------------------------------------------
/TidalPy/structures/layers/gas.py:
--------------------------------------------------------------------------------
1 | from typing import TYPE_CHECKING
2 |
3 | from .basic import LayerBase
4 |
5 | if TYPE_CHECKING:
6 | from ..world_types import GasGiantLayeredWorld
7 |
8 |
9 | class GasLayer(LayerBase):
10 | """" GasLayer
11 | Layer object used to construct gas giant or ice giant planets that contain a significant gas layer. Currently,
12 | these layers do not do anything over the base layer class but allow for future functionality.
13 |
14 | Notes:
15 | .. Does not provide any functionality to perform tidal calculations (see PhysicsLayer instead)
16 |
17 | See Also
18 | --------
19 | TidalPy.structures.layers.LayerBase
20 | """
21 |
22 | layer_class = 'gas'
23 |
24 | def __init__(
25 | self, layer_name: str, layer_index: int, world: 'GasGiantLayeredWorld', layer_config: dict,
26 | is_top_layer: bool, initialize: bool = True
27 | ):
28 | """ Gas layer constructor
29 |
30 | Parameters
31 | ----------
32 | layer_name : str
33 | User-friendly name of layer.
34 | layer_index : int
35 | Location of layer within a world (0 indicates center-most).
36 | world : LayeredWorldType
37 | World instance where layer was initialized in.
38 | layer_config : dict
39 | Layer's user-provided configurations.
40 | is_top_layer : bool
41 | If `True`, this layer is the top-most layer.
42 | initialize : bool = True
43 | If `True`, then the Layer's reinit is called at the end of the constructor.
44 | """
45 |
46 | super().__init__(layer_name, layer_index, world, layer_config, is_top_layer, initialize)
47 |
--------------------------------------------------------------------------------
/TidalPy/__init__.py:
--------------------------------------------------------------------------------
1 | # Find Version Number
2 | import importlib.metadata
3 | __version__ = importlib.metadata.version("TidalPy")
4 | version = __version__
5 |
6 | # Set test_mode to False (used to turn off logging during testing)
7 | _test_mode = False
8 |
9 | import os
10 | if 'TIDALPY_TEST_MODE' in os.environ:
11 | if os.environ['TIDALPY_TEST_MODE']:
12 | _test_mode = True
13 |
14 | import time
15 |
16 | # Initial Runtime
17 | init_time = time.time()
18 |
19 | # Various properties to be set by the configuration file and initializer (these should not be changed by user)
20 | _tidalpy_init = False
21 | _in_jupyter = False
22 | _output_dir = None
23 | _config_path = None
24 |
25 | # TidalPy configurations
26 | config = None
27 |
28 | # World configuration directory
29 | world_config_dir = None
30 |
31 | # Public properties that can be changed by user
32 | extensive_logging = False
33 | extensive_checks = False
34 |
35 | # Load the TidalPy initializer and run it (user can run it later so load it with the handle `reinitialize`)
36 | from TidalPy.initialize import initialize as reinit
37 |
38 | # Call reinit for the first initialization
39 | reinit()
40 |
41 | # Import module functions
42 | from .cache import clear_cache as clear_cache
43 | from .cache import clear_data as clear_data
44 |
45 | def test_mode():
46 | """ Turn on test mode and reinitialize TidalPy """
47 | global _test_mode
48 |
49 | if _test_mode:
50 | # Don't need to do anything.
51 | pass
52 | else:
53 | _test_mode = True
54 | reinit()
55 |
56 | def log_to_file():
57 | """ Quick switch to turn on saving logs to file """
58 | if not config['logging']['write_log_to_disk']:
59 | config['logging']['write_log_to_disk'] = True
60 | reinit()
61 |
--------------------------------------------------------------------------------
/TidalPy/tides/dissipation.py:
--------------------------------------------------------------------------------
1 | from typing import TYPE_CHECKING
2 |
3 |
4 | from TidalPy.constants import G
5 | from TidalPy.utilities.performance import njit
6 |
7 | if TYPE_CHECKING:
8 | from TidalPy.utilities.types import FloatArray
9 |
10 |
11 | @njit(cacheable=True)
12 | def calc_tidal_susceptibility(host_mass: float, target_radius: float, semi_major_axis: 'FloatArray') -> 'FloatArray':
13 | """ Calculate the tidal susceptibility for a given target radius, host mass, and their separation.
14 |
15 | Parameters
16 | ----------
17 | host_mass : float
18 | Mass of central host [kg]
19 | target_radius : float
20 | Radius of target body [m]
21 | semi_major_axis : FloatArray
22 | Semi-major axis [m]
23 |
24 | Returns
25 | -------
26 | tidal_susceptibility : FloatArray
27 | Tidal Susceptibility [N m]
28 | """
29 |
30 | tidal_susceptibility = (3. / 2.) * G * host_mass**2 * target_radius**5 / semi_major_axis**6
31 |
32 | return tidal_susceptibility
33 |
34 |
35 | @njit(cacheable=True)
36 | def calc_tidal_susceptibility_reduced(host_mass: float, target_radius: float) -> float:
37 | """ Calculate the tidal susceptibility (reduced) for a given target radius and host mass.
38 |
39 | The reduced tidal susceptibility excludes the semi-major axis.
40 |
41 | Parameters
42 | ----------
43 | host_mass : float
44 | Mass of central host [kg]
45 | target_radius : float
46 | Radius of target body [m]
47 |
48 | Returns
49 | -------
50 | tidal_susceptibility_reduced : np.ndarray
51 | Tidal Susceptibility [N m]
52 | """
53 |
54 | tidal_susceptibility_reduced = (3. / 2.) * G * host_mass**2 * target_radius**5
55 |
56 | return tidal_susceptibility_reduced
57 |
--------------------------------------------------------------------------------
/TidalPy/tides/inclination_funcs/orderl2.py:
--------------------------------------------------------------------------------
1 | """ Inclination functions (squared) for tidal order-l = 2. These are exact (no truncation on I)
2 | """
3 |
4 | from typing import TYPE_CHECKING
5 |
6 | import numpy as np
7 |
8 | from ...utilities.performance.numba import njit
9 |
10 | if TYPE_CHECKING:
11 | from . import InclinOutput
12 | from ...utilities.types import FloatArray
13 |
14 |
15 | @njit(cacheable=True)
16 | def calc_inclination_off(inclination: 'FloatArray') -> 'InclinOutput':
17 | """Calculate F^2_lmp (assuming I=0) for l = 2"""
18 |
19 | # Inclination Functions Calculated for l = 2, Inclination == off.
20 | ones_ = np.ones_like(inclination)
21 |
22 | inclination_results = {
23 | (0, 1): 0.25 * ones_,
24 | (2, 0): 9. * ones_,
25 | }
26 |
27 | return inclination_results
28 |
29 |
30 | @njit(cacheable=True)
31 | def calc_inclination(inclination: 'FloatArray') -> 'InclinOutput':
32 | """Calculate F^2_lmp for l = 2"""
33 |
34 | # Inclination Functions Calculated for l = 2.
35 | # Optimizations
36 | i = inclination
37 | i_half = i / 2.
38 | i_double = 2. * i
39 | sin_i = np.sin(i)
40 | sin_i_half = np.sin(i_half)
41 | cos_i_half = np.cos(i_half)
42 | sin_i_double = np.sin(i_double)
43 |
44 | inclination_results = {
45 | (0, 0) : 0.140625*sin_i**4,
46 | (0, 1) : (-sin_i_half**4 + sin_i_half**2 + 0.5*sin_i**2 - 0.5)**2,
47 | (0, 2) : 0.140625*sin_i**4,
48 | (1, 0) : 9.0*sin_i_half**2*cos_i_half**6,
49 | (1, 1) : 0.5625*sin_i_double**2,
50 | (1, 2) : 9.0*sin_i_half**6*cos_i_half**2,
51 | (2, 0) : 9.0*cos_i_half**8,
52 | (2, 1) : 2.25*sin_i**4,
53 | (2, 2) : 9.0*sin_i_half**8
54 | }
55 |
56 | return inclination_results
57 |
--------------------------------------------------------------------------------
/TidalPy/utilities/performance/memory.py:
--------------------------------------------------------------------------------
1 | from collections import deque
2 | from itertools import chain
3 | from sys import getsizeof, stderr
4 |
5 | try:
6 | from reprlib import repr
7 | except ImportError:
8 | pass
9 |
10 |
11 | def total_size(o, handlers={}, verbose=False):
12 | """ Returns the approximate memory footprint an object and all of its contents.
13 |
14 | Automatically finds the contents of the following builtin containers and
15 | their subclasses: tuple, list, deque, dict, set and frozenset.
16 | To search other containers, add handlers to iterate over their contents:
17 |
18 | handlers = {SomeContainerClass: iter,
19 | OtherContainerClass: OtherContainerClass.get_elements}
20 |
21 | """
22 |
23 | def dict_handler(d):
24 | return chain.from_iterable(d.items())
25 |
26 | all_handlers = {
27 | tuple : iter,
28 | list : iter,
29 | deque : iter,
30 | dict : dict_handler,
31 | set : iter,
32 | frozenset: iter,
33 | }
34 | all_handlers.update(handlers) # user handlers take precedence
35 | seen = set() # track which object id's have already been seen
36 | default_size = getsizeof(0) # estimate sizeof object without __sizeof__
37 |
38 | def sizeof(o):
39 | if id(o) in seen: # do not double count the same object
40 | return 0
41 | seen.add(id(o))
42 | s = getsizeof(o, default_size)
43 |
44 | if verbose:
45 | print(s, type(o), repr(o), file=stderr)
46 |
47 | for typ, handler in all_handlers.items():
48 | if isinstance(o, typ):
49 | s += sum(map(sizeof, handler(o)))
50 | break
51 | return s
52 |
53 | return sizeof(o) * 1e-6
54 |
--------------------------------------------------------------------------------
/TidalPy/Extending/burnman/package.py:
--------------------------------------------------------------------------------
1 | import TidalPy
2 | from TidalPy.utilities.dictionary_utils import nested_merge
3 | from TidalPy.logger import get_logger
4 | log = get_logger("TidalPy")
5 |
6 | burnman_installed = True
7 | try:
8 | log.debug('Attempting to import the BurnMan package.')
9 | import burnman
10 | except ImportError:
11 | log.warning("BurnMan installation can not be found. TidalPy's BurnMan extension functions can not be used.")
12 | burnman_installed = False
13 | # Build fake class so type checking passes.
14 | class burnman:
15 | Planet = None
16 | Layer = None
17 | Material = None
18 |
19 | class Mineral:
20 | pass
21 |
22 | class Material:
23 | pass
24 |
25 | def dictionarize_formula(x):
26 | return None
27 | def formula_mass(x):
28 | return None
29 | def material_property(x):
30 | return None
31 |
32 | else:
33 | log.debug(f'BurnMan version {burnman.__version__} was found!')
34 | from burnman.classes.material import Material as Material
35 | from burnman.classes.material import material_property as material_property
36 | from burnman.classes.mineral import Mineral as Mineral
37 | from burnman.tools.chemistry import dictionarize_formula as dictionarize_formula
38 | from burnman.tools.chemistry import formula_mass as formula_mass
39 |
40 | log.debug('Appending TidalPy config with BurnMan specific configurations.')
41 | from .burnman_defaultc import default_burnman_configs
42 |
43 | TidalPy.config = nested_merge(TidalPy.config, default_burnman_configs, make_copies=False)
44 | log.debug('BurnMan extensions initialized.')
45 |
46 | from .burnman_layer import BurnmanLayer as BurnmanLayer
47 | from .burnman_world import BurnManWorld as BurnManWorld
--------------------------------------------------------------------------------
/TidalPy/tides/modes/mode_calc_helper/inclin_calc_orderl2.py:
--------------------------------------------------------------------------------
1 | from typing import Dict, TYPE_CHECKING
2 |
3 | from TidalPy.utilities.performance import njit
4 |
5 | from ...inclination_funcs import orderl2
6 |
7 | if TYPE_CHECKING:
8 | from TidalPy.utilities.types import FloatArray
9 |
10 | from ...inclination_funcs import InclinOutput
11 |
12 |
13 | @njit(cacheable=True)
14 | def inclination_off_maxl_2(obliquity: 'FloatArray') -> Dict[int, 'InclinOutput']:
15 | """ Calculates inclination functions (squared) for a given maximum tidal order (going through each l) - Off Mode
16 |
17 | Obliquity is assumed to be zero.
18 |
19 | Max Supported l = 2
20 |
21 | Parameters
22 | ----------
23 | obliquity : FloatArray
24 | Planet's obliquity [radians]
25 | Returns
26 | -------
27 | result_by_orderl : Dict[int, InclinOutput]
28 | Inclination function L^2_lmp truncated. Stored by order-l.
29 | """
30 |
31 | result_by_orderl = {
32 | 2: orderl2.calc_inclination_off(obliquity)
33 | }
34 |
35 | return result_by_orderl
36 |
37 |
38 | @njit(cacheable=True)
39 | def inclination_on_maxl_2(obliquity: 'FloatArray') -> Dict[int, 'InclinOutput']:
40 | """ Calculates inclination functions (squared) for a given maximum tidal order (going through each l) - On Mode
41 |
42 | Obliquity can be arbitrary.
43 |
44 | Max Supported l = 2
45 |
46 | Parameters
47 | ----------
48 | obliquity : FloatArray
49 | Planet's obliquity [radians]
50 | Returns
51 | -------
52 | result_by_orderl : Dict[int, InclinOutput]
53 | Inclination function L^2_lmp truncated. Stored by order-l.
54 | """
55 |
56 | result_by_orderl = {
57 | 2: orderl2.calc_inclination(obliquity)
58 | }
59 |
60 | return result_by_orderl
61 |
--------------------------------------------------------------------------------
/Tests/Test_Utilities/Test_Exoplanets/test_exoplanet_download.py:
--------------------------------------------------------------------------------
1 | def test_exoplanet_download():
2 | """Tests the exoplanet archive download utility."""
3 |
4 | from TidalPy.utilities.exoplanets import get_exoplanet_data
5 |
6 | exoplanet_data = get_exoplanet_data(
7 | ensure_radius=True,
8 | radius_cutoff=1.5,
9 | ensure_mass=True,
10 | mass_cutoff=None,
11 | ensure_orbital_period=True,
12 | orbital_period_cutoff=50,
13 | ensure_eccentricity=True,
14 | eccentricity_threshold=None,
15 | star_type=None,
16 | only_defaults=True)
17 |
18 | assert len(exoplanet_data) > 0
19 |
20 | def test_exoplanet_download_stellar_type():
21 | """Tests the exoplanet archive download utility using the different kinds of stellar types."""
22 |
23 | from TidalPy.utilities.exoplanets import get_exoplanet_data
24 |
25 | # Try just a single stellar type
26 | exoplanet_data = get_exoplanet_data(
27 | ensure_radius=True,
28 | radius_cutoff=1.5,
29 | ensure_mass=True,
30 | mass_cutoff=None,
31 | ensure_orbital_period=True,
32 | orbital_period_cutoff=50,
33 | ensure_eccentricity=True,
34 | eccentricity_threshold=None,
35 | star_type='M',
36 | only_defaults=True)
37 |
38 | assert len(exoplanet_data) > 0
39 |
40 | # Try just a list of stellar types
41 | exoplanet_data = get_exoplanet_data(
42 | ensure_radius=True,
43 | radius_cutoff=1.5,
44 | ensure_mass=True,
45 | mass_cutoff=None,
46 | ensure_orbital_period=True,
47 | orbital_period_cutoff=50,
48 | ensure_eccentricity=True,
49 | eccentricity_threshold=None,
50 | star_type=['F', 'G', 'K'],
51 | only_defaults=True)
52 |
53 | assert len(exoplanet_data) > 0
54 |
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/starting/kamata.pxd:
--------------------------------------------------------------------------------
1 | cdef void cf_kamata_solid_dynamic_compressible(
2 | double frequency,
3 | double radius,
4 | double density,
5 | double complex bulk_modulus,
6 | double complex shear_modulus,
7 | int degree_l,
8 | double G_to_use,
9 | size_t num_ys,
10 | double complex* starting_conditions_ptr
11 | ) noexcept nogil
12 |
13 | cdef void cf_kamata_solid_static_compressible(
14 | double radius,
15 | double density,
16 | double complex bulk_modulus,
17 | double complex shear_modulus,
18 | int degree_l,
19 | double G_to_use,
20 | size_t num_ys,
21 | double complex* starting_conditions_ptr
22 | ) noexcept nogil
23 |
24 | cdef void cf_kamata_solid_dynamic_incompressible(
25 | double frequency,
26 | double radius,
27 | double density,
28 | double complex shear_modulus,
29 | int degree_l,
30 | double G_to_use,
31 | size_t num_ys,
32 | double complex* starting_conditions_ptr
33 | ) noexcept nogil
34 |
35 | ########################################################################################################################
36 | #### Liquid Layers
37 | ########################################################################################################################
38 |
39 | cdef void cf_kamata_liquid_dynamic_compressible(
40 | double frequency,
41 | double radius,
42 | double density,
43 | double complex bulk_modulus,
44 | int degree_l,
45 | double G_to_use,
46 | size_t num_ys,
47 | double complex* starting_conditions_ptr
48 | ) noexcept nogil
49 |
50 | cdef void cf_kamata_liquid_dynamic_incompressible(
51 | double frequency,
52 | double radius,
53 | double density,
54 | int degree_l,
55 | double G_to_use,
56 | size_t num_ys,
57 | double complex* starting_conditions_ptr
58 | ) noexcept nogil
--------------------------------------------------------------------------------
/TidalPy/RadialSolver/starting/saito.pyx:
--------------------------------------------------------------------------------
1 | # distutils: language = c++
2 | # cython: boundscheck=False, wraparound=False, nonecheck=False, cdivision=True, initializedcheck=False
3 |
4 | ########################################################################################################################
5 | #### Liquid Layers
6 | ########################################################################################################################
7 |
8 |
9 | cdef void cf_saito_liquid_static_incompressible(
10 | double radius,
11 | int degree_l,
12 | size_t num_ys,
13 | double complex* starting_conditions_ptr
14 | ) noexcept nogil:
15 | """ Calculate the initial guess at the bottom of a liquid layer using the static assumption.
16 |
17 | This function uses the Saito 1974 equations (Eq. 19).
18 |
19 | Using the static assumption in a liquid layer results in one independent solutions for the radial derivative.
20 |
21 | These independent solution allow for a general tidal harmonic l, for static tides (w = 0).
22 | However, compressibility and all dissipation dependence is lost due to no dependence on bulk or shear moduli.
23 |
24 |
25 | References
26 | ----------
27 | S74
28 |
29 | Parameters
30 | ----------
31 | radius : double
32 | Radius where the radial functions are calculated. [m]
33 | degree_l : unsigned char
34 | Tidal harmonic order.
35 | num_ys : ssize_t
36 | Number of radial solutions for this layer type.
37 | starting_conditions_ptr : double complex*,