seisflows.solver.specfem
This Solver module is in charge of interacting with external numerical solvers such as SPECFEM (2D/3D/3D_GLOBE). This SPECFEM base class provides general functions that work with all versions of SPECFEM. Subclasses will provide additional capabilities unique to each version of SPECFEM.
Note
The Base class implementation is almost completely SPECFEM2D related. However, SPECFEM2D requires a few unique parameters that 3D/3D_GLOBE do not. Because of the inheritance architecture of SeisFlows, we do not want the 3D and 3D_GLOBE versions to inherit 2D-specific parameters, so we need this this more generalized SPECFEM base class.
- TODO
add in apply_hess functionality that was partially written in legacy code
move _initialize_adjoint_traces to workflow.migration
Add density scaling based on Vp?
Classes
Solver SPECFEM [Solver Base] |
Module Contents
- class seisflows.solver.specfem.Specfem(syn_data_format='ascii', materials='acoustic', update_density=False, nproc=1, ntask=1, attenuation=False, smooth_h=0.0, smooth_v=0.0, smooth_type='gaussian', components=None, source_prefix=None, mpiexec=None, workdir=os.getcwd(), path_solver=None, path_eval_grad=None, path_data=None, path_specfem_bin=None, path_specfem_data=None, path_model_init=None, path_model_true=None, path_output=None, **kwargs)
Solver SPECFEM [Solver Base]
Defines foundational structure for Specfem-based solver module. Generalized SPECFEM interface to manipulate SPECFEM2D/3D/3D_GLOBE w/ Python
Parameters
- type syn_data_format:
str
- param syn_data_format:
data format for reading synthetic traces into memory. Available: [‘SU’: seismic unix format, ‘ASCII’: human-readable ascii]
- type materials:
str or list
- param materials:
Material name used to define the model parameters that will be updated during an Inversion workflow. Available options (case-insensitive): - type: list (2D, 3D, 3D_GLOBE): User-defined list of lower-case
parameters (e.g., [‘vp’, ‘vs’] to mimic ‘ELASTIC’) NOTE: User is responsible for understanding if their chosen parameters are actually represented in SPECFEM, there are no guard rails here to protect incorrect parameter naming
ACOUSTIC (2D, 3D, 3D_GLOBE): vp
ELASTIC (2D, 3D, 3D_GLOBE): vp, vs
TRANSVERSE_ISOTROPIC (3D, 3D_GLOBE): vpv, vph, vsv, vsh, eta
2D_ANISOTROPIC (2D): c11 c13 c15 c33 c35 c55 c12 c23 c25 c22
ANISOTROPIC (3D, 3D_GLOBE): c_ij (21 parameter anisotropy)
- type update_density:
bool
- param update_density:
How to treat density during inversion. If True, updates density during inversion. If False, keeps it constant. TODO allow density scaling during an inversion
- type attenuation:
bool
- param attenuation:
How to treat attenuation during inversion. if True, turns on attenuation during forward simulations only. If False, attenuation is always set to False. Requires underlying attenution (Q_mu, Q_kappa) model
- type smooth_h:
float
- param smooth_h:
Gaussian half-width for horizontal smoothing in units of meters. If 0., no smoothing applied. Only applicable for workflows: [‘migration’, ‘inversion’], ignored for ‘forward’ workflow. SPECFEM3D_GLOBE only: if `smooth_type`==’laplacian’ then this is just the X and Y extent of the applied smoothing
- type smooth_v:
float
- param smooth_v:
Gaussian half-width for vertical smoothing in units of meters. Only applicable for workflows: [‘migration’, ‘inversion’], ignored for ‘forward’ workflow. SPECFEM3D_GLOBE only: if `smooth_type`==’laplacian’ then this is just the Z extent of the applied smoothing
- type smooth_type:
str
- param smooth_type:
choose how smoothing is performed for gradients. these are tied to the internal smoothing functions available, and only certain code flavors have certain smoothing functions available: - ‘gaussian’ [2D/3D/3D_GLOBE]: Default, convolve with a 3D gaussian,
slow and computationally intensive. Only option for 2D.
- ‘laplacian’ [3D_GLOBE]: RECOMMENDED FOR 3D_GLOBE. Average points
around vertex to smooth. Much faster than Gaussian.
- ‘pde’ [3D]: RECOMMENDED for 3D. Diffusion-based PDE smoothing.
Much faster than Gaussian. See SPECFEM3D PR#1725
- type components:
str
- param components:
components to search for synthetic data with. None by default which uses a wildcard when searching for synthetics. If provided, User only wants to use a subset of components generated by SPECFEM. In that case, components should be string of letters such as ‘ZN’ (for up and north components)
- type solver_io:
str
- param solver_io:
format of model/kernel/gradient files expected by the numerical solver. Available: [‘fortran_binary’: default .bin files]. TODO: [‘adios’: ADIOS formatted files]
- type source_prefix:
str
- param source_prefix:
prefix of source/event/earthquake files. If None, will attempt to guess based on the specific solver chosen.
- type mpiexec:
str
- param mpiexec:
MPI executable used to run parallel processes. Should also be defined for the system module
Paths
- type path_data:
str
- param path_data:
path to any externally stored waveform data required for data-synthetic comparison
- type path_specfem_bin:
str
- param path_specfem_bin:
path to SPECFEM bin/ directory which contains binary executables for running SPECFEM
- type path_specfem_data:
str
- param path_specfem_data:
path to SPECFEM DATA/ directory which must contain the CMTSOLUTION, STATIONS and Par_file files used for running SPECFEM
- syn_data_format = 'ascii'
- materials = 'acoustic'
- nproc = 1
- ntask = 1
- update_density = False
- attenuation = False
- smooth_h = 0.0
- smooth_v = 0.0
- smooth_type = 'gaussian'
- components = None
- source_prefix = 'SOURCE'
- prune_scratch = None
- path
- _parameters = []
- _mpiexec = None
- _source_names = None
- _ext = ''
- _available_model_types = ['gll']
- _available_materials = None
- _syn_available_data_formats = ['ASCII', 'SU']
- _required_binaries = ['xspecfem2D', 'xmeshfem2D', 'xcombine_sem']
- _acceptable_source_prefixes = ['SOURCE', 'FORCE', 'FORCESOLUTION']
- _fwd_simulation_executables = ['bin/xmeshfem2D', 'bin/xspecfem2D']
- _adj_simulation_executables = ['bin/xspecfem2D']
- _absorb_wildcard = 'absorb_*_*'
- _forward_array_wildcard = ''
- _regions = None
- _export_vtk = False
- check()
Checks parameter validity for SPECFEM input files and model parameters
- setup()
Prepares solver scratch directories for an impending workflow.
Sets up directory structure expected by SPECFEM and copies or generates seismic data to be inverted or migrated.
Exports INIT/STARTING and TRUE/TARGET models to disk (output/ dir.)
- check_model_values(path)
Convenience function to check parameter and model validity for chosen Solver model. Should be called by the Workflow module
- Parameters:
path (str) – path to model file(s) that should be in the format expected by the Model class (FORTRAN binary, ADIOS etc.)
- set_parameters(keys, vals, file, delim, **kwargs)
Public API that allows other modules modify solver-specific files with paths relative to the cwd attribute.
Primarily used to modify locations or force vector direction for the generation of different kernels in noise workflows.
Only works if file exists, otherwise raises FileNotFoundError Kwargs are passed to seisflows.tools.specfem.setpar()
- Parameters:
key (str) – case-insensitive key to match in par_file. must match EXACT
val (str) – value to OVERWRITE to the given key
- Raises:
FileNotFoundError – if file does not exist within the solver’s working directory
- property source_names
Returns list of source names which should be stored in PAR.SPECFEM_DATA Source names are expected to match the following wildcard, ‘PREFIX_*’ where PREFIX is something like ‘CMTSOLUTION’ or ‘FORCE’
Note
Dependent on environment variable ‘SEISFLOWS_TASKID’ which is assigned by system.run() to each individually running process.
- Return type:
list
- Returns:
list of source names
- property source_name
Returns name of source currently under consideration
Note
Dependent on environment variable ‘SEISFLOWS_TASKID’ which is assigned by system.run() to each individually running process.
- Return type:
str
- Returns:
given source name for given task id
- property cwd
Returns working directory currently in use by a running solver instance
Note
Dependent on environment variable ‘SEISFLOWS_TASKID’ which is assigned by system.run() to each individually running process.
- Return type:
str
- Returns:
current solver working directory
- data_wildcard(comp='?')
Returns a wildcard identifier for synthetic data based on SPECFEM2D file naming schema. Allows formatting dcomponent e.g., when called by solver.data_filenames.
Some example SPECFEM2D ASCII seismogram file names for reference: - AA.S000000.BXY.semd: Membrane wave displacement - AA.S000000.BXY.semp: Membrane wave pressure - AA.S000000.PRE.semp: P-SV pressure seismogram
Note
SPECFEM3D/3D_GLOBE versions must overwrite this function
- Parameters:
comp (str) – component formatter, defaults to wildcard ‘?’
- Return type:
str
- Returns:
wildcard identifier for channels
- model_wildcard(par='*', kernel=False)
Returns a wildcard identifier to search for models kernels generated by the solver. An example SPECFEM2D/3D kernel filename (in FORTRAN binary file format) is: ‘proc000001_rho_kernel.bin’ Whereas the corresponding model would be ‘proc000001_rho.bin’
Allows dynamically searching for specific files when renaming, moving or copying files. Also allows for different wildcard for 3D_GLOBE version
- Parameters:
par (str) – parameter formatter, defaults to wildcard ‘?’
kernel (bool) – wildcarding a kernel file. If True, adds the ‘kernel’ tag. If not, assuming we are wildcarding for a model file
- Return type:
str
- Returns:
wildcard identifier for channels
- data_filenames(choice='obs')
Returns the filenames of SPECFEM2D data, either by the requested components or by all available files in the directory.
Note
SPECFEM3D/3D_GLOBE versions must overwrite this function
Note
If the glob returns an empty list, this function exits the workflow because filenames should not be empty is they’re being queried
- Return type:
list
- Returns:
list of data filenames
- property model_databases
The location of model inputs and outputs as defined by SPECFEM2D. This is RELATIVE to a SPECFEM2D working directory.
Note
This path is SPECFEM version dependent so SPECFEM3D/3D_GLOBE versions must overwrite this function
- Return type:
str
- Returns:
path where SPECFEM2D database files are stored, relative to solver.cwd
- property model_files
Return a list of paths to model files that match the internal parameter list. Used to generate model vectors of the same length as gradients.
- Return type:
list
- Returns:
a list of full paths to model files that matches the internal list of solver parameters
- property kernel_databases
The location of kernel inputs and outputs as defined by SPECFEM2D This is RELATIVE to a SPECFEM2D working directory.
Note
This path is SPECFEM version dependent so SPECFEM3D/3D_GLOBE versions must overwrite this function
- Return type:
str
- Returns:
path where SPECFEM2D database files are stored, relative to solver.cwd
- forward_simulation(save_traces=False, export_traces=False, save_forward_arrays=False, flag_save_forward=True, **kwargs)
- Wrapper for SPECFEM binaries: ‘xmeshfem?D’ ‘xgenerate_databases’,
‘xspecfem?D’
Calls SPECFEM2D forward solver, exports solver outputs to traces dir
Note
SPECFEM3D/3D_GLOBE versions must overwrite this function
- Parameters:
save_traces (str) – move files from their native SPECFEM output location to another directory. This is used to move output waveforms to ‘traces/obs’ or ‘traces/syn’ so that SeisFlows knows where to look for them, and so that SPECFEM doesn’t overwrite existing files during subsequent forward simulations
export_traces (str) – export traces from the scratch directory to a more permanent storage location. i.e., copy files from their original location
save_forward_arrays (str) – relative path (relative to /scratch/solver/<source_name>/<model_database>) to move the forward arrays which are used for adjoint simulations. Mainly used for ambient noise adjoint tomography which requires multiple forward simulations prior to adjoint simulations, putting forward arrays at the risk of overwrite. Normal Users can leave this default.
flag_save_forward (bool) – whether to turn on the flag for saving the forward arrays which are used for adjoint simulations. Not required if only running forward simulations.
- adjoint_simulation(save_kernels=False, export_kernels=False, load_forward_arrays=False, del_loaded_forward_arrays=False, **kwargs)
Wrapper for SPECFEM binary ‘xspecfem?D’
Calls SPECFEM2D adjoint solver, creates the SEM folder with adjoint traces which is required by the adjoint solver. Renames kernels after they have been created from ‘alpha’ and ‘beta’ to ‘vp’ and ‘vs’, respectively.
Note
SPECFEM3D/3D_GLOBE versions must overwrite this function
- Parameters:
save_kernels (str) – move the kernels from their native SPECFEM output location to another path. This is used to move kernels to another SeisFlows scratch directory so that they are discoverable by other modules. The typical location they are moved to is path_eval_grad
export_kernels (str) – export/copy/save kernels from the scratch directory to a more permanent storage location. i.e., copy files from their original location. Note that kernel file sizes are LARGE, so exporting kernels can lead to massive storage requirements.
load_forward_arrays (str) – relative path (relative to solver.cwd) to load previously generated forward arrays which are used for adjoint simulations. Mainly used for ambient noise adjoint tomography. Will OVERWRITE any forward array files already located in the database directory.
del_loaded_forward_arrays (bool) – only used if load_forward_arrays is set. After adjoint simulation completes nominally, delete the forward arrays that were used to run the adjoint simulation to save space. Usually
- _rename_kernel_parameters()
Rename kernels to work w/ conflicting name conventions. - alpha -> vp - beta -> vs
Performed directly inside the directory so that rename won’t affect any strings in the full path. Deals with both SPECFEM3D and 3D_GLOBE. GLOBE version adds in the ‘reg?’ tag that needs to be considered.
Kept as a separate function so it can be called outside the adjoint simulation task for debugging purposes.
- combine(input_paths, output_path, parameters=None)
Wrapper for ‘xcombine_sem’. Sums kernels from individual source contributions to create gradient.
Note
The binary xcombine_sem simply sums matching databases
Note
It is ASSUMED that this function is being called by system.run(single=True) so that we can use the main solver directory to perform the kernel summation task
- Parameters:
input_paths (list) – list of paths to directories containing binary files to be combined
output_path (str) – path to export the outputs of xcombine_sem
parameters (list) – optional list of parameters, defaults to self._parameters
- smooth(input_path, output_path, parameters=None, span_h=None, span_v=None, use_gpu=False)
Wrapper for SPECFEM smoothing binaries: xsmooth_sem, xsmooth_sem_pde, xsmooth_laplacian_sem User chooses which underlying function they want with the smooth_type parameter
Note
It is ASSUMED that this function is being called by system.run(single=True) so that we can use the main solver directory to perform the kernel smooth task
- Parameters:
input_path (str) – path to data
output_path (str) – path to export the outputs of xcombine_sem
parameters (list) – optional list of parameters, defaults to self._parameters
span_h (float) – horizontal smoothing length in meters
span_v (float) – vertical smoothing length in meters
use_gpu (bool) – whether to use GPU acceleration for smoothing. Requires GPU compiled binaries and GPU compute node.
- _run_binary(executable, stdout='solver.log', with_mpi=True)
Calls MPI solver executable to run solver binaries, used by individual processes to run the solver on system. If the external solver returns a non-zero exit code (failure), this function will return a negative boolean.
Note
This function ASSUMES it is being run from a SPECFEM working directory, i.e., that the executables are located in ./bin/
Note
This is essentially an error-catching wrapper of subprocess.run()
- Parameters:
executable (str) – executable function to call. May or may not start E.g., acceptable calls for the solver would ‘./bin/xspecfem2D’. Also accepts additional command line arguments such as: ‘xcombine_sem alpha_kernel kernel_paths…’
stdout (str) – where to redirect stdout
with_mpi (bool) – If mpiexec is given, use MPI to run the executable. Some executables (e.g., combine_vol_data_vtk) must be run in serial so this flag allows them to turn off MPI running.
- Raises:
SystemExit – If external numerical solver return any failure code while running
- static _exc2log(exc)
Very simple conversion utility to get log file names based on binaries. e.g., binary ‘xspecfem2D’ will return ‘solver’. Helps keep log file naming consistent and generalizable
- TODO add a check here to see if the log file exists, and then use
number_fid to increment so that we keep all the output logs
- Parameters:
exc (str) – specfem executable, e.g., xspecfem2D, xgenerate_databases
- Return type:
str
- Returns:
logfile name that matches executable name
- import_model(path_model)
Copy files from given path_model into the current working directory model database. Used for grabbing starting models (e.g., MODEL_INIT) and models that have been perturbed by the optimization library.
- Parameters:
path_model (str) – path to an existing starting model
- _initialize_working_directories(max_workers=None)
Serial or parallel task used to initialize working directories for each of the available sources
- Parameters:
max_workers (int) – number of concurrent tasks to use when creating working directories. Defaults to using all available cores on the machine since this is a lightweight task
- _initialize_working_directory(cwd=None)
Creates scratch directory structure expected by SPECFEM (i.e., bin, DATA, OUTPUT_FILES). Copies executables (bin) and input data (DATA) directories, prepares simulation input files.
Each directory will act as completely independent Specfem working dir. This allows for embarrassing parallelization while avoiding the need for intra-directory communications, at the cost of temporary disk space.
Note
path to binary executables must be supplied by user as SeisFlows has no mechanism for automatically compiling from source code.
- Parameters:
cwd (str) – optional scratch working directory to intialize. If None, will set based on current running seisflows task (self.taskid)
- _export_starting_models(parameters=None)
Export the initial and target models to the SeisFlows output/ directory. These are not used for actual simulations, just to keep track of models that were used during the workflow.
- Parameters:
parameters (list) – list of parameters to export. If None, will default to self._parameters
- make_output_vtk_files(input_path, output_path=None, parameters=None, hi_res=False, tag=None, kernel=False)
A warpper on combine_vol_data_vtk() that automatically tries to generate .vtk files using the SPECFEM binary xcombine_vol_data_vtk, and rename the output files to not be so generic. Files will be stored in the output_path directory, and will be named based on the tag unless overwritten by the User.
- Parameters:
input_path (str) – path to database files to be summed.
output_path (strs) – path to export the outputs of the binary
parameters (list) – optional list of parameters, defaults to self._parameters if None provided (e.g., [‘vp’, ‘vs’])
tag (str) – optional tag to rename output vtk files. If not provided, will use the name of the directory holding the files
kernel (bool) – whether the files being converted are kernel files or model files. This changes the file naming convention
hi_res (bool) – Set the high resolution flag to 1 or True, which will generate .vtk files with data at EACH GLL point, rather than at each nodal vertex. These files are LARGE, and we discourage using `hi_res`==True unless you know you want these files.
- finalize()
General finalization procedures for SPECFEM-based solver activities