Skip to content

Commit 6671a8b

Browse files
committed
Add late-time velocity validity mapping workflow
1 parent eed6211 commit 6671a8b

1 file changed

Lines changed: 233 additions & 0 deletions

File tree

Lines changed: 233 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,233 @@
1+
name: Cosmology late-time velocity validity map
2+
3+
on:
4+
push:
5+
branches:
6+
- dark-sector-stability-architecture
7+
paths:
8+
- 'dark_sector_architecture/LATE_TIME_VELOCITY_VALIDITY_MAP_PLAN.md'
9+
- 'dark_sector_architecture/qualification/gevolution_particle_lineage.py'
10+
- 'dark_sector_architecture/qualification/run_late_time_velocity_validity_map.py'
11+
- '.github/workflows/cosmology-late-time-velocity-validity.yml'
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: write
16+
17+
concurrency:
18+
group: cosmology-late-time-velocity-validity
19+
cancel-in-progress: true
20+
21+
jobs:
22+
late-time-velocity-validity:
23+
runs-on: ubuntu-latest
24+
timeout-minutes: 60
25+
env:
26+
GEVOLUTION_SHA: 0cca42e51a824002ae4fb602cbd79d671e8ffe60
27+
LATFIELD2_SHA: 2d8c737ab6adc965a1d2718c209f5085af27b09c
28+
TEMPLATE_BLOB: d4de9a5400ef58f6a0181fbe61f18056b233a425
29+
30+
steps:
31+
- uses: actions/checkout@v4
32+
with:
33+
ref: dark-sector-stability-architecture
34+
fetch-depth: 0
35+
- uses: actions/setup-python@v5
36+
with:
37+
python-version: '3.12'
38+
- name: Install dependencies
39+
run: |
40+
sudo apt-get update
41+
sudo apt-get install -y build-essential openmpi-bin libopenmpi-dev libfftw3-dev libgsl-dev libhdf5-dev
42+
python -m pip install --upgrade pip
43+
python -m pip install numpy h5py
44+
- name: Verify frozen validity plan
45+
run: |
46+
git log -1 --format=%H -- dark_sector_architecture/LATE_TIME_VELOCITY_VALIDITY_MAP_PLAN.md \
47+
| tee late_velocity_plan_commit.txt
48+
- name: Fetch pinned sources and template
49+
run: |
50+
git clone https://github.com/gevolution-code/gevolution-1.3.git gevolution
51+
git -C gevolution checkout "$GEVOLUTION_SHA"
52+
git clone https://gitlab.uzh.ch/julian.adamek/LATfield2.git LATfield2
53+
git -C LATfield2 checkout "$LATFIELD2_SHA"
54+
curl -L --fail --silent --show-error \
55+
https://raw.githubusercontent.com/gevolution-code/gevolution-1.2/df8a930732aae1bafa32fd839ee70728bb10773a/sc1_crystal.dat \
56+
-o gevolution/late_velocity_template.dat
57+
test "$(git hash-object gevolution/late_velocity_template.dat)" = "$TEMPLATE_BLOB"
58+
- name: Patch full-precision snapshot logging
59+
run: |
60+
python - <<'PY'
61+
from pathlib import Path
62+
path=Path('gevolution/main.cpp')
63+
text=path.read_text()
64+
marker=(
65+
'\t\t// snapshot output\n'
66+
'\t\tif (snapcount < sim.num_snapshot && '
67+
'1. / a < sim.z_snapshot[snapcount] + 1.)\n'
68+
)
69+
if marker not in text:
70+
raise SystemExit('snapshot marker missing')
71+
replacement=(
72+
'\t\t// snapshot output\n'
73+
'\t\tif (snapcount < sim.num_snapshot && '
74+
'1. / a < sim.z_snapshot[snapcount] + 1.)\n'
75+
'\t\t{\n'
76+
'\t\t\tchar validity_meta[256];\n'
77+
'\t\t\tsprintf(validity_meta, '
78+
'"VEL_VALIDITY_META index=%d cycle=%d a=%.17g z=%.17g '
79+
'tau_over_boxsize=%.17g", snapcount, cycle, a, (1./a)-1., tau);\n'
80+
'\t\t\tCOUT << validity_meta << endl;\n'
81+
'\t\t}\n'
82+
'\t\tif (snapcount < sim.num_snapshot && '
83+
'1. / a < sim.z_snapshot[snapcount] + 1.)\n'
84+
)
85+
path.write_text(text.replace(marker,replacement,1))
86+
PY
87+
- name: Compile gevolution with velocity output
88+
working-directory: gevolution
89+
run: |
90+
make clean
91+
make -j2 \
92+
INCLUDE="-I../LATfield2 -I/usr/include/hdf5/serial" \
93+
LIB="-lfftw3 -lm -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5 -lgsl -lgslcblas" \
94+
DGEVOLUTION="-DPHINONLINEAR -DBENCHMARK -DVELOCITY"
95+
- name: Build frozen N32 and N64 validity settings
96+
run: |
97+
python - <<'PY'
98+
from pathlib import Path
99+
base=Path('dark_sector_architecture/qualification/gevolution_modal_pilot.ini').read_text()
100+
redshifts='5, 2, 1, 0.5, 0.1'
101+
for n,tiling in ((32,8),(64,16)):
102+
tag=f'n{n}'
103+
text=base
104+
replacements={
105+
'template file = pilot_template.dat':'template file = late_velocity_template.dat',
106+
'tiling factor = 2':f'tiling factor = {tiling}',
107+
'Ngrid = 8':f'Ngrid = {n}',
108+
'time step limit = 0.04':'time step limit = 0.02',
109+
'output path = ../pilot_output/':f'output path = ../late_velocity_{tag}_output/',
110+
'generic file base = modalpilot':f'generic file base = late_velocity_{tag}',
111+
'snapshot file base = modalpilot_snap':f'snapshot file base = late_velocity_{tag}_snap',
112+
'snapshot redshifts = 99':f'snapshot redshifts = {redshifts}',
113+
'snapshot outputs = phi, B, chi, hij, v':'snapshot outputs = v, particles',
114+
'Pk file base = modalpilot_pk':f'Pk file base = late_velocity_{tag}_pk',
115+
'Pk outputs = phi, B, chi, hij':'Pk outputs = phi',
116+
'Pk redshifts = 99':'Pk redshifts = 0.1',
117+
}
118+
for old,new in replacements.items():
119+
if old not in text:
120+
raise SystemExit(f'missing token {old}')
121+
text=text.replace(old,new,1)
122+
Path(f'gevolution/late_velocity_{tag}.ini').write_text(text)
123+
PY
124+
- name: Run N32 late-time trajectory
125+
run: |
126+
mkdir -p late_velocity_n32_output
127+
cd gevolution
128+
mpirun --oversubscribe -np 4 ./gevolution -n 2 -m 2 -s late_velocity_n32.ini | tee ../late_velocity_n32.log
129+
- name: Run N64 late-time trajectory
130+
run: |
131+
mkdir -p late_velocity_n64_output
132+
cd gevolution
133+
mpirun --oversubscribe -np 4 ./gevolution -n 2 -m 2 -s late_velocity_n64.ini | tee ../late_velocity_n64.log
134+
- name: Parse precise metadata and verify five snapshots
135+
run: |
136+
python - <<'PY'
137+
import json,re
138+
from pathlib import Path
139+
requested=[5.0,2.0,1.0,0.5,0.1]
140+
pattern=re.compile(
141+
r'VEL_VALIDITY_META index=([0-9]+) cycle=([0-9]+) '
142+
r'a=([0-9eE+.-]+) z=([0-9eE+.-]+) tau_over_boxsize=([0-9eE+.-]+)'
143+
)
144+
out=Path('dark_sector_architecture/qualification/results')
145+
out.mkdir(parents=True,exist_ok=True)
146+
for n in (32,64):
147+
tag=f'n{n}'
148+
matches=pattern.findall(Path(f'late_velocity_{tag}.log').read_text())
149+
if len(matches)!=5:
150+
raise SystemExit(f'N{n}: expected five snapshot metadata lines, got {matches}')
151+
snaps=[]
152+
root=Path(f'late_velocity_{tag}_output')
153+
for j,(idx,cycle,a,z,tau) in enumerate(matches):
154+
if int(idx)!=j:
155+
raise SystemExit(f'N{n}: snapshot index mismatch')
156+
v=list(root.glob(f'*snap{j:03d}_v.h5'))
157+
p=list(root.glob(f'*snap{j:03d}_cdm.h5'))
158+
if len(v)!=1 or len(p)!=1:
159+
raise SystemExit(f'N{n}: missing v/particle files at {j}: {v} {p}')
160+
snaps.append({
161+
'index':j,
162+
'requested_redshift':requested[j],
163+
'actual_scale_factor':float(a),
164+
'actual_redshift':float(z),
165+
'tau_over_boxsize':float(tau),
166+
'cycle':int(cycle),
167+
})
168+
meta={
169+
'protocol':'P0-Q_LATE_TIME_VELOCITY_VALIDITY_MEMBER',
170+
'grid':n,
171+
'requested_redshifts':requested,
172+
'snapshots':snaps,
173+
'seed':424242,
174+
'boxsize_mpc_over_h':64.0,
175+
'time_step_limit':0.02,
176+
'gevolution_sha':'0cca42e51a824002ae4fb602cbd79d671e8ffe60',
177+
'latfield2_sha':'2d8c737ab6adc965a1d2718c209f5085af27b09c',
178+
}
179+
(out/f'late_velocity_validity_n{n}_metadata.json').write_text(
180+
json.dumps(meta,indent=2,sort_keys=True)+'\n'
181+
)
182+
PY
183+
- name: Analyze frozen validity map
184+
run: |
185+
python dark_sector_architecture/qualification/run_late_time_velocity_validity_map.py \
186+
--member 32 late_velocity_n32_output dark_sector_architecture/qualification/results/late_velocity_validity_n32_metadata.json \
187+
--member 64 late_velocity_n64_output dark_sector_architecture/qualification/results/late_velocity_validity_n64_metadata.json \
188+
--output dark_sector_architecture/qualification/results/late_time_velocity_validity_map.json
189+
- name: Add frozen provenance
190+
run: |
191+
python - <<'PY'
192+
import json
193+
from pathlib import Path
194+
p=Path('dark_sector_architecture/qualification/results/late_time_velocity_validity_map.json')
195+
d=json.loads(p.read_text())
196+
d['frozen_plan_commit']=Path('late_velocity_plan_commit.txt').read_text().strip()
197+
d['workflow_head']='${{ github.sha }}'
198+
p.write_text(json.dumps(d,indent=2,sort_keys=True)+'\n')
199+
PY
200+
- uses: actions/upload-artifact@v4
201+
with:
202+
name: cosmology-late-time-velocity-validity
203+
path: |
204+
late_velocity_plan_commit.txt
205+
late_velocity_n32.log
206+
late_velocity_n64.log
207+
gevolution/late_velocity_n32.ini
208+
gevolution/late_velocity_n64.ini
209+
late_velocity_n32_output/*_v.h5
210+
late_velocity_n32_output/*_cdm.h5
211+
late_velocity_n64_output/*_v.h5
212+
late_velocity_n64_output/*_cdm.h5
213+
dark_sector_architecture/qualification/results/late_velocity_validity_n32_metadata.json
214+
dark_sector_architecture/qualification/results/late_velocity_validity_n64_metadata.json
215+
dark_sector_architecture/qualification/results/late_time_velocity_validity_map.json
216+
if-no-files-found: error
217+
- name: Persist validity summaries
218+
run: |
219+
git config user.name "github-actions[bot]"
220+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
221+
git add \
222+
dark_sector_architecture/qualification/results/late_velocity_validity_n32_metadata.json \
223+
dark_sector_architecture/qualification/results/late_velocity_validity_n64_metadata.json \
224+
dark_sector_architecture/qualification/results/late_time_velocity_validity_map.json
225+
if git diff --cached --quiet; then exit 0; fi
226+
git commit -m "Persist late-time velocity validity map"
227+
for attempt in 1 2 3 4 5; do
228+
git fetch origin dark-sector-stability-architecture
229+
git rebase origin/dark-sector-stability-architecture
230+
if git push origin HEAD:dark-sector-stability-architecture; then exit 0; fi
231+
sleep 2
232+
done
233+
exit 1

0 commit comments

Comments
 (0)