initial upload

This commit is contained in:
2025-12-17 10:53:43 +08:00
commit f3f1778f77
308 changed files with 129940 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
# Inversion test
This is an example for inversion calculation with small grid.
![](img/result_fun.png)
1. Run all cells of `make_test_model.ipynb` or python script `make_test_mode.py` for creating necessary input files:
- source, receiver file (src_rec_test.dat)
- true model (test_model_true.h5)
- initial model (test_model_init.h5)
2. then run TOMOATT forward with `input_params_pre.yml` for calculating the true arrival times at the stations.
The calculated travel time at the stations is saved in the file `src_rec_test_out.dat`
Following command will run the forward simulation with the true model
``` bash
mpirun --oversubscribe -n 8 ../../build/bin/TOMOATT -i input_params_pre.yml
```
Volumetric output data is saved in the file `OUTPUT_FILES/out_data_sim_0.h5`.
This file may be visualized by paraview with opening the index file `OUTPUT_FILES/out_data_sim_0.xmf`.
3. run TOMOATT in inversion mode with `input_params.yml`, by the command
``` bash
mpirun --oversubscribe -n 8 ../../build/bin/TOMOATT -i input_params.yml
```
The volumetric output data is again saved in the file `OUTPUT_FILES/out_data_sim_0.h5`.
4. The final output data is stored in OUTPUT_FILES/final_model.h5. This file may be visualized by e.g. check_3d_out.ipynb

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,71 @@
# This script shows how to recompose the output data for further analysis
# As the result data is collectively written out by each process, the data is composed on subgrid basis.
# the data needs to be reindexed and reassembled to a global grid.
import numpy as np
import sys
sys.path.append("../../utils/")
from tomoatt_data_retrieval import get_data_from_h5
#
# plot calculated travel time field
# number of grids
nx = 50
ny = 50
nz = 10
# number of subgrid
ndiv_x = 2
ndiv_y = 2
ndiv_z = 1
# read data
_src_id = 0
_inv_id = 0
# filling 0 for digit
inv_id = str(_inv_id).zfill(4)
src_id = str(_src_id).zfill(4)
# file name
#fname_data = "OUTPUT_FILES/T_res_inv_{}_src_{}.dat".format(inv_id, src_id)
fname_data = "OUTPUT_FILES/out_data_sim_{}.h5".format(_src_id)
# path for grid data
fname_grid = "OUTPUT_FILES/out_data_grid.h5"
# name dataset to be read
dataset_name = "/Data/fun_inv_{}".format(inv_id)
data, r, t, p = get_data_from_h5(fname_data, fname_grid, dataset_name, nz, ny, nx, ndiv_z, ndiv_y, ndiv_x, verbose=True)
# plot
import matplotlib.pyplot as plt
fig, axs = plt.subplots(3, 1, figsize=(15, 5))
#axs[0].imshow(data[5,:,:], cmap='jet', interpolation='bilinear')
ir_slice=5
axs[0].pcolormesh(p[ir_slice,0,:], t[ir_slice,:,0], data[ir_slice,:,:], shading='auto')
axs[0].set_title('lon-lat')
axs[0].set_xlabel('longitude')
axs[0].set_ylabel('latitude')
axs[0].set_aspect(1)
it_slice=15
axs[1].pcolormesh(p[0,it_slice,:], r[:,it_slice,0], data[:,it_slice,:], shading='auto')
axs[1].set_title('r-lon')
axs[1].set_xlabel('longitude')
axs[1].set_ylabel('latitude')
axs[1].set_aspect(10)
ip_slice=15
axs[2].pcolormesh(t[0,:,ip_slice], r[:,0,ip_slice], data[:,:,ip_slice], shading='auto')
axs[2].set_title('r-lat')
axs[2].set_xlabel('longitude')
axs[2].set_ylabel('latitude')
axs[2].set_aspect(10)
plt.tight_layout()
plt.show()

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

View File

