Package: jhuki
Writing parameter files for Cactus simulations is not easy. To achieve a
successful evolution, one has to tune several parameters, which typically depend
on the grid configuration or on other settings. Writing these par files by hand
is tedious and error-prone.Jhukiis a Python library to prepare
simulations for theEinstein Toolkit(or Cactus-based codes).:warning: This package is currently under development. It may be full of bugs,
and its interfaces might change without notice. It is also highly
opinionated.FeaturesGenerate parameter files from a template using configuration files or
command-line argumentsTake care of the grid configuration given the desired resolution at the finest
level and other detailsGenerate binary black hole configurations for quasi-circular mergers
(automatically setting the linear momenta)Add dissipationYou can find the reference material at the websitesbozzolo.github.io/Jhuki.ExamplesIntegration with SimFactoryJhukiintegrates well withSimFactory. Assume you have the following
simpletest_sim.rparfile:#!/usr/bin/env python3fromjhuki.simfactoryimportsimfactory_optionfromjhuki.simfactoryimportwrite_parfilepar_b=simfactory_option("@PARB@",5)m_plus=0.5lines="""TwoPunctures::par_b      = $par_bTwoPunctures::par_m_plus = $m_plus# Rest of the parameter file"""write_parfile(lines)SimFactorycan execute this Python file to produce a.parfile to run:simcreate-runtest_sim.rparwill run the parfile with contentTwoPunctures::par_b=5TwoPunctures::par_m_plus=0.5The value forpar_bis run-time adjustable:simcreate-runtest_sim.rpar--definePARB10will produceTwoPunctures::par_b=10TwoPunctures::par_m_plus=0.5Since arbitrary Python code can be executed before the parfile is written,
all the features ofJhukipresented below can be used directly. For instance,
as discussed below, one can prepare quasi circular inspirals with the functionprepare_quasicircular_inspiral, so one can add the entire parfile code for
the two puncture with:#!/usr/bin/env python3fromjhuki.simfactoryimportsimfactory_optionfromjhuki.simfactoryimportwrite_parfilefromjhuki.twopuncturesimportprepare_quasicircular_inspiralpar_b=simfactory_option("@PARB@",5)twopunctures=prepare_quasicircular_inspiral(mass_ratio=1,coordinate_distance=par_b)lines="""$twopunctures# Rest of the parameter file"""write_parfile(lines)This sets up a good fraction of the parfile needed to run quasi circular
inspirals.Working with grid structuresProblem: you want to generate the parfile code for a grid structure with two
refinement centers, each with 8 levels and resolution at the finest level 0.001
and CFL factor of 0.4 (in the finest level). In this, you want to ensure that
the maximum timestep on the grid never exceeds 1 to avoid numerical instability.#!/usr/bin/env python3fromjhukiimportgridaspgrefinement_radii=tuple(2**levelforlevelinrange(7))center1=pg.RefinementCenter(refinement_radii,dx_fine=0.001,cfl_fine=0.5,center_num=1,position=(10,0,0))# Same but with different center_num and positioncenter2=pg.RefinementCenter(refinement_radii,dx_fine=0.001,cfl_fine=0.5,center_num=2,position=(-10,0,0))grid_not_synced=pg.Grid((center1,center2),outer_boundary=1000)grid_synced=pg.set_dt_max_grid(grid_not_synced,dt_max=1)print(grid_synced)This will output something along the lines ofCartGrid3D::type="coordbase"Carpet::domain_from_coordbase="yes"CoordBase::domainsize="minmax"Driver::ghost_size=3CoordBase::boundary_size_x_lower=3CoordBase::boundary_size_y_lower=3CoordBase::boundary_size_z_lower=3CoordBase::boundary_size_x_upper=3CoordBase::boundary_size_y_upper=3CoordBase::boundary_size_z_upper=3CoordBase::xmin=1000CoordBase::ymin=1000CoordBase::zmin=1000CoordBase::xmax=1000CoordBase::ymax=1000CoordBase::zmax=1000CoordBase::dx=0.64
CoordBase::dy=0.64
CoordBase::dz=0.64
Carpet::max_refinement_levels=8Carpet::time_refinement_factors="[1,1,2,4,8,16,32,64]"CarpetRegrid2::num_levels_1=8CarpetRegrid2::position_x_1=10CarpetRegrid2::position_y_1=0CarpetRegrid2::position_z_1=0CarpetRegrid2::radius_1[1]=64CarpetRegrid2::radius_1[2]=32CarpetRegrid2::radius_1[3]=16CarpetRegrid2::radius_1[4]=8CarpetRegrid2::radius_1[5]=4CarpetRegrid2::radius_1[6]=2CarpetRegrid2::radius_1[7]=1CarpetRegrid2::num_levels_2=8CarpetRegrid2::position_x_2=-10
CarpetRegrid2::position_y_2=0CarpetRegrid2::position_z_2=0CarpetRegrid2::radius_2[1]=64CarpetRegrid2::radius_2[2]=32CarpetRegrid2::radius_2[3]=16CarpetRegrid2::radius_2[4]=8CarpetRegrid2::radius_2[5]=4CarpetRegrid2::radius_2[6]=2CarpetRegrid2::radius_2[7]=1You can also add a small shift to the grid so that the origin is not on (0,0,0)
passing thetiny_shiftargument toGrid.Another useful method isrl_synced_every, which returns the number of
iterations at which all the refinement levels are at the same time.Working with binary black holesProblem: you want to simulate a binary black quasi-circular merger. This can be
tricky because you have to provide the correct linear momenta. WithJuhki,
this is trivial:#!/usr/bin/env python3fromjhuki.twopuncturesimportprepare_quasicircular_inspiralmass_ratio=1coordinate_distance=12dimensionless_spin_plus=(0.1,0.2,0.3)dimensionless_spin_minus=(0.4,-0.1,-0.2)twopunctures=prepare_quasicircular_inspiral(mass_ratio,coordinate_distance,chi_plus=dimensionless_spin_plus,chi_minus=dimensionless_spin_minus)print(twopunctures)This will produce an output similar to the following:ADMBase::initial_data = twopunctures
ADMBase::initial_lapse = twopunctures-averaged
ADMBase::initial_shift = zero
ADMBase::initial_dtlapse = zero
ADMBase::initial_dtshift = zero
TwoPunctures::give_bare_mass = no
TwoPunctures::par_b = 6.0
TwoPunctures::target_m_plus = 0.5
TwoPunctures::target_m_minus = 0.5
TwoPunctures::par_P_plus[0] = -0.000531433937072403
TwoPunctures::par_P_plus[1] = 0.0848055056299618
TwoPunctures::par_P_plus[2] = 0
TwoPunctures::par_P_minus[0] = 0.000531433937072403
TwoPunctures::par_P_minus[1] = -0.0848055056299618
TwoPunctures::par_P_minus[2] = 0
TwoPunctures::par_S_plus[0] = 0.025
TwoPunctures::par_S_plus[1] = 0.05
TwoPunctures::par_S_plus[2] = 0.075
TwoPunctures::par_S_minus[0] = 0.1
TwoPunctures::par_S_minus[1] = -0.025
TwoPunctures::par_S_minus[2] = -0.05
TwoPunctures::center_offset[0] = 0.0
TwoPunctures::center_offset[1] = 0.0
TwoPunctures::center_offset[2] = 0.0This module should be used along with theGridone.InstallationThe best way to installJhukiis by cloning this repo and usingpoetry. If you have poetry install, just runpoetry installin the folder where you cloned the repo to installJhuki.
Alternatively,Jhukiis available on PyPI.TestsJhukicomes with a suite of unit tests. To run the tests,poetryrunpytest--cov=./--cov-report=termTests are automatically run after each commit by GitHub Actions. This will also
tell you what is the test coverage.Code styleWe lint the code withblack -l 79.We work only with immutable structures.What doesjhukimean?The wordjhukibelongs to the Tohono O'odham vocabulary and meansrain. Ifkuibitis the tool you use to collect the
fruit of yourCactussimulations, thenjhukiis what allowed that fruit to
be there in the first place.CreditsThe logo contains elements designed bypngtree.com.The computation of the momenta for quasi-circular mergers of binary black holes
usesNRPyPN.
If you use this module, please follow the citation guidelines as specified by
the documentation in theNRPyPNrepo.