-
Notifications
You must be signed in to change notification settings - Fork 229
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Freesurface with subdomain (iso-acoustic) #1344
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1344 +/- ##
==========================================
- Coverage 86.69% 86.65% -0.05%
==========================================
Files 183 183
Lines 26254 26300 +46
Branches 3605 3613 +8
==========================================
+ Hits 22762 22790 +28
- Misses 3067 3083 +16
- Partials 425 427 +2
Continue to review full report at Codecov.
|
should we make a unit test with a mirror condition? this is friggin great! once we get to actually using devito the first thing we will need is this. |
z = model.grid.dimensions[-1] | ||
zfs = model.grid.subdomains['fsdomain'].dimensions[-1] | ||
|
||
funcs = retrieve_functions(rhs) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this whole function is OKish for this PR, but I feel the user will need something easier than this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I know, I have a TODO in it, this just for "it works" but could be done better at some point.
val = dampcoeff * (pos - sin(2*np.pi*pos)/(2*np.pi)) | ||
val = -val if abc_type == "mask" else val | ||
eqs += [Inc(damp.subs({d: dim_l}), val/d.spacing)] | ||
if not fs or d is not damp.dimensions[-1]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like this. This is a symptom that this code needs some refactoring to distinguish the fs vs no-fs cases
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I follow. This pads damp where it's define, which is every side, except the top for the free surface case. That's all that's needed and refactoring would probably not make it easier to follow IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I think I understand now...it's a bit contrieved the way it is ATM, IMHO
so what you mean is :
pad_dims = list(damp.dimensions)
if fs:
pad_dims.pop(-1)
for d in pad_dims:
<padding code, just as in master>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But you still have to pad half of the last dim, this would remove ABC at the bottom.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just fission the loop into two loops ? it would be much much clearer I feel
val = dampcoeff * (pos - sin(2*np.pi*pos)/(2*np.pi)) | ||
val = -val if abc_type == "mask" else val | ||
eqs += [Inc(damp.subs({d: dim_l}), val/d.spacing)] | ||
if not fs or d is not damp.dimensions[-1]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, I think I understand now...it's a bit contrieved the way it is ATM, IMHO
so what you mean is :
pad_dims = list(damp.dimensions)
if fs:
pad_dims.pop(-1)
for d in pad_dims:
<padding code, just as in master>
?
db669b1
to
2bf7992
Compare
parser = seismic_args(description) | ||
parser.add_argument('--noazimuth', dest='azi', default=False, action='store_true', | ||
help="Whether or not to use an azimuth angle") | ||
args = parser.parse_args() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
blank line below
|
||
# Preset parameters | ||
ndim = args.ndim | ||
shape = args.shape[:args.ndim] | ||
spacing = tuple(ndim * [10.0]) | ||
tn = 750. if ndim < 3 else 1250. | ||
tn = args.tn if args.tn > 0 else (750. if ndim < 3 else 1250.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm writing this here, but it applies to all our examples. It feels like that much of the preprocessing could be moved inside seismic_args
once and for all, instead of being repeated each time in the individual examples?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not necessarily for this PR (would be out of scope admittedly), but you know, just saying..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked into it, and it's not possible if we return the parser from seismic_args
. We either return the args
and put all the possible ones in seismic_args
ir we return the parser and this can only be done afer parse_args()
which is done here if we want these different cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I imagined... perhaps that's one reason to switch to click
-- in which case, we could provide callbacks to each argument! as I said, just food for thought...
Just starting to look through this now, but first comment is 'no tutorial notebook? 😲' 😛 |
|
||
# Add free surface | ||
if model.fs: | ||
eqns.append(freesurface(model, Eq(unext, eq_time))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing Eq(unext, eq_time)
and then splitting it up again in freesurface
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this apply the free surface to the equation directly
examples/seismic/model.py
Outdated
self.shape = shape | ||
self.space_order = space_order | ||
self.nbl = int(nbl) | ||
self.origin = tuple([dtype(o) for o in origin]) | ||
self.fs = fs | ||
if self.fs: | ||
warning("Freesurface is only supported for isotropic acoustic solver") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we not:
- Not have a warning if using iso-acoustic
- Throw a not implemented error if not using isco-acoustic
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can try, the model doesn't really know which physics it is at this point so would need to move it to each example. I can just remove it as would just be False
for all other examples
mapper = {} | ||
# Mirror negative indices | ||
# TODO: Make a proper "mirror_indices" tool function | ||
for f in funcs: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the TODO
- but if I'm reading this correctly it's messing with values in the halo to implement this atm? Is that something we really want to do? (Please correct me if I'm misunderstanding).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, or is the sponge still there and values are being manipulated in that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not touching the halo at all no. This is just turning any indices smaller than symbolic min into its mirror i.e u[x-1] => u[ abs(x-1)]. The halo is actually unnecessary then since nothing is ever accessed in it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, ok, I was initially thrown by the if ... < 0
. So you're creating a 'boundary layer' of length so
to mirror the values in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the top so
gridpoints are the layer in which indices are mirrored if negative. Ultimately (after some work) this would be basically autowrapping at the edge of any domain which would remove the need of a halo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And the boundary layer could also be completely removed by modifying the fd stencil appropriately -- easily doable for iso-acoustic, but probably too much pain to do nicely once this is generalized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And the boundary layer could also be completely removed by modifying the fd stencil appropriately
That'd be really ideal yes but not really easy on the symbolic side as now you would have a different stencil (coeffs and radius) per distance to the boundary so wouldn't really be doable with a subdomain that expects the same equation for all points in the domain. Even for iso-acoustic, it's fairly trivial to do it by hand but not as a generic symbolic rule (unless I missed something).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even for iso-acoustic, it's fairly trivial to do it by hand but not as a generic symbolic rule (unless I missed something).
For flat boundaries we can make use of custom FD coefficients to do it pretty easily.
Another comment is why is this being restricted to the 'left' of the last dimension? I suppose the argument would be that the |
Also, shouldn't we have a norm test for a run with an FS? |
I can add one to #1348 that adds lots of tests to the examples once this one is in. |
POC for freesurface with a subdomain. Only implemented for isotropic acoustic as elastic is another story. Can be added to TTI as well.
FYI generated code with sign wrap around
(((i2z - 2) > 0) - ((i2z - 2) < 0))
: