Shamrock 2025.10.0
Astrophysical Code
Loading...
Searching...
No Matches
__init__.py
1"""
2Phantom related utilities.
3"""
4
5import os
6
7import shamrock.sys
8
9
10def parse_in_file(in_file):
11 """
12 Parse a Phantom .in file and return a dictionary of the parameters.
13 """
14 with open(in_file, "r") as f:
15 lines = f.readlines()
16
17 params = {}
18
19 for line in lines:
20 # Skip empty lines and comment lines
21 stripped_line = line.strip()
22 if not stripped_line or stripped_line.startswith("#"):
23 continue
24
25 # Check if line contains an equals sign
26 if "=" in line:
27 # Split by '=' to get variable name and value part
28 parts = line.split("=", 1)
29 var_name = parts[0].strip()
30
31 # Get value part (everything after =)
32 value_part = parts[1]
33
34 # Remove comment if present (text after !)
35 if "!" in value_part:
36 value_part = value_part.split("!")[0]
37
38 # Strip whitespace from value
39 value = value_part.strip()
40
41 # Try to convert to appropriate type
42 # Check for boolean
43 if value == "T":
44 value = True
45 elif value == "F":
46 value = False
47 else:
48 # Try to convert to number
49 try:
50 # Try integer first
51 if "." not in value and "E" not in value and "e" not in value:
52 value = int(value)
53 else:
54 # Try float
55 value = float(value)
56 except ValueError:
57 # Keep as string if conversion fails
58 pass
59
60 params[var_name] = value
61
62 return params
63
64
65def load_simulation(simulation_path, dump_file_name=None, in_file_name=None, do_print=True):
66 """
67 Load a Phantom simulation into a Shamrock model.
68 """
69
70 if do_print and shamrock.sys.world_rank() == 0:
71 print("-----------------------------------------------------------")
72 print("---------------- Phantom dump loading -----------------")
73 print("-----------------------------------------------------------")
74
75 if in_file_name is not None:
76 in_file_path = os.path.join(simulation_path, in_file_name)
77 in_params = parse_in_file(in_file_path)
78 else:
79 in_params = None
80
81 if dump_file_name is None:
82 if in_file_name is not None:
83 dump_file_name = in_params["dumpfile"]
84
85 else:
86 raise ValueError("Either dump_file_name or in_file_name must be provided")
87
88 dump_path = os.path.join(simulation_path, dump_file_name)
89
90 if do_print and shamrock.sys.world_rank() == 0:
91 print(" - Loading phantom dump from: ", dump_path)
92
93 # setup = dump finish with .tmp
94 is_setup_file = dump_file_name.endswith(".tmp")
95
96 # Open the phantom dump
97 dump = shamrock.load_phantom_dump(dump_path)
98
99 # Start a SPH simulation from the phantom dump
100 ctx = shamrock.Context()
101 ctx.pdata_layout_new()
102 model = shamrock.get_Model_SPH(context=ctx, vector_type="f64_3", sph_kernel="M4")
103
104 if do_print and shamrock.sys.world_rank() == 0:
105 print(" - Generating Shamrock solver config from phantom dump")
106 cfg = model.gen_config_from_phantom_dump(dump)
107 if do_print and shamrock.sys.world_rank() == 0:
108 print(" - Setting Shamrock solver config")
109 # Set the solver config to be the one stored in cfg
110 model.set_solver_config(cfg)
111
112 if do_print and shamrock.sys.world_rank() == 0:
113 print(" - Initializing domain scheduler")
114
115 model.init_scheduler(int(1e8), 1)
116
117 if do_print and shamrock.sys.world_rank() == 0:
118 print(f" - Initializing from phantom dump (setup file: {is_setup_file})")
119
120 if is_setup_file:
121 model.init_from_phantom_dump(dump, 0.05)
122 else:
123 model.init_from_phantom_dump(dump, 1.0)
124
125 # Print infos
126 if do_print and shamrock.sys.world_rank() == 0:
127 print(" - Shamrock solver config:")
128 model.get_current_config().print_status()
129
130 if in_params is not None:
131 print(" - Phantom input file parameters:")
132 for key, value in in_params.items():
133 print(f"{key}: {value}")
134
135 # print("Dump state:")
136 # dump.print_state()
137
138 return ctx, model, in_params
139
140
141def run_phantom_simulation(simulation_folder, sim_name):
142 """
143 Run a Phantom simulation in Shamrock.
144 """
145
146 input_file_name = sim_name + ".in"
147
148 ctx, model, in_params = shamrock.utils.phantom.load_simulation(
149 simulation_folder, in_file_name=input_file_name
150 )
151
152 dump_file_name = in_params["dumpfile"]
153
154 # phantom dumps are 00000.tmp if before start and then sim_name_{:05d}
155 # parse the dump number
156 dump_number = int(dump_file_name.split("_")[1].split(".")[0])
157 print(f"Dump number: {dump_number}")
158
159 dtmax = float(in_params["dtmax"])
160 tmax = float(in_params["tmax"])
161
162 def get_ph_dump_file_name(dump_number):
163 return f"{sim_name}_{dump_number:05d}"
164
165 def get_ph_dump_name(dump_number):
166 return os.path.join(simulation_folder, get_ph_dump_file_name(dump_number))
167
168 def do_dump(dump_number):
169 if shamrock.sys.world_rank() == 0:
170 print("-----------------------------------------------------------")
171 print("---------------- Phantom dump saving -----------------")
172 print("-----------------------------------------------------------")
173 print(f" - Saving dump {dump_number} to {get_ph_dump_name(dump_number)}")
174 dump = model.make_phantom_dump()
175 dump.save_dump(get_ph_dump_name(dump_number))
176
177 # replace dumpfile in the input file
178 lines = []
179 with open(os.path.join(simulation_folder, f"{sim_name}.in"), "r") as f:
180 lines = f.readlines()
181 with open(os.path.join(simulation_folder, f"{sim_name}.in"), "w") as f:
182 for line in lines:
183 if "dumpfile" in line:
184 line = f" dumpfile = {get_ph_dump_file_name(dump_number)} ! dump file to start from\n"
185 f.write(line)
186
187 # if .tmp is there remove it
188 if (
189 os.path.exists(os.path.join(simulation_folder, f"{sim_name}_00000.tmp"))
190 and shamrock.sys.world_rank() == 0
191 ):
192 os.remove(os.path.join(simulation_folder, f"{sim_name}_00000.tmp"))
193
194 do_dump(dump_number)
195
196 dump_number += 1
197
198 # evolve until tmax in increments of dtmax
199 last_step = False
200 while not last_step:
201 next_time = model.get_time() + dtmax
202
203 if next_time > tmax:
204 next_time = tmax
205 last_step = True
206
207 last_step = model.evolve_until(next_time)
208
209 do_dump(dump_number)
210 dump_number += 1
211
212 return ctx, model, in_params
load_simulation(simulation_path, dump_file_name=None, in_file_name=None, do_print=True)
Definition __init__.py:65
run_phantom_simulation(simulation_folder, sim_name)
Definition __init__.py:141