################################################################## ## ## definition of printing the basic information of AMSS-NCKU program ## author:xiaoqu ## 2024/03/22 ## 2025/09/13 modified ## ################################################################## import AMSS_NCKU_Input as input_data import numpy import os import math ################################################################## devide_factor = input_data.devide_factor static_grid_level = input_data.static_grid_level moving_grid_level = input_data.moving_grid_level total_grid_level = input_data.grid_level static_grid_number = input_data.static_grid_number moving_grid_number = input_data.moving_grid_number if ( input_data.Symmetry=="octant-symmetry" ): maximal_domain_size_static_x = numpy.array( [ 0.0, input_data.largest_box_xyz_max[0] ] ) maximal_domain_size_static_y = numpy.array( [ 0.0, input_data.largest_box_xyz_max[1] ] ) maximal_domain_size_static_z = numpy.array( [ 0.0, input_data.largest_box_xyz_max[2] ] ) elif( input_data.Symmetry=="octant-symmetry" ): maximal_domain_size_static_x = numpy.array( [ input_data.largest_box_xyz_min[0], input_data.largest_box_xyz_max[0] ] ) maximal_domain_size_static_y = numpy.array( [ input_data.largest_box_xyz_min[1], input_data.largest_box_xyz_max[1] ] ) maximal_domain_size_static_z = numpy.array( [ 0.0, input_data.largest_box_xyz_max[2] ] ) else: maximal_domain_size_static_x = numpy.array( [ input_data.largest_box_xyz_min[0], input_data.largest_box_xyz_max[0] ] ) maximal_domain_size_static_y = numpy.array( [ input_data.largest_box_xyz_min[1], input_data.largest_box_xyz_max[1] ] ) maximal_domain_size_static_z = numpy.array( [ input_data.largest_box_xyz_min[2], input_data.largest_box_xyz_max[2] ] ) minimal_domain_size_static_x = maximal_domain_size_static_x / ( (devide_factor)**(static_grid_level-1) ) minimal_domain_size_static_y = maximal_domain_size_static_y / ( (devide_factor)**(static_grid_level-1) ) minimal_domain_size_static_z = maximal_domain_size_static_z / ( (devide_factor)**(static_grid_level-1) ) maximal_domain_size_moving = ( minimal_domain_size_static_x / devide_factor ) * ( moving_grid_number / static_grid_number ) minimal_domain_size_moving = maximal_domain_size_moving / ( (devide_factor)**(input_data.moving_grid_level-1) ) maximal_resolution_static = (input_data.largest_box_xyz_max[0] - input_data.largest_box_xyz_min[0]) / static_grid_number minimal_resolution_static = maximal_resolution_static / ( (devide_factor)**(static_grid_level-1) ) maximal_resolution_moving = minimal_resolution_static / devide_factor minimal_resolution_moving = maximal_resolution_moving / ( (devide_factor)**(moving_grid_level-1) ) TimeStep = input_data.Courant_Factor * maximal_resolution_static / ( (devide_factor)**(input_data.refinement_level) ) shell_grid_number = input_data.shell_grid_number minimal_domain_size_shellpatch = input_data.largest_box_xyz_max[0] maximal_domain_size_shellpatch = input_data.largest_box_xyz_max[0] + maximal_resolution_static * shell_grid_number[2] shellpatch_resolution_R = maximal_resolution_static shellpatch_resolution_theta = 0.5 * math.pi / shell_grid_number[1] shellpatch_resolution_phi = 0.5 * math.pi / shell_grid_number[0] ################################################################## ## this function is used to print the basic input data of the whole program def print_input_data( File_directory ): print( "------------------------------------------------------------------------------------------" ) print( ) print( " Printing the basic parameter and setting in the AMSS-NCKU simulation " ) print( ) print( " The number of MPI processes in the AMSS-NCKU simulation = ", input_data.MPI_processes ) print( ) print( " The form of computational equation = ", input_data.Equation_Class ) print( " The initial data in this simulation = ", input_data.Initial_Data_Method ) print( ) print( " Starting evolution time = ", input_data.Start_Evolution_Time ) print( " Final evolution time = ", input_data.Final_Evolution_Time ) print( " Maximal iteration number = ", input_data.Evolution_Step_Number ) print( " Courant factor = ", input_data.Courant_Factor ) print( " Strength of dissipation = ", input_data.Dissipation ) print( " Symmetry of system = ", input_data.Symmetry ) print( " The Runge-Kutta scheme in the time evolution = ", input_data.Time_Evolution_Method ) print( " The finite-difference scheme in the simulation = ", input_data.Finite_Diffenence_Method ) print( ) print( " The static AMR grid type = ", input_data.static_grid_type ) print( " The moving AMR grid type = ", input_data.moving_grid_type ) print( ) print( " The number of static AMR grid levels = ", static_grid_level ) print( " The number of moving AMR grid levels = ", moving_grid_level ) print( " The number of total AMR grid levels = ", total_grid_level ) print( ) print( " The grid number of each static AMR grid level = ", static_grid_number ) print( " The grid number of each moving AMR grid level = ", moving_grid_number ) print( ) print( " The scale for largest static AMR grid in X direction = ", maximal_domain_size_static_x ) print( " The scale for largest static AMR grid in Y direction = ", maximal_domain_size_static_y ) print( " The scale for largest static AMR grid in Z direction = ", maximal_domain_size_static_z ) print( " The scale for smallest static AMR grid in X direction = ", minimal_domain_size_static_x ) print( " The scale for smallest static AMR grid in Y direction = ", minimal_domain_size_static_y ) print( " The scale for smallest static AMR grid in Z direction = ", minimal_domain_size_static_z ) print( ) if ( input_data.moving_grid_level > 0): print( " The scale for largest moving AMR grid = ", maximal_domain_size_moving ) print( " The scale for smallest moving AMR grid = ", minimal_domain_size_moving ) print( ) print( " The coarest resolution for static AMR grid = ", maximal_resolution_static ) print( " The finest resolution for static AMR grid = ", minimal_resolution_static ) if ( input_data.moving_grid_level > 0): print( " The coarest resolution for moving AMR grid = ", maximal_resolution_moving ) print( " The finest resolution for moving AMR grid = ", minimal_resolution_moving ) print( ) print( " The time refinement starts from AMR grid level = ", input_data.refinement_level+1 ) print( " The time interval in each step for coarest AMR grid during time evaluation = ", TimeStep ) print( ) if input_data.basic_grid_set == "Shell-Patch": print( " The Shell-Patch AMR grid structure is used in this simulation " ) print( " Shell-Patch grid number = ", shell_grid_number ) print( " Shell-Patch grid minimal radius = ", minimal_domain_size_shellpatch ) print( " Shell-Patch grid maximal radius = ", maximal_domain_size_shellpatch ) print( " Shell-Patch grid radial resolution = ", shellpatch_resolution_R ) print( " Shell-Patch grid angular resolution = ", shellpatch_resolution_phi, \ shellpatch_resolution_theta ) print( ) elif input_data.basic_grid_set == "Patch": print( " This simulation only uses the Patch AMR grid structure, the Shell-Patch is not used " ) print( ) else: print( " The AMR grid structure setting is wrong !!! " ) print( ) print( "------------------------------------------------------------------------------------------" ) ## file output filepath = os.path.join( File_directory, "AMSS_NCKU_resolution" ) file0 = open(filepath, 'w') print( file=file0 ) print( " Printing the basic parameter and setting in the AMSS-NCKU simulation ", file=file0 ) print( file=file0 ) print( " The number of MPI processes in the AMSS-NCKU simulation = ", input_data.MPI_processes, file=file0 ) print( file=file0 ) print( " The form of computational equation = ", input_data.Equation_Class, file=file0 ) print( " The initial data in this simulation = ", input_data.Initial_Data_Method, file=file0 ) print( file=file0 ) print( " Starting evolution time = ", input_data.Start_Evolution_Time, file=file0 ) print( " Final evolution time = ", input_data.Final_Evolution_Time, file=file0 ) print( " Maximal iteration number = ", input_data.Evolution_Step_Number, file=file0 ) print( " Courant factor = ", input_data.Courant_Factor, file=file0 ) print( " Strength of dissipation = ", input_data.Dissipation, file=file0 ) print( " Symmetry of system = ", input_data.Symmetry, file=file0 ) print( " The Runge-Kutta scheme in the time evolution = ", input_data.Time_Evolution_Method, file=file0 ) print( " The finite-difference scheme in the simulation = ", input_data.Finite_Diffenence_Method, file=file0 ) print( file=file0 ) print( " The static AMR grid type = ", input_data.static_grid_type, file=file0 ) print( " The moving AMR grid type = ", input_data.moving_grid_type, file=file0 ) print( file=file0 ) print( " The number of static AMR grid levels = ", static_grid_level, file=file0 ) print( " The number of moving AMR grid levels = ", moving_grid_level, file=file0 ) print( " The number of total AMR grid levels = ", total_grid_level, file=file0 ) print( file=file0 ) print( " The grid number of each static AMR grid level = ", static_grid_number, file=file0 ) print( " The grid number of each moving AMR grid level = ", moving_grid_number, file=file0 ) print( file=file0 ) print( " The scale for largest static AMR grid in X direction = ", maximal_domain_size_static_x, file=file0 ) print( " The scale for largest static AMR grid in Y direction = ", maximal_domain_size_static_y, file=file0 ) print( " The scale for largest static AMR grid in Z direction = ", maximal_domain_size_static_z, file=file0 ) print( " The scale for smallest static AMR grid in X direction = ", minimal_domain_size_static_x, file=file0 ) print( " The scale for smallest static AMR grid in Y direction = ", minimal_domain_size_static_y, file=file0 ) print( " The scale for smallest static AMR grid in Z direction = ", minimal_domain_size_static_z, file=file0 ) print( ) if ( input_data.moving_grid_level > 0): print( " The scale for largest moving AMR grid = ", maximal_domain_size_moving, file=file0 ) print( " The scale for smallest moving AMR grid = ", minimal_domain_size_moving, file=file0 ) print( file=file0 ) print( " The coarest resolution for static AMR grid = ", maximal_resolution_static, file=file0 ) print( " The finest resolution for static AMR grid = ", minimal_resolution_static, file=file0 ) if ( input_data.moving_grid_level > 0): print( " The coarest resolution for moving AMR grid = ", maximal_resolution_moving, file=file0 ) print( " The finest resolution for moving AMR grid = ", minimal_resolution_moving, file=file0 ) print( file=file0 ) print( " The time refinement starts from AMR grid level = ", input_data.refinement_level+1, file=file0 ) print( " The time interval in each step for coarest AMR grid during time evaluation = ", TimeStep, file=file0 ) print( file=file0 ) if input_data.basic_grid_set == "Shell-Patch": print( " The Shell-Patch AMR grid structure is used in this simulation ", file=file0 ) print( " Shell-Patch grid number = ", shell_grid_number, file=file0 ) print( " Shell-Patch grid minimal radius = ", minimal_domain_size_shellpatch, file=file0 ) print( " Shell-Patch grid maximal radius = ", maximal_domain_size_shellpatch, file=file0 ) print( " Shell-Patch grid radial resolution = ", shellpatch_resolution_R, file=file0 ) print( " Shell-Patch grid angular resolution = ", shellpatch_resolution_phi, \ shellpatch_resolution_theta, file=file0 ) print( file=file0 ) elif input_data.basic_grid_set == "Patch": print( " This simulation only uses the Patch AMR grid structure, the Shell-Patch is not used ", file=file0 ) print( file=file0 ) else: print( " The AMR grid structure setting is wrong !!! ", file=file0 ) print( file=file0 ) ################################################################## ################################################################## # output the puncture information def print_puncture_information(): position = numpy.zeros( (input_data.puncture_number, 3) ) ## initialize the position of each black hole momentum = numpy.zeros( (input_data.puncture_number, 3) ) ## initialize the momentum of each black hole angular_momentum = numpy.zeros( (input_data.puncture_number, 3) ) ## initialize the angular momentum of each black hole parameter = numpy.zeros( (input_data.puncture_number, 3) ) ## initialize the parameter of each black hole print("------------------------------------------------------------------------------------------") print( ) print( " Printing the puncture information " ) print( ) for i in range(input_data.puncture_number): ## set the parameter of each black hole parameter[i] = input_data.parameter_BH[i] position[i] = input_data.position_BH[i] momentum[i] = input_data.momentum_BH[i] ## angular_momentum[i] = input_data.angular_momentum_BH[i] ## setting the angular momentum of each black hole according to the input file if ( input_data.Symmetry == "equatorial-symmetry" ): angular_momentum[i] = [ 0.0, 0.0, (input_data.parameter_BH[i,0]**2) * input_data.parameter_BH[i,2] ] elif ( input_data.Symmetry == "no-symmetry" ): angular_momentum[i] = (input_data.parameter_BH[i,0]**2) * input_data.dimensionless_spin_BH[i] print( f" The information for {i+1} puncture " ) print( f" Mass({i+1}) = {parameter[i,0] :>10.6f}, Charge({i+1}) = {parameter[i,1] :>10.6f}, a({i+1}) = {parameter[i,2] :>10.6f}" ) print( f" X({i+1}) = {position[i,0] :>10.6f}, Y({i+1}) = {position[i,1] :>10.6f}, Z({i+1}) = {position[i,2] :>10.6f}" ) print( f" Px({i+1}) = {momentum[i,0] :>10.6f}, Py({i+1}) = {momentum[i,1] :>10.6f}, Pz({i+1}) = {momentum[i,2] :>10.6f}" ) print( f" Jx({i+1}) = {angular_momentum[i,0]:>10.6f}, Jy({i+1}) = {angular_momentum[i,1]:>10.6f}, Jz({i+1}) = {angular_momentum[i,2]:>10.6f}" ) print() print("------------------------------------------------------------------------------------------") ################################################################## ## Generate the input parfile for AMSS-NCKU program def generate_AMSSNCKU_input(): file1 = open( os.path.join(input_data.File_directory, "AMSS-NCKU.input"), "w" ) ## file1 = open( "AMSS-NCKU.input", "w" ) ## output ABE related settings print( file=file1 ) print( "ABE::checkrun = 0", file=file1 ) print( "ABE::checkfile = bssn.chk", file=file1 ) print( "ABE::Steps = ", input_data.Evolution_Step_Number, file=file1 ) print( "ABE::StartTime = ", input_data.Start_Evolution_Time, file=file1 ) print( "ABE::TotalTime = ", input_data.Final_Evolution_Time, file=file1 ) print( "ABE::DumpTime = ", input_data.Dump_Time, file=file1 ) print( "ABE::d2DumpTime = ", input_data.D2_Dump_Time, file=file1 ) print( "ABE::CheckTime = ", input_data.Check_Time, file=file1 ) print( "ABE::AnalysisTime = ", input_data.Analysis_Time, file=file1 ) print( "ABE::Courant = ", input_data.Courant_Factor, file=file1 ) if ( input_data.Symmetry == "octant-symmetry" ): print( "ABE::Symmetry = 2 ", file=file1 ) elif ( input_data.Symmetry == "equatorial-symmetry" ): print( "ABE::Symmetry = 1 ", file=file1 ) elif ( input_data.Symmetry == "no-symmetry" ): print( "ABE::Symmetry = 0 ", file=file1 ) else : print( " Symmetry Setting Error" ) print( "ABE::small dissipation = ", input_data.Dissipation, file=file1 ) print( "ABE::big dissipation = ", input_data.Dissipation, file=file1 ) print( "ABE::shell dissipation = ", input_data.Dissipation, file=file1 ) print( "ABE::Analysis Level = ", input_data.analysis_level, file=file1 ) print( "ABE::Max mode l = ", input_data.GW_L_max, file=file1 ) print( "ABE::detector number = ", input_data.Detector_Number, file=file1 ) print( "ABE::farest detector position = ", input_data.Detector_Rmax, file=file1 ) print( f"ABE::detector distance = { (input_data.Detector_Rmax-input_data.Detector_Rmin) / (input_data.Detector_Number-1) }", \ file=file1 ) print( "ABE::cpu part = ", input_data.CPU_Part, file=file1 ) print( "ABE::gpu part = ", input_data.GPU_Part, file=file1 ) print( "ABE::output dir = ", input_data.Output_directory, file=file1 ) if ( input_data.Initial_Data_Method == "Cao-Analytical" ): print( "ABE::ID Type = -3", file=file1 ) elif ( input_data.Initial_Data_Method == "KerrSchild-Analytical" ): print( "ABE::ID Type = -2", file=file1 ) elif ( input_data.Initial_Data_Method == "Lousto-Analytical" ): print( "ABE::ID Type = -1", file=file1 ) elif ( input_data.Initial_Data_Method == "Ansorg-TwoPuncture" ): print( "ABE::ID Type = 0", file=file1 ) elif ( input_data.Initial_Data_Method == "Pablo-Olliptic" ): print( "ABE::ID Type = 1", file=file1 ) else : print( " Initial Data Setting Error" ) print( file=file1 ) ## output AHF related settings print( "AHF::AHfindevery = ", input_data.AHF_Find_Every, file=file1 ) print( "AHF::AHdumptime = ", input_data.AHF_Dump_Time, file=file1 ) print( file=file1 ) ## output other settings print( file=file1 ) print( "SurfaceIntegral::number of points for quarter sphere = ", input_data.quarter_sphere_number, file=file1 ) print( file=file1 ) ## output scalar-tensor-F(R) theory settings ## it will not report error even if there is no FR related setting in the input file AMSS_NCKU_Input.py after adding conditional judgment if (input_data.Equation_Class == "BSSN-EScalar"): ## keep certain decimal places in output print( "FR::a2 = ", format(input_data.FR_a2, '.2f'), file=file1 ) print( "FR::l2 = ", format(input_data.FR_l2, '.2f'), file=file1 ) print( "FR::phi0 = ", format(input_data.FR_phi0, '.8f'), file=file1 ) print( "FR::r0 = ", format(input_data.FR_r0, '.2f'), file=file1 ) print( "FR::sigma0 = ", format(input_data.FR_sigma0, '.2f'), file=file1 ) print( file=file1 ) else: print( file=file1 ) file1.close() return file1 ##################################################################