Releases: emsig/emg3d
Max offset
- Survey:
add_noise
takes new amax_offset
argument; receivers
responses at offsets greater than maximum offset are set to NaN (also
available through the CLI).
Anisotropic gradient
- Simulation:
gradient
,jvec
, andjtvec
new support triaxial
anisotropy (also through the CLI). As a consequence,gradient
and
jtvec
return an ndarray of shape(nx, ny, nz)
(isotropic) or
({2;3}, nx, ny, nz)
(VTI/HTI; triaxial), andjvec
expects an ndarray
of shape(nx, ny, nz)
(isotropic) or({1;2;3}, nx, ny, nz)
(isotropic; VTI/HTI; triaxial).
Meshing: center on edge
-
Meshes:
construct_mesh
andorigin_and_widths
take a new variable
center_on_edge
: IfTrue
, the center is put on an edge, if
False
, it is put at the cell center. Status quo isTrue
, but the
default will change toFalse
in v1.7.0. If not set, it will
currently raise a FutureWarning making the user aware of the change.
Settingcenter_on_edge
explicitly will suppress the warning.- Constructed grids through
construct_mesh
andorigin_and_widths
with
a definedseasurface
might slightly change due to some improvements and
refactoring in the course of the above changes to the center. The changes
should not be severe.
-
Simulation:
gradient
: Changed slightly to use the proper adjoint (changed only if
the computational grids differ from the inversion grid; requires
discretize
).jvec
: Adjusted to work for any mapping, not only conductivity, and also
with adaptive gridding. It expects new a Fortran-ordered vector with the
shape of the model (or a vector of that size).
Gently reminder that the functionsgradient
,jvec
, andjtvec
are still considered experimental, and might change.- New optional keyword
tqdm_opts
. WithFalse
you can switch off the
progress bars. Alternatively one can provide a dict, which is forwarded
totqdm
.
-
CLI:
- Expose
mean_noise
andntype
, in addition tomin_offset
, to the
CLI (for adding noise); alsoplain
(for solver), andcenter_on_edge
(for gridding options).
- Expose
Meshing: improve vector
-
Meshes: Non-backwards compatible changes in
construct_mesh
(origin_and_widths
;estimate_gridding_options
) when providing
vector
's (implemented non-backwards compatible as the old rules were not
intuitive nor logic; previous meshes can still be obtained, mostly, by
setting the parameters carefully).- Priority-order changed to
domain > distance > vector
(before it was
domain > vector > distance
). - A provided
vector
is new trimmed to the corresponding domain if it is
larger than a also provided domain (fromdomain
ordistance
);
trimmed at the first point where
vector <= domain[0]
,vector >= domain[1]
. - A
vector
can new also be smaller than the defined domain, and the
domain is then filled according to the normal rules; the last cell of
vector
in each direction is taken as starting width for the expansion.
- Priority-order changed to
-
Bugfixes and maintenance:
- Removed functions and modules that were deprecated in v1.2.1.
- Fixed kwargs-error when adding
add_noise
explicitly to
Simulation.compute()
. - Python 3.10 added to tests; Python 3.7 tests reduced to minimum.
Bugfix CLI-select
CLI: Add remove_empty
to parameter file; set to False
by default (pre-v1.3.1 behaviour, and therefore backwards compatible).
Select: remove empty pairs
-
Survey.select
removes now empty source-receiver-frequency pairs. If you
want the old behaviour setremove_empty=False
. -
Maintenance: Added a cron to GHA; 20th of every month at 14:14.
File-based computations
-
electrodes
:- New source
TxMagneticPoint
(requiresdiscretize
; mainly used as
adjoint source for magnetic receivers; does not work in the presence of
magnetic permeabilities in the vicinity of the source). - Both receivers (
Rx{Electric;Magnetic}Point
) can now produce their
proper adjoint (thanks to @sgkang!).
- New source
-
Changes in Simulation and parallel execution.
- Parallel computation is not sharing the simulation any longer.
- Parallel computation can new be done both file-based or all in memory.
The new possibility for file-based computation should make it possible
to compute responses for any amount of source-frequency pairs. See
parameterfile_dir
in the Simulation class (or corresponding parameter
in the CLI parameter file). get_model
andget_hfield
are now done on the fly, they are not
stored in a dict;simulation._dict_model
and
simulation._dict_hfield
do not exist any longer.- New methods
jvec
(sensitivity times a vector) andjtvec
(sensitivity transpose times a vector). These methods are currently
experimental; documentation and examples are lacking behind.
-
Various small things:
- Models and Fields return itself (not a copy) when the grid provided to
interpolate_to_grid
is the same as the current one.
- Models and Fields return itself (not a copy) when the grid provided to
Remove optimize & bug fix
-
io
: Adjustment so that hdf5 tracks the order of dicts. -
simulations
:-
Adjust printing: correct simulation results for adjusted solver printing
levels; default solver verbosity is new 1;log
can now be
overwritten insolver_opts
(mainly for debugging). -
Functions moved out of
simulations
:expand_grid_model
moved to
models
andestimate_gridding_options
tomeshes
. The
availability of these functions throughsimulations
will be removed in
v1.4.0.
-
-
optimize
: the module is deprecated and will be removed in v1.4.0. The two
functionsoptimize.{misfit;gradient}
are embedded directly in
Simulation.{misfit;gradient}
.
White noise
-
CLI:
- New parameters
save
andload
to save and load an entire simulation.
In the parameter file, they are under[files]
; on the command line,
they are available as--save
and--load
; they are followed by the
filename including its path and suffix. (In turn, the parameter
store_simulation
was removed.)
- New parameters
-
simulations.Simulation
:- Warns if the gradient is called, but
receiver_interpolation
is not
'linear'
. - Slightly changed the added noise in
compute(observed=True)
: It uses new
thesurvey.add_noise
attribute. There is new a flag to set if noise
should be added or not (add_noise
), and if the amplitudes should be
chopped or not (min_amplitude
). Also note that the added noise is new
white noise with constant amplitude and random phase.
- Warns if the gradient is called, but
-
surveys
:-
New function
random_noise
, which can be used to create random noise in
different ways. The default noise is white noise, hence constant amplitude
with random phase. (This is different to before, where random Gaussian
noise was added separately to the real and imaginary part.) For the random
noise it requires new at least NumPy 1.17.0. -
New attribute
Survey.add_noise
, which uses under the hood above
function. -
A
Survey
can new be instantiated without receivers by setting
receivers
toNone
. This is useful if one is only interested in
forward modelling the entire fields. In this case, the related data object
and the noise floor and relative error have no meaning. Also, in
conjunction with a Simulation, the misfit and the gradient will be zero.
-
-
Various:
- All emg3d-warnings (not solver warnings) are now set to
'always'
, and
corresponding print statements were removed. - Simplified (unified)
_edge_curl_factor
(private fct).
- All emg3d-warnings (not solver warnings) are now set to
Adjoint-fix for electric receivers
This release contains, besides the usual small bugfixes, typos, and small
improvements, an important fix for optimize.gradient
. Keep in mind that
while the forward modelling is regarded as stable, the optimize
module is
still work in progress.
The fixes with regard to optimize.gradient
ensure that the gradient is
indeed using the proper adjoint to back-propagate the field. This is currently
only given for electric receivers, not yet for magnetic receivers. These
improvement happened mainly thanks to the help of Seogi (@sgkang).
The changes in more detail:
-
fields
:get_receiver
has a new keywordmethod
, which can be'cubic'
or
'linear'
; default is the former, which is the same behaviour as before.
However, if you want to compute the gradient, you should set it to
'linear'
in your Simulation parameters. Otherwise the adjoint-state
gradient will not exactly be the adjoint state.get_source_field
returns new the real-valued, frequency-independent
source vector iffrequency=None
.get_source_field
uses the adjoint of trilinear interpolation for point
sources (new). For dipoles and wires it the source is distributed onto the
cells as fraction of the source length (as before).
-
electrodes
: Re-introduced the point source asTxElectricPoint
. -
simulations.Simulation
:- New keyword
receiver_interpolation
, which corresponds to themethod
inget_receiver
(see above). Cubic is more precise. However, if you are
interested in the gradient, you need to choose linear interpolation at the
moment, as the point source is the adjoint of linear interpolation. To be
the proper adjoint for the gradient the receiver has to be interpolated
linearly too. - If
gridding
is'same'
or'input'
, it checks now if the provided
grid is a sensible grid for emg3d; if not, it throws a warning.
- New keyword
-
meshes
: New functioncheck_grid
to verify if a given grid is good for
emg3d. -
optimize.gradient
: Changed order when going from computational grid to
inversion grid. Changing the grids at the field stage (cubic interpolation)
seems to be better than changing at the cell-averaged stage::New: field_comp -> field_inv -> cells_inv Old: field_comp -> cells_comp -> cells_inv
-
cli
: Uses now by default linear receiver interpolation if the
gradient
is wanted (new), otherwise it uses cubic interpolation (as
before). The new keywordreceiver_interpolation
of the simulation can be
set in the parameter file, which overwrites the described default behaviour.