################################################################## ## ## AMSS-NCKU Numerical Relativity Mini Test Program ## Author: Assistant (based on Xiaoqu's code) ## 2026/01/20 ## ## This script runs a scaled-down version of the GW150914 test case ## suitable for laptop testing. ## ################################################################## import os import shutil import sys import time # --- Context Manager for Input File Swapping --- class InputFileSwapper: def __init__(self, mini_file="AMSS_NCKU_Input_Mini.py", target_file="AMSS_NCKU_Input.py"): self.mini_file = mini_file self.target_file = target_file self.backup_file = target_file + ".bak" self.swapped = False def __enter__(self): print(f"[MiniProgram] Swapping {self.target_file} with {self.mini_file}...") if os.path.exists(self.target_file): shutil.move(self.target_file, self.backup_file) shutil.copy(self.mini_file, self.target_file) self.swapped = True return self def __exit__(self, exc_type, exc_value, traceback): if self.swapped: print(f"[MiniProgram] Restoring original {self.target_file}...") os.remove(self.target_file) if os.path.exists(self.backup_file): shutil.move(self.backup_file, self.target_file) def main(): # Use the swapper to ensure all imported modules see the mini configuration with InputFileSwapper(): # Import modules AFTER swapping input file try: import AMSS_NCKU_Input as input_data import print_information import setup import numerical_grid import generate_macrodef import makefile_and_run import generate_TwoPuncture_input import renew_puncture_parameter import plot_xiaoqu import plot_GW_strain_amplitude_xiaoqu except ImportError as e: print(f"Error importing modules: {e}") return print_information.print_program_introduction() print("\n" + "#"*60) print(" RUNNING MINI TEST CASE: GW150914-mini") print("#"*60 + "\n") # --- Directory Setup --- File_directory = os.path.join(input_data.File_directory) if os.path.exists(File_directory): print(f" Output directory '{File_directory}' exists. Removing for mini test...") shutil.rmtree(File_directory, ignore_errors=True) os.mkdir(File_directory) shutil.copy("AMSS_NCKU_Input.py", File_directory) # Copies the current (mini) input output_directory = os.path.join(File_directory, "AMSS_NCKU_output") os.mkdir(output_directory) binary_results_directory = os.path.join(output_directory, input_data.Output_directory) os.mkdir(binary_results_directory) figure_directory = os.path.join(File_directory, "figure") os.mkdir(figure_directory) print(" Output directories generated.\n") # --- Setup and Input Generation --- setup.print_input_data(File_directory) setup.generate_AMSSNCKU_input() setup.print_puncture_information() print("\n Generating AMSS-NCKU input parfile...") numerical_grid.append_AMSSNCKU_cgh_input() print("\n Plotting initial grid...") numerical_grid.plot_initial_grid() print("\n Generating macro files...") generate_macrodef.generate_macrodef_h() generate_macrodef.generate_macrodef_fh() # --- Compilation Preparation --- print("\n Preparing to compile and run...") AMSS_NCKU_source_path = "AMSS_NCKU_source" AMSS_NCKU_source_copy = os.path.join(File_directory, "AMSS_NCKU_source_copy") if not os.path.exists(AMSS_NCKU_source_path): print(" Error: AMSS_NCKU_source not found! Please run in the project root.") return shutil.copytree(AMSS_NCKU_source_path, AMSS_NCKU_source_copy) macrodef_h_path = os.path.join(File_directory, "macrodef.h") macrodef_fh_path = os.path.join(File_directory, "macrodef.fh") shutil.copy2(macrodef_h_path, AMSS_NCKU_source_copy) shutil.copy2(macrodef_fh_path, AMSS_NCKU_source_copy) # --- Compilation --- cwd = os.getcwd() os.chdir(AMSS_NCKU_source_copy) print(" Compiling ABE...") makefile_and_run.makefile_ABE() if (input_data.Initial_Data_Method == "Ansorg-TwoPuncture" ): print(" Compiling TwoPunctureABE...") makefile_and_run.makefile_TwoPunctureABE() os.chdir(cwd) # --- Copy Executables --- if (input_data.GPU_Calculation == "no"): ABE_file = os.path.join(AMSS_NCKU_source_copy, "ABE") else: ABE_file = os.path.join(AMSS_NCKU_source_copy, "ABEGPU") if not os.path.exists(ABE_file): print(" Error: ABE executable compilation failed.") return shutil.copy2(ABE_file, output_directory) TwoPuncture_file = os.path.join(AMSS_NCKU_source_copy, "TwoPunctureABE") if (input_data.Initial_Data_Method == "Ansorg-TwoPuncture" ): if not os.path.exists(TwoPuncture_file): print(" Error: TwoPunctureABE compilation failed.") return shutil.copy2(TwoPuncture_file, output_directory) # --- Execution --- start_time = time.time() if (input_data.Initial_Data_Method == "Ansorg-TwoPuncture" ): print("\n Generating TwoPuncture input...") generate_TwoPuncture_input.generate_AMSSNCKU_TwoPuncture_input() AMSS_NCKU_TwoPuncture_inputfile = 'AMSS-NCKU-TwoPuncture.input' AMSS_NCKU_TwoPuncture_inputfile_path = os.path.join( File_directory, AMSS_NCKU_TwoPuncture_inputfile ) shutil.copy2( AMSS_NCKU_TwoPuncture_inputfile_path, os.path.join(output_directory, 'TwoPunctureinput.par') ) print(" Running TwoPunctureABE...") os.chdir(output_directory) makefile_and_run.run_TwoPunctureABE() os.chdir(cwd) # Update Puncture Parameter renew_puncture_parameter.append_AMSSNCKU_BSSN_input(File_directory, output_directory) AMSS_NCKU_inputfile = 'AMSS-NCKU.input' AMSS_NCKU_inputfile_path = os.path.join(File_directory, AMSS_NCKU_inputfile) shutil.copy2( AMSS_NCKU_inputfile_path, os.path.join(output_directory, 'input.par') ) print("\n Input files ready. Launching ABE...") os.chdir(output_directory) makefile_and_run.run_ABE() os.chdir(cwd) end_time = time.time() elapsed_time = end_time - start_time # --- Post-processing --- print("\n Copying output files for inspection...") AMSS_NCKU_error_file_path = os.path.join(binary_results_directory, "setting.par") if os.path.exists(AMSS_NCKU_error_file_path): shutil.copy( AMSS_NCKU_error_file_path, os.path.join(output_directory, "AMSSNCKU_setting_parameter") ) AMSS_NCKU_error_file_path = os.path.join(binary_results_directory, "Error.log") if os.path.exists(AMSS_NCKU_error_file_path): shutil.copy( AMSS_NCKU_error_file_path, os.path.join(output_directory, "Error.log") ) for fname in ["bssn_BH.dat", "bssn_ADMQs.dat", "bssn_psi4.dat", "bssn_constraint.dat"]: fpath = os.path.join(binary_results_directory, fname) if os.path.exists(fpath): shutil.copy(fpath, os.path.join(output_directory, fname)) # --- Plotting --- print("\n Plotting results...") try: plot_xiaoqu.generate_puncture_orbit_plot( binary_results_directory, figure_directory ) plot_xiaoqu.generate_puncture_orbit_plot3D( binary_results_directory, figure_directory ) plot_xiaoqu.generate_puncture_distence_plot( binary_results_directory, figure_directory ) for i in range(input_data.Detector_Number): plot_xiaoqu.generate_gravitational_wave_psi4_plot( binary_results_directory, figure_directory, i ) plot_GW_strain_amplitude_xiaoqu.generate_gravitational_wave_amplitude_plot( binary_results_directory, figure_directory, i ) for i in range(input_data.Detector_Number): plot_xiaoqu.generate_ADMmass_plot( binary_results_directory, figure_directory, i ) for i in range(input_data.grid_level): plot_xiaoqu.generate_constraint_check_plot( binary_results_directory, figure_directory, i ) plot_xiaoqu.generate_binary_data_plot( binary_results_directory, figure_directory ) except Exception as e: print(f"Warning: Plotting failed: {e}") print(f"\n Program Cost = {elapsed_time:.2f} Seconds \n") print(" AMSS-NCKU-Python simulation finished (Mini Test).\n") if __name__ == "__main__": main()