In a previous post, I showed how to use a trajectory file with the single-zone network example code. You do this by setting the environment variable NNT_HYDRO_CODE=traj. Other example trajectories are a wind-type trajectory and a shock-type trajectory that are set, respectively, with NNT_HYDRO_CODE=wind and NNT_HYDRO_CODE=shock,
In this post, I will show how to define your own trajectory function. Since this involves changing example and user codes, the best way to do this is to create my_examples and my_user directories where you can keep your own versions of these codes and not have them collide with any changes we may make to NucNet Tools in the future. To do this, either download or update NucNet Tools. In my case, since I already downloaded NucNet Tools, I do an update:
I now create the my_examples and my_user directories:
mkdir -p my_examples
mkdir -p my_user
The -p flag prevents an error from being reported if the directory already exists. We do not version control these directories in NucNet Tools, so you can do your own versioning, if you would like.
Our new thermodynamic trajectory code will be a modification of user/hydro.cpp. It will compute the mass density ρ as a function of time t as a combination of an exponential expansion and a wind-like trajectory:
ρ(t) = ρ0 exp(-t/τ0) + ρ1 / (1 + t / τ1)2
We will compute T9 = T/109 K from
ρ ∝ T93
To do this, I change into my_user and copy user/hydro.cpp to my_hydro.cpp and user/hydro.h to my_hydro.h:
cp ../user/hydro.cpp my_hydro.cpp
cp ../user/hydro.h my_hydro.h
Notice that I change the names of the files to distinguish them from the default versions. Edit my_hydro.cpp until it is identical to my_hydro.cpp and my_hydro.h until it is identical to my_hydro.h. Of course, you can just download those files directly into my_user, but I want to emphasize that you can, in general, copy user codes to my_user and edit them. Also, notice the important change of the namespace from user to my_user in both my_hydro.cpp and my_hydro.h. This will tell the final code to use the new routines instead of the default ones.
The next step is to download Makefile.inc to my_user. This file will help build our modified code. Notice that if you wish to modify and use other user codes, you will add them to MY_USER_OBJ. For example, if you wanted to change the screening code to your own version in addition to the hydro code, you would copy user/screen.cpp to my_user/my_screen.cpp and user/screen.h to my_user/my_screen.h. You would then edit my_screen.cpp and my_screen.h appropriately and change the namespace to my_user. You would then modify the lines in Makefile.inc to read
#=============================================================================== # User object files. Add routines to MY_USER_OBJ. #=============================================================================== MY_USER_OBJ = $(OBJDIR)/my_hydro.o \ $(OBJDIR)/my_screen.o \ $(MY_USER_OBJ): $(OBJDIR)/%.o: %.cpp $(CC) -c -o $@ $<
For now you need not make any changes to Makefile.inc since the only code we are modifying is hydro.cpp.
With the modified hydro code available, my next step is to create the modified run_single_zone code. I change into my_examples and create a network directory:
mkdir -p network
Notice that I am replicating the directory structure under nucnet-tools-code/examples. I now change into the new network directory and copy run_single_zone.cpp and Makefile from examples/network:
cp ../../examples/network/run_single_zone.cpp .
cp ../../examples/network/Makefile .
Edit these until they are identical to run_single_zone.cpp and Makefile, respectively. (Again, you can simply download these new versions to my_examples, but I wish to emphasize the procedure to modify other example codes.) The main difference between the new Makefile and the old one is that new one includes reference to the my_user directory, while the main difference between the new and old run_single_zone.cpp codes is that the new version uses the my_user namespace for several function calls.
When all this is done, you should be able to make the single-zone network code:
I can now test the trajectory. I make sure I have the appropriate data:
I then edit ../../data_pub/zone.xml to read:
<zone_data> <zone> <optional_properties> <property name="tend">1.e6</property> <property name="tau_0">0.035</property> <property name="tau_1">1.</property> <property name="munuekT">-inf</property> <property name="t9_0">10.</property> <property name="steps">20</property> <property name="rho_0">1.4985e6</property> <property name="rho_1">1.5e3</property> </optional_properties> <mass_fractions> <nuclide name="n"> <z>0</z> <a>1</a> <x>0.67</x> </nuclide> <nuclide name="h1"> <z>1</z> <a>1</a> <x>0.33</x> </nuclide> </mass_fractions> </zone> </zone_data>
I can either do this as described in a previous post or, perhaps more simply, by editing zone.xml by hand. Notice that I input the parameters ρ0, ρ1, τ0, and τ1 through this file. You can of course change the input values to vary the trajectory.
I now run the single-zone code to get the trajectory:
./run_single_zone ../../data_pub/my_net.xml ../../data_pub/zone.xml my_output.xml "[z < 10]" none
The XPath expression none selects no reactions for the calculation. I am not worried about the nucleosynthesis right now, so I do not need to include any reactions.
Once the calculation is done, I can graph the mass density as a function of time. To do this, I first ensure that I have created the analysis codes. Then, in my_examples/network, I type:
../../examples/analysis/print_properties my_output.xml time t9 rho > props.txt
I then graph the mass density (column 4 of props.txt) versus time (column 2 of props.txt) to get
Here we see the initial fast exponential expansion on the τ0 = 0.035 second timescale followed by the slower wind-like expansion on the τ1 = 1 second timescale. (To get a smooth plot, I changed steps in the zone.xml file from 20 to 1.) I will use this trajectory to explore r-process nucleosynthesis in the next few posts.