#ifndef CONFIG_H #define CONFIG_H #include #include #include #include #include #include #include "version.h" // custom floating point accuracy #ifdef SINGLE_PRECISION #define CUSTOMREAL float #define MPI_CR MPI_FLOAT #else #define CUSTOMREAL double #define MPI_CR MPI_DOUBLE #endif #define MPI_DUMMY_TAG 1000 // version inline const std::string TOMOATT_VERSION = std::to_string(PROJECT_VERSION_MAJOR) + "." + std::to_string(PROJECT_VERSION_MINOR) + "." + std::to_string(PROJECT_VERSION_PATCH); inline int loc_I, loc_J, loc_K; inline int loc_I_vis, loc_J_vis, loc_K_vis; inline int loc_I_excl_ghost, loc_J_excl_ghost, loc_K_excl_ghost; inline int n_inv_grids; inline int n_inv_I_loc, n_inv_J_loc, n_inv_K_loc; inline int n_inv_I_loc_ani, n_inv_J_loc_ani, n_inv_K_loc_ani; // 3d indices to 1d index #define I2V(A,B,C) ((C)*loc_I*loc_J + (B)*loc_I + A) inline void V2I(const int& ijk, int& i, int& j, int& k) { k = ijk / (loc_I * loc_J); j = (ijk - k * loc_I * loc_J) / loc_I; i = ijk - k * loc_I * loc_J - j * loc_I; } #define I2V_INV_GRIDS(A,B,C,D) ((D)*n_inv_I_loc*n_inv_J_loc*n_inv_K_loc + (C)*n_inv_I_loc*n_inv_J_loc + (B)*n_inv_I_loc + A) #define I2V_INV_KNL(A,B,C) ((C)*n_inv_I_loc*n_inv_J_loc + (B)*n_inv_I_loc + A) #define I2V_INV_GRIDS_1DK(A,B) ((B)*n_inv_K_loc + (A)) #define I2V_INV_GRIDS_2DJ(A,B,C) ((C)*n_inv_J_loc*n_inv_K_loc + (B)*n_inv_J_loc + (A)) #define I2V_INV_GRIDS_2DI(A,B,C) ((C)*n_inv_I_loc*n_inv_K_loc + (B)*n_inv_I_loc + (A)) #define I2V_INV_ANI_GRIDS(A,B,C,D) ((D)*n_inv_I_loc_ani*n_inv_J_loc_ani*n_inv_K_loc_ani + (C)*n_inv_I_loc_ani*n_inv_J_loc_ani + (B)*n_inv_I_loc_ani + A) #define I2V_INV_ANI_KNL(A,B,C) ((C)*n_inv_I_loc_ani*n_inv_J_loc_ani + (B)*n_inv_I_loc_ani + A) #define I2V_INV_ANI_GRIDS_1DK(A,B) ((B)*n_inv_K_loc_ani + (A)) #define I2V_INV_ANI_GRIDS_1DJ(A,B,C) ((C)*n_inv_J_loc_ani*n_inv_K_loc_ani + (B)*n_inv_J_loc_ani + (A)) #define I2V_INV_ANI_GRIDS_1DI(A,B,C) ((C)*n_inv_I_loc_ani*n_inv_K_loc_ani + (B)*n_inv_I_loc_ani + (A)) #define I2V_INV_GRIDS_1D_GENERIC(A,B,C_ninv) ((B)*C_ninv + (A)) #define I2V_INV_GRIDS_2D_GENERIC(A,B,C,D_ninv,E_inv) ((C)*D_ninv*E_inv + (B)*D_ninv + (A)) #define I2V_EXCL_GHOST(A,B,C) ((C)* loc_I_excl_ghost * loc_J_excl_ghost + (B)* loc_I_excl_ghost + A) #define I2V_VIS(A,B,C) ((C)* loc_I_vis * loc_J_vis + (B)* loc_I_vis + A) #define I2V_3D(A,B,C) ((C)* loc_I_excl_ghost*loc_J_excl_ghost + (B)* loc_I_excl_ghost + A) #define I2V_ELM_CONN(A,B,C) ((C)*(loc_I_vis-1)*(loc_J_vis-1) + (B)*(loc_I_vis-1) + A) #define I2VLBFGS(A,B,C,D) ((A)*loc_I*loc_J*loc_K + (D)*loc_I*loc_J + (C)*loc_I + B) // 2d indices to 1d index #define IJ2V(A,B,C) (C*loc_I*loc_J + (B)*loc_I + A) #define JK2V(A,B,C) (C*loc_J*loc_K + (B)*loc_J + A) #define IK2V(A,B,C) (C*loc_I*loc_K + (B)*loc_I + A) inline const CUSTOMREAL eps = 1e-12; inline const CUSTOMREAL epsAdj = 1e-6; inline bool isZero(CUSTOMREAL x) { return fabs(x) < eps; } inline bool isNegative(CUSTOMREAL x) { return (x) < -eps; } inline bool isPositive(CUSTOMREAL x) { return (x) > eps; } inline bool isZeroAdj(CUSTOMREAL x) { return fabs(x) < epsAdj; } // constants inline const CUSTOMREAL PI = 3.14159265358979323846264338327950288; inline const CUSTOMREAL DEG2RAD = PI/180.0; inline const CUSTOMREAL RAD2DEG = 180.0/PI; inline const CUSTOMREAL M2KM = 0.001; inline const CUSTOMREAL _0_CR = 0.0; inline const CUSTOMREAL _0_5_CR = 0.5; inline const CUSTOMREAL _1_CR = 1.0; inline const CUSTOMREAL _1_5_CR = 1.5; inline const CUSTOMREAL _2_CR = 2.0; inline const CUSTOMREAL _3_CR = 3.0; inline const CUSTOMREAL _4_CR = 4.0; inline const CUSTOMREAL _8_CR = 8.0; inline const CUSTOMREAL TAU_INITIAL_VAL = 1.0; inline const CUSTOMREAL TAU_INF_VAL = 20.0; inline const int SWEEPING_COEFF = 1.0; // coefficient for calculationg sigr/sigt/sigp for cpu // ASCII output precision typedef std::numeric_limits< CUSTOMREAL > dbl; inline const int ASCII_OUTPUT_PRECISION = dbl::max_digits10; // radious of the earth in km //inline CUSTOMREAL R_earth = 6378.1370; inline CUSTOMREAL R_earth = 6371.0; // for compatibility with fortran code inline const CUSTOMREAL GAMMA = 0.0; inline const CUSTOMREAL r_kermel_mask = 40.0; inline CUSTOMREAL step_length_init = 0.01; // update step size limit inline CUSTOMREAL step_length_init_sc = 0.001; // update step size limit (for station correction) inline CUSTOMREAL step_length_decay = 0.9; inline CUSTOMREAL step_length_down = 0.5; inline CUSTOMREAL step_length_up = 1.2; inline CUSTOMREAL step_length_lbfgs; inline int step_method = 1; // 0:modulate according to obj, 1: modulate according to gradient direction. inline CUSTOMREAL step_length_gradient_angle = 120.0; inline const int OBJ_DEFINED = 0; inline const int GRADIENT_DEFINED = 1; // halve steping params inline const CUSTOMREAL HALVE_STEP_RATIO = 0.7; inline const CUSTOMREAL MAX_DIFF_RATIO_VOBJ = 0.8; // maximum difference ratio between vobj_t+1 and vobj_t inline const CUSTOMREAL HALVE_STEP_RESTORAION_RATIO = 0.7; // no restoration if == HALVE_STEP_RATIO // RUN MODE TYPE FLAG inline const int ONLY_FORWARD = 0; inline const int DO_INVERSION = 1; inline const int SRC_RELOCATION = 2; inline const int INV_RELOC = 3; inline const int ONED_INVERSION = 4; inline const int TELESEIS_PREPROCESS = -1; // hiden function // SWEEPING TYPE FLAG inline const int SWEEP_TYPE_LEGACY = 0; inline const int SWEEP_TYPE_LEVEL = 1; inline bool hybrid_stencil_order = false; // if true, code at first run 1st order, then change to 3rd order (Dong Cui 2020) // STENCIL TYPE inline const int NON_UPWIND = 0; inline const int UPWIND = 1; // convert depth <-> radius inline CUSTOMREAL depth2radius(CUSTOMREAL depth) { return R_earth - depth; } inline CUSTOMREAL radius2depth(CUSTOMREAL radius) { return R_earth - radius; } // parallel calculation parameters // here we use so called "inline variables" for defining global variables inline int ngrid_i = 0; // number of grid points in i direction inline int ngrid_j = 0; // number of grid points in j direction inline int ngrid_k = 0; // number of grid points in k direction //inline int ngrid_i_inv = 0; // number of inversion grid points in i direction # DUPLICATED with n_inv_I_loc as all the subdomains have the same number of inversion grid points //inline int ngrid_j_inv = 0; // number of inversion grid points in j direction # DUPLICATED with n_inv_J_loc //inline int ngrid_k_inv = 0; // number of inversion grid points in k direction # DUPLICATED with n_inv_K_loc //inline int ngrid_i_inv_ani = 0; // number of inversion grid points in i direction for anisotropy # DUPLICATED with n_inv_I_loc_ani //inline int ngrid_j_inv_ani = 0; // number of inversion grid points in j direction for anisotropy # DUPLICATED with n_inv_J_loc_ani //inline int ngrid_k_inv_ani = 0; // number of inversion grid points in k direction for anisotropy # DUPLICATED with n_inv_K_loc_ani // inversion grid type flags #define INV_GRID_REGULAR 0 #define INV_GRID_FLEX 1 #define INV_GRID_TRAPE 2 // mpi parameters inline int world_nprocs; // total number of processes (all groups) inline int world_rank; // mpi rank of this process (all groups) inline int sim_nprocs; // number of processes in this simulation group inline int sim_rank; // mpi rank of this process in this simulation group inline int inter_sim_rank; inline int sub_nprocs; // total number of processes inline int sub_rank; // mpi rank of this process inline int inter_sub_rank; // mpi rank of this process in the inter-subdomain communicator inline int inter_sub_nprocs; // number of processes in the inter-subdomain communicator inline int nprocs; // = n subdomains inline int myrank; // = id subdomain inline MPI_Comm sim_comm, inter_sim_comm, sub_comm, inter_sub_comm; // mpi communicator for simulation, inter-simulation, subdomain, and inter subdomains inline int n_sims = 1; // number of mpi groups for simultaneous runs inline int n_procs_each_sim = 1; // number of processes in each simulation group inline int n_subdomains = 1; // number of subdomains inline int n_subprocs = 1; // number of sub processes in each subdomain inline int ndiv_i = 1; // number of divisions in x direction inline int ndiv_j = 1; // number of divisions in y direction inline int ndiv_k = 1; // number of divisions in z direction inline int id_sim = 0; // simultaneous run id (not equal to src id) (parallel level 1) inline int id_subdomain = 0; // subdomain id (parallel level 2) inline bool subdom_main = false; // true if this process is main process in subdomain (parallel level 3) // flags for explaining the process's role inline bool proc_read_srcrec = false; // true if this process is reading source file inline bool proc_store_srcrec = false; // true if this process is storing srcrec file // MNMN stop using these global variable for avoiding misleadings during the sources' iteration loop //inline int id_sim_src = 0; // id of current target source //inline std::string name_sim_src = "unknown"; //name of current target source // rule to distribute source to simultaneous group inline int select_id_sim_for_src(const int& i_src, const int& n_sims){ return i_src % n_sims; } // read input yaml file inline std::string input_file="input_params.yaml"; // output directory name inline std::string output_dir="./OUTPUT_FILES/"; // output file format #define OUTPUT_FORMAT_HDF5 11111 #define OUTPUT_FORMAT_ASCII 22222 //#define OUTPUT_FORMAT_BINARY 33333 //#TODO: add inline int output_format = OUTPUT_FORMAT_HDF5; // 0 - ascii, 1 - hdf5, 2 - binary // HDF5 io mode (independent or collective) #ifdef USE_HDF5_IO_COLLECTIVE #define HDF5_IO_MODE H5FD_MPIO_COLLECTIVE #else #define HDF5_IO_MODE H5FD_MPIO_INDEPENDENT #endif // smooth parameters inline int smooth_method = 0; // 0: multi grid parametrization, 1: laplacian smoothing inline CUSTOMREAL smooth_lp = 1.0; inline CUSTOMREAL smooth_lt = 1.0; inline CUSTOMREAL smooth_lr = 1.0; inline CUSTOMREAL regul_lp = 1.0; inline CUSTOMREAL regul_lt = 1.0; inline CUSTOMREAL regul_lr = 1.0; inline const int GRADIENT_DESCENT = 0; inline const int HALVE_STEPPING_MODE = 1; inline const int LBFGS_MODE = 2; inline int optim_method = 0; // 0: gradient descent, 1: halve_stepping, 2: LBFGS inline const CUSTOMREAL wolfe_c1 = 1e-4; inline const CUSTOMREAL wolfe_c2 = 0.9; inline const int Mbfgs = 5; // number of gradients/models stored in memory inline CUSTOMREAL regularization_weight = 0.5; // regularization weight inline int max_sub_iterations = 20; // maximum number of sub-iterations inline const CUSTOMREAL LBFGS_RELATIVE_step_length = 3.0; // relative step size for the second and later iteration inline CUSTOMREAL Kdensity_coe = 0.0; // a preconditioner \in [0,1], kernel -> kernel / pow(kernel density, Kdensity_coe) // variables for test inline bool if_test = false; // verboose mode inline bool if_verbose = false; //inline bool if_verbose = true; // if use gpu inline bool use_gpu; // total number of sources in the srcrec file inline int nsrc_total = 0; // flag if common receiver double difference data is used inline bool src_pair_exists = false; // weight of different typs of data inline CUSTOMREAL abs_time_local_weight = 1.0; // weight of absolute traveltime data for local earthquake, default: 1.0 inline CUSTOMREAL cr_dif_time_local_weight = 1.0; // weight of common receiver differential traveltime data for local earthquake, default: 1.0 inline CUSTOMREAL cs_dif_time_local_weight = 1.0; // weight of common source differential traveltime data for local earthquake, default: 1.0 (not ready) inline CUSTOMREAL teleseismic_weight = 1.0; // weight of teleseismic data default: 1.0 (not ready) inline CUSTOMREAL abs_time_local_weight_reloc = 1.0; // weight of absolute traveltime data for local earthquake, default: 1.0 inline CUSTOMREAL cs_dif_time_local_weight_reloc = 1.0; // weight of common source differential traveltime data for local earthquake, default: 1.0 inline CUSTOMREAL cr_dif_time_local_weight_reloc = 1.0; // weight of common receiver differential traveltime data for local earthquake, default: 1.0 inline CUSTOMREAL teleseismic_weight_reloc = 1.0; // weight of teleseismic data default: 1.0 (not ready) // misfit balance inline bool balance_data_weight = false; // add the weight to normalize the initial objective function of different types of data. 1 for yes and 0 for no inline CUSTOMREAL total_abs_local_data_weight = 0.0; inline CUSTOMREAL total_cr_dif_local_data_weight = 0.0; inline CUSTOMREAL total_cs_dif_local_data_weight = 0.0; inline CUSTOMREAL total_teleseismic_data_weight = 0.0; inline bool balance_data_weight_reloc = false; // add the weight to normalize the initial objective function of different types of data for relocation. 1 for yes and 0 for no inline CUSTOMREAL total_abs_local_data_weight_reloc = 0.0; inline CUSTOMREAL total_cr_dif_local_data_weight_reloc = 0.0; inline CUSTOMREAL total_cs_dif_local_data_weight_reloc = 0.0; inline CUSTOMREAL total_teleseismic_data_weight_reloc = 0.0; // 2d solver parameters for teleseismic data // use fixed domain size for all 2d simulations in teleseismic data inline CUSTOMREAL rmin_2d = 3370.5; inline CUSTOMREAL rmax_2d = 6471.5; inline CUSTOMREAL tmin_2d = -5.0/180.0*PI; inline CUSTOMREAL tmax_2d = 120.0/180.0*PI; inline CUSTOMREAL dr_2d = 2.0; inline CUSTOMREAL dt_2d = PI/1000.0; inline const CUSTOMREAL TOL_2D_SOLVER = 1e-5; inline const CUSTOMREAL MAX_ITER_2D_SOLVER = 4000; inline const CUSTOMREAL SWEEPING_COEFF_TELE = 1.05; // coefficient for calculationg sigr/sigt/sigp inline const int N_LAYER_SRC_BOUND = 1; // number of layers for source boundary inline CUSTOMREAL DIST_SRC_DDT = 2.5*DEG2RAD; // distance threshold of two stations inline const std::string OUTPUT_DIR_2D = "/2D_TRAVEL_TIME_FIELD/"; // output directory for 2d solver // earthquake relocation inline CUSTOMREAL step_length_src_reloc = 0.01; // step length for source relocation inline CUSTOMREAL step_length_decay_src_reloc = 0.9; inline int N_ITER_MAX_SRC_RELOC = 501; // max iteration for source location inline CUSTOMREAL TOL_SRC_RELOC = 1e-3; // threshold of the norm of gradient for stopping single earthquake location inline const CUSTOMREAL TOL_step_length = 1e-4; // threshold of the max step size for stopping single earthquake location inline CUSTOMREAL rescaling_dep = 10.0; inline CUSTOMREAL rescaling_lat = 5.0; inline CUSTOMREAL rescaling_lon = 5.0; inline CUSTOMREAL rescaling_ortime = 0.5; inline CUSTOMREAL max_change_dep = 10.0; // default: max change is 10 km inline CUSTOMREAL max_change_lat = 5.0; // default: max change is 5 km inline CUSTOMREAL max_change_lon = 5.0; // default: max change is 5 km inline CUSTOMREAL max_change_ortime = 0.5; // default: max change is 0.5 s inline bool ortime_local_search = true; inline int min_Ndata_reloc = 4; // if an earthquake is recorded by less than times, relocation is not allowed. // inversion strategy parameters inline int inv_mode = 1; inline int model_update_N_iter = 1; inline int relocation_N_iter = 1; inline int max_loop_mode0 = 10; inline int max_loop_mode1 = 10; // INV MODE TYPE FLAG inline const int ITERATIVE = 0; inline const int SIMULTANEOUS = 1; // source receiver weight calculation inline CUSTOMREAL ref_value = 1.0; // reference value for source receiver weight calculation inline std::string output_file_weight = "srcrec_weight.txt"; // output file name for source receiver weight calculation #endif // CONFIG_H