@@ -0,0 +1,259 @@
version: 3
#################################################
# computational domian #
#################################################
domain:
min_max_dep: [-10, 10] # depth in km
min_max_lat: [37.7, 42.3] # latitude in degree
min_max_lon: [22.7, 27.3] # longitude in degree
n_rtp: [10, 50, 50] # number of nodes in depth,latitude,longitude direction
#################################################
# traveltime data file path #
#################################################
source:
src_rec_file: OUTPUT_FILES/src_rec_file_forward.dat # source receiver file path
swap_src_rec: true # swap source and receiver
#################################################
# initial model file path #
#################################################
model:
init_model_path: ./test_model_init.h5 # path to initial model file
# model_1d_name: dummy_model_1d_name # 1D model name used in teleseismic 2D solver (iasp91, ak135, user_defined is available), defined in include/1d_model.h
#################################################
# parallel computation settings #
#################################################
parallel: # parameters for parallel computation
n_sims: 1 # number of simultanoues runs (parallel the sources)
ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
nproc_sub: 1 # number of processors for sweep parallelization (parallel the fast sweep method)
use_gpu: false # true if use gpu (EXPERIMENTAL)
############################################
# output file setting #
############################################
output_setting:
output_dir: ./OUTPUT_FILES/ # path to output director (default is ./OUTPUT_FILES/)
output_source_field: true # output the calculated field of all sources
output_model_dat: false # output model_parameters_inv_0000.dat (data in text format) or not.
output_final_model: true # output merged final model (final_model.h5) or not.
output_in_process: true # output model at each inv iteration or not.
output_in_process_data: true # output src_rec_file at each inv iteration or not.
single_precision_output: false # output results in single precision or not.
verbose_output_level: 1 # output internal parameters, if no, only model parameters are out.
output_file_format: 0
#################################################
# inversion or forward modeling #
#################################################
# run mode
# 0 for forward simulation only,
# 1 for inversion
# 2 for earthquake relocation
# 3 for inversion + earthquake relocation
run_mode: 1
###################################################
# model update parameters setting #
###################################################
model_update:
max_iterations: 3 # maximum number of inversion iterations
optim_method: 0 # optimization method. 0 : grad_descent, 1 : halve-stepping, 2 : lbfgs (EXPERIMENTAL)
#common parameters for all optim methods
step_length: 0.01 # the initial step length of model perturbation. 0.01 means maximum 1% perturbation for each iteration.
# parameters for optim_method 0 (gradient_descent)
optim_method_0:
step_method: 1 # the method to modulate step size. 0: according to objective function; 1: according to gradient direction
# if step_method:0. if objective function increase, step size -> step length * step_length_decay.
step_length_decay: 0.9 # default: 0.9
# if step_method:1. if the angle between the current and the previous gradients is greater than step_length_gradient_angle, step size -> step length * step_length_change[0].
# otherwise, step size -> step length * step_length_change[1].
step_length_gradient_angle: 120 # default: 120.0
step_length_change: [0.5, 1.2] # default: [0.5,1.2]
# Kdensity_coe is used to rescale the final kernel: kernel -> kernel / pow(density of kernel, Kdensity_coe). if Kdensity_coe > 0, the region with less data will be enhanced during the inversion
# e.g., if Kdensity_coe = 0, kernel remains upchanged; if Kdensity_coe = 1, kernel is normalized. 0.5 or less is recommended if really required.
Kdensity_coe: 0 # default: 0.0, range: 0.0 - 1.0
# parameters for optim_method 1 (halve-stepping) or 2 (lbfgs)
optim_method_1_2:
max_sub_iterations: 20 # maximum number of each sub-iteration
regularization_weight: 0.5 # weight value for regularization (lbfgs mode only)
coefs_regulalization_rtp: [1, 1, 1] # regularization coefficients for rtp (lbfgs mode only)
# smoothing
smoothing:
smooth_method: 0 # 0: multiparametrization, 1: laplacian smoothing (EXPERIMENTAL)
l_smooth_rtp: [1, 0.0174533, 0.0174533] # smoothing coefficients for laplacian smoothing
# parameters for smooth method 0 (multigrid model parametrization)
# inversion grid can be viewed in OUTPUT_FILES/inversion_grid.txt
n_inversion_grid: 5 # number of inversion grid sets
# settings for flexible inversion grid
dep_inv: [-10, -7.5, -5, -2.5, 0, 2.5, 5, 7.5, 10] # inversion grid for vel in depth (km)
lat_inv: [37.7, 38.16, 38.62, 39.08, 39.54, 40.0, 40.46, 40.92, 41.38, 41.84, 42.3] # inversion grid for vel in latitude (degree)
lon_inv: [22.7, 23.06, 23.42, 23.78, 24.14, 24.5, 24.86, 25.22, 25.58, 25.94, 26.3, 26.66, 27.02, 27.3] # inversion grid for vel in longitude (degree)
trapezoid: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
# if we want to use another inversion grid for inverting anisotropy, set invgrid_ani: true (default: false)
invgrid_ani: false
# settings for flexible inversion grid for anisotropy
dep_inv_ani: [] # inversion grid for ani in depth (km)
lat_inv_ani: [] # inversion grid for ani in latitude (degree)
lon_inv_ani: [] # inversion grid for ani in longitude (degree)
trapezoid_ani: [1, 0, 50] # usually set as [1.0, 0.0, 50.0] (default)
# Carefully change trapezoid and trapezoid_ani, if you really want to use trapezoid inversion grid, increasing the inversion grid spacing with depth to account for the worse data coverage in greater depths.
# The trapezoid_ inversion grid with index (i,j,k) in longitude, latitude, and depth is defined as:
# if dep_inv[k] < trapezoid[1], lon = lon_inv[i];
# lat = lat_inv[j];
# dep = dep_inv[k];
# if trapezoid[1] <= dep_inv[k] < trapezoid[2], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*(dep_inv[k]-trapezoid[1])/(trapezoid[2]-trapezoid[1])*trapezoid[0];
# dep = dep_inv[k];
# if trapezoid[2] <= dep_inv[k], lon = mid_lon_inv+(lon_inv[i]-mid_lon_inv)*trapezoid[0];
# lat = mid_lat_inv+(lat_inv[i]-mid_lat_inv)*trapezoid[0];
# dep = dep_inv[k];
# The shape of trapezoid inversion gird (x) looks like:
#
# lon_inv[0] [1] [2] [3] [4]
# |<-------- (lon_inv[end] - lon_inv[0]) ---->|
# dep_inv[0] | x x x x x |
# | |
# dep_inv[1] | x x x x x |
# | |
# dep_inv[2] = trapezoid[1] / x x x x x \
# / \
# dep_inv[3] / x x x x x \
# / \
# dep_inv[4] = trapezoid[2] / x x x x x \
# | |
# dep_inv[5] | x x x x x |
# | |
# dep_inv[6] | x x x x x |
# |<---- trapezoid[0]* (lon_inv[end] - lon_inv[0]) ------>|
# inversion grid volume rescale (kernel -> kernel / volume of inversion grid mesh),
# this precondition may be carefully applied if the sizes of inversion grids are unbalanced
invgrid_volume_rescale: true
# path to station correction file (under development)
use_sta_correction: false
# sta_correction_file: dummy_sta_correction_file # station correction file path
step_length_sc: 0.001 # step length relate to the update of station correction terms
# In the following data subsection, XXX_weight means a weight is assigned to the data, influencing the objective function and gradient
# XXX_weight : [d1,d2,w1,w2] means:
# if XXX < d1, weight = w1
# if d1 <= XXX < d2, weight = w1 + (XXX-d1)/(d2-d1)*(w2-w1), (linear interpolation)
# if d2 <= XXX , weight = w2
# You can easily set w1 = w2 = 1.0 to normalize the weight related to XXX.
# -------------- using absolute traveltime data --------------
abs_time:
use_abs_time: true # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
residual_weight: [1, 3, 1, 1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
distance_weight: [50, 150, 1, 1] # XXX is epicenter distance (km) between the source and receiver related to the data
# -------------- using common source differential traveltime data --------------
cs_dif_time:
use_cs_time: false # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
residual_weight: [1, 3, 1, 0.1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
azimuthal_weight: [15, 30, 1, 0.1] # XXX is the azimuth difference between two separate stations related to the common source.
# -------------- using common receiver differential traveltime data --------------
cr_dif_time:
use_cr_time: false # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
residual_weight: [1, 3, 1, 0.1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
azimuthal_weight: [15, 30, 1, 0.1] # XXX is the azimuth difference between two separate sources related to the common receiver.
# -------------- global weight of different types of data (to balance the weight of different data) --------------
global_weight:
balance_data_weight: true # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
abs_time_weight: 1 # weight of absolute traveltime data after balance, default: 1.0
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data after balance, default: 1.0
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data after balance, default: 1.0
teleseismic_weight: 1 # weight of teleseismic data after balance, default: 1.0 (exclude in this version)
# -------------- inversion parameters --------------
update_slowness : true # update slowness (velocity) or not. default: true
update_azi_ani : true # update azimuthal anisotropy (xi, eta) or not. default: false
# -------------- for teleseismic inversion (under development) --------------
# depth_taper : [d1,d2] means:
# if XXX < d1, kernel <- kernel * 0.0
# if d1 <= XXX < d2, kernel <- kernel * (XXX-d1)/(d2-d1), (linear interpolation)
# if d2 <= XXX , kernel <- kernel * 1.0
# You can easily set d1 = -200, d1 = -100 to remove this taper.
depth_taper : [-200, -100]
#################################################
# relocation parameters setting #
#################################################
relocation: # update earthquake hypocenter and origin time (when run_mode : 2 and 3)
min_Ndata: 4 # if the number of data of the earthquake is less than <min_Ndata>, the earthquake will not be relocated. defaut value: 4
# relocation_strategy
step_length : 0.01 # initial step length of relocation perturbation. 0.01 means maximum 1% perturbation for each iteration.
step_length_decay : 0.9 # if objective function increase, step size -> step length * step_length_decay. default: 0.9
rescaling_dep_lat_lon_ortime : [10, 10, 10, 1] # The perturbation is related to <rescaling_dep_lat_lon_ortime>. Unit: km,km,km,second
max_change_dep_lat_lon_ortime : [5, 5, 5, 0.5] # the change of dep,lat,lon,ortime do not exceed max_change. Unit: km,km,km,second
max_iterations : 100 # maximum number of iterations for relocation
tol_gradient : 0.0001 # if the norm of gradient is smaller than the tolerance, the iteration of relocation terminates
# -------------- using absolute traveltime data --------------
abs_time:
use_abs_time : true # 'yes' for using absolute traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
residual_weight : [1, 3, 1, 0.1] # XXX is the absolute traveltime residual (second) = abs(t^{obs}_{n,i} - t^{syn}_{n,j})
distance_weight : [50, 150, 1, 0.1] # XXX is epicenter distance (km) between the source and receiver related to the data
# -------------- using common source differential traveltime data --------------
cs_dif_time:
use_cs_time : false # 'yes' for using common source differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
residual_weight : [1, 3, 1, 1] # XXX is the common source differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{n,j} - t^{syn}_{n,i} + t^{syn}_{n,j}).
azimuthal_weight : [100, 200, 1, 1] # XXX is the azimuth difference between two separate stations related to the common source.
# -------------- using common receiver differential traveltime data --------------
cr_dif_time:
use_cr_time : true # 'yes' for using common receiver differential traveltime data to update ortime and location; 'no' for not using (no need to set parameters in this section)
residual_weight : [1, 3, 1, 0.1] # XXX is the common receiver differential traveltime residual (second) = abs(t^{obs}_{n,i} - t^{obs}_{m,i} - t^{syn}_{n,i} + t^{syn}_{m,i})
azimuthal_weight : [10, 30, 1, 0.1] # XXX is the azimuth difference between two separate sources related to the common receiver.
# -------------- global weight of different types of data (to balance the weight of different data) --------------
global_weight:
balance_data_weight: false # yes: over the total weight of the each type of the data. no: use original weight (below weight for each type of data needs to be set)
abs_time_local_weight: 1 # weight of absolute traveltime data for relocation after balance, default: 1.0
cs_dif_time_local_weight: 1 # weight of common source differential traveltime data for relocation after balance, default: 1.0
cr_dif_time_local_weight: 1 # weight of common receiver differential traveltime data for relocation after balance, default: 1.0
####################################################################
# inversion strategy for tomography and relocation #
####################################################################
inversion_strategy: # update model parameters and earthquake hypocenter iteratively (when run_mode : 3)
inv_mode : 0 # 0 for update model parameters and relocation iteratively. 1 for update model parameters and relocation simultaneously.
# for inv_mode : 0, parameters below are required
inv_mode_0: # update model for <model_update_N_iter> steps, then update location for <relocation_N_iter> steps, and repeat the process for <max_loop> loops.
model_update_N_iter : 1
relocation_N_iter : 1
max_loop : 10
# for inv_mode : 1, parameters below are required
inv_mode_1: # update model and location simultaneously for <max_loop> loops.
max_loop : 10
# keep these setting unchanged, unless you are familiar with the eikonal solver in this code
calculation:
convergence_tolerance: 0.0001 # threshold value for checking the convergence for each forward/adjoint run
max_iterations: 500 # number of maximum iteration for each forward/adjoint run
stencil_order: 1 # order of stencil, 1 or 3
stencil_type: 1 # 0: , 1: first-order upwind scheme (only sweep_type 0 is supported)
sweep_type: 1 # 0: legacy, 1: cuthill-mckee with shm parallelization

View File

@@ -0,0 +1,188 @@
version: 3
#################################################
# computational domian #
#################################################
domain:
min_max_dep: [-10.0, 10.0] # depth in km
min_max_lat: [37.7, 42.3] # latitude in degree
min_max_lon: [22.7, 27.3] # longitude in degree
n_rtp: [10, 50, 50] # number of nodes
source:
src_rec_file: OUTPUT_FILES/src_rec_file_forward.dat # source receiver file (if found, src_dep_lat_lon is ignored)
swap_src_rec: true # swap source and receiver (1: yes, 0: no)
model:
init_model_path: ./test_model_init.h5 # path to initial model file (ignored if init_model_type is '1d_*')
parallel: # parameters for parallel computation
n_sims: 1 # number of simultaneous run
ndiv_rtp: [1, 1, 1] # number of subdomains
nproc_sub: 2 # number of subprocess used for each subdomain
output_setting:
output_dir: ./OUTPUT_FILES/ # path to output director (default is ./OUTPUT_FILES/)
output_source_field: false # output the calculated field of all sources
output_model_dat: false # output model_parameters_inv_0000.dat or not.
output_final_model: true # output merged final model or not.
output_in_process: true # output model at each inv iteration or not.
single_precision_output: false # output results in single precision or not.
verbose_output_level: 0 # output internal parameters, if 0, only model parameters are out. Higher level, more internal parameters are output. default: 0
output_file_format: 0 # in/output file format, if 0: HDF5, if 1: ASCII
#################################################
# inversion or forward modeling #
#################################################
# run mode
# 0 for forward simulation only,
# 1 for inversion
# 2 for earthquake relocation
# 3 for inversion+earthquake relocation
run_mode: 1
###################################################
# model update parameters setting #
###################################################
model_update: # update model parameters (when run_mode : 1 and 3)
max_iterations: 20 # maximum number of inversion iterations
optim_method: 1 # optimization method. 0 : grad_descent, 1 : halve-stepping, 2 : lbfgs (EXPERIMENTAL)
# common parameters for all optim methods
step_length: 0.03 # step length of model perturbation at each iteration. 0.01 means maximum 1% perturbation for each iteration.
# parameters for optim_method 0 (grad_descent)
optim_method_0:
step_length_decay: 0.7 # if objective function increase, step size -> step length * step_length_decay. default: 0.9
step_length_sc: 0.001 # ... # use it also ?
# parameters for optim_method 1 (halve-stepping) or 2 (lbfgs)
optim_method_1_2:
max_sub_iterations: 10 # maximum number of each sub-iteration
regularization_weight: 100 # weight value for regularization (lbfgs mode only)
# smoothing
smoothing:
smooth_method: 0 # 0: multiparametrization, 1: laplacian smoothing (EXPERIMENTAL)
l_smooth_rtp: [1, 1, 1] # smoothing coefficients for laplacian smoothing
# parameters for smooth method 0 (multigrid model parametrization)
n_inversion_grid: 5 # number of inversion grid sets
# inversion grid type
type_invgrid_dep: 1 # 0: uniform inversion grid, 1: flexible grid
type_invgrid_lat: 0 # 0: uniform inversion grid, 1: flexible grid
type_invgrid_lon: 0 # 0: uniform inversion grid, 1: flexible grid
# settings for uniform inversion grid (if type_*_inv : 0)
n_inv_dep_lat_lon: [5, 10, 10] # number of the base inversion grid points (ignored if type_*_inv : 1)
min_max_dep_inv: [-10.0, 10.0] # depth in km (Radius of the earth is defined in config.h/R_earth) (ignored if type_dep_inv : 1)
min_max_lat_inv: [37.7, 42.3] # latitude in degree
min_max_lon_inv: [22.7, 27.3] # longitude in degree
# settings for flexible inversion grid (if type_*_inv : 1)
dep_inv: [-15, -10, -5, 0, 5, 10, 15] # depth in km (Radius of the earth is defined in config.h/R_earth)
lat_inv: [] # latitude in degree (ignored if type_lat_inv : 0)
lon_inv: [] # longitude in degree (ignored if type_lon_inv : 0)
# path to station correction file
use_sta_correction: false
sta_correction_file: dummy_sta_correction_file # station correction file path
# -------------- using absolute traveltime data --------------
abs_time:
use_abs_time: true # 'true' for using absolute traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
residual_weight: [1.0, 3.0, 1.0, 0.1] # weight (wt) of residual. wt = residual_weight[2] for res < residual_weight[0]. wt = residual_weight[3] for res > residual_weight[1], and linear weight in between.
distance_weight: [50.0, 150.0, 1.0, 0.1] # weight of epicenter distance. wt = distance_weight[2] for dis < distance_weight[0]. wt = distance_weight[3] for dis > distance_weight[1], and linear weight in between.
# -------------- using common source differential traveltime data --------------
cs_dif_time:
use_cs_time: true # 'true' for using common source differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
residual_weight: [1.0, 3.0, 1.0, 0.1] # weight (wt) of residual.
azimuthal_weight: [15.0, 30.0, 1.0, 0.1] # weight of azimuth between two stations.
# -------------- using common receiver differential traveltime data --------------
cr_dif_time:
use_cr_time: true # 'true' for using common receiver differential traveltime data to update model parameters; 'false' for not using (no need to set parameters in this section)
residual_weight: [1.0, 3.0, 1.0, 0.1] # weight (wt) of residual.
azimuthal_weight: [15.0, 30.0, 1.0, 0.1] # weight of azimuth between two earthquakes.
# -------------- global weight of different types of data (to balance the weight of different data) --------------
global_weight:
balance_data_weight: true # yes: over the total weight of the each type of the data. the obj of different data means the average data misfit; no: use original weight (below weight for each type of data needs to be set)
abs_time_weight: 1.0 # weight of absolute traveltime data, default: 1.0
cs_dif_time_local_weight: 1.0 # weight of common source differential traveltime data, default: 1.0
cr_dif_time_local_weight: 1.0 # weight of common receiver differential traveltime data, default: 1.0
teleseismic_weight: 1.0 # weight of teleseismic data, default: 1.0 (exclude in this version)
# -------------- inversion parameters (exclude in this version) --------------
update_slowness: true # update slowness (velocity) or not. default: true
update_azi_ani: false # update azimuthal anisotropy (xi, eta) or not. default: false
update_rad_ani: false # update radial anisotropy (in future) or not. default: false
# -------------- for teleseismic inversion (exclude in this version) --------------
depth_taper: [-200.0, -100.0] # kernel weight : depth. --> 0: -inf ~ taper[0]; 0 ~ 1 : taper[0] ~ taper[1]; 1 : taper[1] ~ inf
#################################################
# relocation parameters setting #
#################################################
relocation: # update earthquake hypocenter and origin time (when run_mode : 1)
# relocation_strategy
step_length: 0.01 # step length of relocation perturbation at each iteration. 0.01 means maximum 1% perturbation for each iteration.
step_length_decay: 0.9 # if objective function increase, step size -> step length * step_length_decay. default: 0.9
rescaling_dep_lat_lon_ortime: [10.0, 10.0, 10.0, 1.0] # The perturbation is related to <rescaling_dep_lat_lon_ortime>. Unit: km,km,km,second
max_change_dep_lat_lon_ortime: [5.0, 5.0, 5.0, 0.5] # the change of dep,lat,lon,ortime do not exceed max_change. Unit: km,km,km,second
max_iterations: 100 # maximum number of iterations for relocation
tol_gradient: 0.0001 # threshold value for checking the convergence for each iteration
# params keeped for current version of relocation but may not be required
ortime_local_search: true # true: do local search for origin time; false: do not do local search for origin time
ref_ortime_change: 0.5 # reference value for origin time change (unit: second). If the change of origin time is larger than ref_ortime_change, do local search for origin time.
step_length_ortime_rescale: 0.1 # step length for rescaling origin time
# more option for using different types of data is under development (following)
# -------------- using absolute traveltime data --------------
abs_time:
use_abs_time: yes # 'yes' for using absolute traveltime data to update model parameters; 'no' for not using (no need to set parameters in this section)
residual_weight: [1.0, 3.0, 1.0, 0.1] # weight (wt) of residual. wt = residual_weight[2] for res < residual_weight[0]. wt = residual_weight[3] for res > residual_weight[1], and linear weight in between.
distance_weight: [50.0, 150.0, 1.0, 0.1] # weight of epicenter distance. wt = distance_weight[2] for dis < distance_weight[0]. wt = distance_weight[3] for dis > distance_weight[1], and linear weight in between.
# -------------- using common receiver differential traveltime data --------------
cr_dif_time:
use_cr_time: true # 'yes' for using common receiver differential traveltime data to update model parameters; 'no' for not using (no need to set parameters in this section)
residual_weight: [1.0, 3.0, 1.0, 0.1] # weight (wt) of residual.
azimuthal_weight: [10.0, 30.0, 1.0, 0.1] # weight of azimuth (deg.) between two earthquakes.
####################################################################
# inversion strategy for tomography and relocation #
####################################################################
inversion_strategy: # update model parameters and earthquake hypocenter iteratively (when run_mode : 3)
inv_mode: 0 # 0 for update model parameters and relocation iteratively. (other options for future work)
# for inv_mode : 0, parameters below are required
inv_mode_0: # Fristly, do relocation; Subsequently, do relocation every N steps; Finally, do relocation
relocation_first: true # true: do relocation first; false: do not relocation first. default: true
relocation_first_iterations: 10 # maximum number of iterations for relocation in the beginning. default: 10
relocation_every_N_steps: 5 # subsequently, do relocation every N steps of updating model parameters. The iteration of relocation follows <max_iterations> in Section <relocation>
relocation_final: true # true: do relocation finally; false: do not relocation finally. default: true
relocation_final_iterations: 10 # maximum number of iterations for relocation in the beginning. default: 10
# --- parameters for core solver ---------------------------------------------------------
# --- please do not change the following parameters unless you know what you are doing ---
########################################################################
# Scheme of Eikonal solver (fast sweeping method) #
########################################################################
calculation:
convergence_tolerance: 1e-4
max_iterations: 200
stencil_order: 3 # 1 or 3
sweep_type: 1 # 0: legacy, 1: cuthill-mckee with shm parallelization

View File

@@ -0,0 +1,57 @@
version: 3
#################################################
# computational domian #
#################################################
domain:
min_max_dep: [-10.0, 10.0] # depth in km
min_max_lat: [37.7, 42.3] # latitude in degree
min_max_lon: [22.7, 27.3] # longitude in degree
n_rtp: [10, 50, 50] # number of nodes
source:
src_rec_file: src_rec_test.dat # source receiver file (if found, src_dep_lat_lon is ignored)
swap_src_rec: true # swap source and receiver (1: yes, 0: no)
model:
init_model_path: ./test_model_true.h5 # path to initial model file (ignored if init_model_type is '1d_*')
parallel: # parameters for parallel computation
n_sims: 1 # number of simultaneous run
ndiv_rtp: [1, 1, 1] # number of subdomains
nproc_sub: 1 # number of subprocess used for each subdomain
output_setting:
output_dir: ./OUTPUT_FILES/ # path to output director (default is ./OUTPUT_FILES/)
output_source_field: true # output the calculated field of all sources
output_model_dat: false # output model_parameters_inv_0000.dat or not.
output_final_model: true # output merged final model or not.
output_in_process: true # output model at each inv iteration or not.
single_precision_output: false # output results in single precision or not.
verbose_output_level: 0 # output internal parameters, if 0, only model parameters are out. Higher level, more internal parameters are output. default: 0
output_file_format: 0 # in/output file format, if 0: HDF5, if 1: ASCII
#################################################
# inversion or forward modeling #
#################################################
# run mode
# 0 for forward simulation only,
# 1 for inversion
# 2 for earthquake relocation
# 3 for inversion+earthquake relocation
run_mode: 0
# --- parameters for core solver ---------------------------------------------------------
# --- please do not change the following parameters unless you know what you are doing ---
########################################################################
# Scheme of Eikonal solver (fast sweeping method) #
########################################################################
calculation:
convergence_tolerance: 1e-4
max_iterations: 500
stencil_order: 1 # 1 or 3
stencil_type : 1 # 0: , 1: first-order upwind scheme (only sweep_type 0 is supported)
sweep_type: 1 # 0: legacy, 1: cuthill-mckee with shm parallelization

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,240 @@
# %% [markdown]
# # notebook for create init and true test model
# %%
import numpy as np
import math
# grid
R_earth = 6371.0
rr1=6361
rr2=6381
tt1=(38.0-0.3)/180*math.pi
tt2=(42.0+0.3)/180*math.pi
pp1=(23.0-0.3)/180*math.pi
pp2=(27.0+0.3)/180*math.pi
n_rtp = [10,50,50]
dr = (rr2-rr1)/(n_rtp[0]-1)
dt = (tt2-tt1)/(n_rtp[1]-1)
dp = (pp2-pp1)/(n_rtp[2]-1)
rr = np.array([rr1 + x*dr for x in range(n_rtp[0])])
tt = np.array([tt1 + x*dt for x in range(n_rtp[1])])
pp = np.array([pp1 + x*dp for x in range(n_rtp[2])])
# initial model
gamma = 0.0
s0 = 1.0/6.0
slow_p=0.06
ani_p=0.04
eta_init = np.zeros(n_rtp)
xi_init = np.zeros(n_rtp)
zeta_init = np.zeros(n_rtp)
fun_init = np.zeros(n_rtp)
vel_init = np.zeros(n_rtp)
# true model
eta_true = np.zeros(n_rtp)
xi_true = np.zeros(n_rtp)
zeta_true = np.zeros(n_rtp)
fun_true = np.zeros(n_rtp)
vel_true = np.zeros(n_rtp)
c=0
for ir in range(n_rtp[0]):
for it in range(n_rtp[1]):
for ip in range(n_rtp[2]):
# already initialized above
#eta_init[ir,it,ip] = 0.0
#xi_init[ir,it,ip] = 0.0
zeta_init[ir,it,ip] = gamma*math.sqrt(eta_init[ir,it,ip]**2 + xi_init[ir,it,ip]**2)
fun_init[ir,it,ip] = s0
vel_init[ir,it,ip] = 1.0/s0
# true model
if (tt[it] >= 38.0/180.0*math.pi and tt[it] <= 42.0/180.0*math.pi \
and pp[ip] >= 23.0/180.0*math.pi and pp[ip] <= 27.0/180.0*math.pi):
c+=1
sigma = math.sin(2.0*math.pi*(tt[it]-38.0/180.0*math.pi)/(4.0/180.0*math.pi))*math.sin(2.0*math.pi*(pp[ip]-23.0/180.0*math.pi)/(4.0/180.0*math.pi))
else:
sigma = 0.0
if sigma < 0:
psi = 60.0/180.0*math.pi
elif sigma > 0:
psi = 120.0/180.0*math.pi
else:
psi = 0.0
eta_true[ir,it,ip] = ani_p*abs(sigma)*math.sin(2.0*psi)
xi_true[ir,it,ip] = ani_p*abs(sigma)*math.cos(2.0*psi)
zeta_true[ir,it,ip] = gamma*math.sqrt(eta_true[ir,it,ip]**2 + xi_true[ir,it,ip]**2)
fun_true[ir,it,ip] = s0/(1.0+sigma*slow_p)
vel_true[ir,it,ip] = 1.0/fun_true[ir,it,ip]
#r_earth = 6378.1370
print("depminmax {} {}".format(R_earth-rr1,R_earth-rr2))
print(c)
# %%
# write out in hdf5 format
import h5py
fout_init = h5py.File('test_model_init.h5', 'w')
fout_true = h5py.File('test_model_true.h5', 'w')
# write out the arrays eta_init, xi_init, zeta_init, fun_init, a_init, b_init, c_init, f_init
fout_init.create_dataset('eta', data=eta_init)
fout_init.create_dataset('xi', data=xi_init)
fout_init.create_dataset('zeta', data=zeta_init)
fout_init.create_dataset('vel', data=vel_init)
# writeout the arrays eta_true, xi_true, zeta_true, fun_true, a_true, b_true, c_true, f_true
fout_true.create_dataset('eta', data=eta_true)
fout_true.create_dataset('xi', data=xi_true)
fout_true.create_dataset('zeta', data=zeta_true)
fout_true.create_dataset('vel', data=vel_true)
fout_init.close()
fout_true.close()
# %% [markdown]
# # prepare src station file
#
# The following code creates a src_rec_file for the inversion, which describes the source and receiver positions and arrival times.
# Format is as follows:
#
# ```
# 26 1992 1 1 2 43 56.900 1.8000 98.9000 137.00 2.80 8 305644 <- src  : id_src year month day hour min sec lat lon dep_km mag num_recs id_event
# 26 1 PCBI 1.8900 98.9253 1000.0000 P 10.40 18.000 <- arrival : id_src id_rec name_rec lat lon elevation_m phase epicentral_distance_km arrival_time_sec
# 26 2 MRPI 1.6125 99.3172 1100.0000 P 50.84 19.400
# 26 3 HUTI 2.3153 98.9711 1600.0000 P 57.84 19.200
# ....
#
# ```
# %%
import random
random.seed(1145141919810)
# dummys
year_dummy = 1998
month_dummy = 1
day_dummy = 1
hour_dummy = 0
minute_dummy = 0
second_dummy = 0
mag_dummy = 3.0
id_dummy = 1000
st_name_dummy = 'AAAA'
phase_dummy = 'P'
arriv_t_dummy = 0.0
weight_dummy = 0.444
tt1deg = tt1 * 180.0/math.pi
tt2deg = tt2 * 180.0/math.pi
pp1deg = pp1 * 180.0/math.pi
pp2deg = pp2 * 180.0/math.pi
n_srcs = [10,20,20]
#n_srcs = [2,1,1]
n_src = n_srcs[0]*n_srcs[1]*n_srcs[2]
n_rec = [30 for x in range(n_src)]
lines = []
nij_rec = math.sqrt(n_rec[0])
pos_src=[]
pos_rec=[]
# create receiver coordinates
elev_recs=[]
lon_recs=[]
lat_recs=[]
rec_names=[]
for i in range(n_rec[0]):
#elev_recs.append(random.uniform(-100.0,-100.0)) # elevation in m
#elev_recs.append(0) # elevation in m
#lon_recs .append(random.uniform(pp1deg*1.1,pp2deg*0.9))
#lat_recs .append(random.uniform(tt1deg*1.1,tt2deg*0.9))
rec_names.append(i)
# regularly
elev_recs.append(0.0)
tmp_ilon = i%nij_rec
tmp_ilat = int(i/nij_rec)
lon_recs.append(pp1deg + tmp_ilon*(pp2deg-pp1deg)/nij_rec)
lat_recs.append(tt1deg + tmp_ilat*(tt2deg-tt1deg)/nij_rec)
# create source coordinates
for ir in range(n_srcs[0]):
for it in range(n_srcs[1]):
for ip in range(n_srcs[2]):
i_src = ir*n_srcs[1]*n_srcs[2] + it*n_srcs[2] + ip
# define one point in the domain (rr1 bottom, rr2 top)
# random
#dep = random.uniform((R_earth-rr1)*0.5,(R_earth-rr1)*0.98)
#lon = random.uniform(pp1deg,pp2deg)
#lat = random.uniform(tt1deg,tt2deg)
# regular
dep = (R_earth-rr1)/n_srcs[0]*ir
lon = pp1deg + ip*(pp2deg-pp1deg)/n_srcs[2]
lat = tt1deg + it*(tt2deg-tt1deg)/n_srcs[1]
# put independent name for each source
id_dummy = "src_"+str(i_src)
src = [i_src, year_dummy, month_dummy, day_dummy, hour_dummy, minute_dummy, second_dummy, lat, lon, dep, mag_dummy, n_rec[i_src], id_dummy, weight_dummy]
lines.append(src)
pos_src.append([lon,lat,dep])
# create dummy station
for i_rec in range(n_rec[i_src]):
elev_rec = elev_recs[i_rec]
lon_rec = lon_recs[i_rec]
lat_rec = lat_recs[i_rec]
st_name_dummy = "rec_"+str(rec_names[i_rec])
rec = [i_src, i_rec, st_name_dummy, lat_rec, lon_rec, elev_rec, phase_dummy, arriv_t_dummy, weight_dummy]
lines.append(rec)
pos_rec.append([lon_rec,lat_rec,elev_rec])
# write out ev_arrivals file
fname = 'src_rec_test.dat'
with open(fname, 'w') as f:
for line in lines:
for elem in line:
f.write('{} '.format(elem))
f.write('\n')
# # %%
# # draw src and rec positions
# import matplotlib.pyplot as plt
# for i_src in range(n_src):
# plt.scatter(pos_src[i_src][1],pos_src[i_src][0],c='r',marker='o')
# # %%
# # plot receivers
# for i_rec in range(n_rec[0]):
# plt.scatter(pos_rec[i_rec][1],pos_rec[i_rec][0],c='b',marker='o')

View File

@@ -0,0 +1,36 @@
#!/bin/bash
python make_test_model.py
# get number of sweep parallel processes from input variable (default 1)
nproc_sweep=${1:-1}
# get number of processes for domain decomposition
nproc_dd=${2:-1}
# calculate the total number of processes
nproc_total=$((nproc_sweep*nproc_dd*nproc_dd*nproc_dd))
# echo the number of processes
echo "Number of sweep parallel processes: $nproc_sweep"
echo "Number of processes for domain decomposition: $nproc_dd"
echo "Total number of processes: $nproc_total"
# modify the input_params_pre.yml file
# nproc_sub: (integer) # number of processors for sweep parallelization (parallel the fast sweep method)
pta setpar input_params_pre.yml parallel.nproc_sub ${nproc_sweep}
# ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
pta setpar input_params_pre.yml parallel.ndiv_rtp ${nproc_dd},${nproc_dd},${nproc_dd}
# nproc_sub: (integer) # number of processors for sweep parallelization (parallel the fast sweep method)
pta setpar input_params.yml parallel.nproc_sub ${nproc_sweep}
# ndiv_rtp: [1, 1, 1] # number of subdivision on each direction (parallel the computional domain)
pta setpar input_params.yml parallel.ndiv_rtp ${nproc_dd},${nproc_dd},${nproc_dd}
# run for preparing true travel times
mpirun --oversubscribe -n $nproc_total ../../build/bin/TOMOATT -i input_params_pre.yml
# run for inversion
mpirun --oversubscribe -n $nproc_total ../../build/bin/TOMOATT -i input_params.yml
#mpirun -n 8 ../../build/bin/TOMOATT -i input_params_flexible_inv_grid.yml
# then final model can be plot by e.g. check_3d_out.ipynb
#paraview OUTPUT_FILES/out_data_sim.xmf