-
Notifications
You must be signed in to change notification settings - Fork 630
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
collapse empty dimensions of time-domain grid slices by default and remove snap argument from get_array_metadata #1456
Conversation
python/simulation.py
Outdated
""" | ||
This routine provides geometric information useful for interpreting the arrays | ||
returned by `get_array` or `get_dft_array` for the spatial region defined by `vol` | ||
or `center`/`size`. In both cases, the return value is a tuple `(x,y,z,w)`, where: | ||
|
||
+ `x,y,z` are 1d NumPy arrays storing the $x,y,z$ coordinates of the points in the | ||
+ `x,y,z` are tuples storing the $x,y,z$ coordinates of the points in the |
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 another drive by comment following this from the reference to #1431... x
, y
, and z
look like they're NumPy arrays, not tuples.
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.
Thanks for calling this out. The "tics" return values (x,y,z)
should be NumPy arrays but in fact they are set up as tuples:
Lines 3278 to 3289 in f5fc4cd
xyzw_vector = self.fields.get_array_metadata(v, collapse, snap) | |
offset, tics = 0, [] | |
for n in range(3): | |
N = int(xyzw_vector[offset]) | |
tics.append( xyzw_vector[offset+1:offset+1+N] ) | |
offset += 1+N | |
wshape=[len(t) for t in tics if len(t)>1] | |
weights=np.reshape(xyzw_vector[offset:],wshape) | |
if return_pw: | |
points=[ mp.Vector3(x,y,z) for x in tics[0] for y in tics[1] for z in tics[2] ] | |
return points,weights | |
return tics + [weights] |
I verified this using type(x)
, type(y)
, type(z)
and the results was a tuple. (w
though is a NumPy array.) If we really want these return values as 1d NumPy arrays then we will need to modify get_array_metadata
in a separate PR. I just updated the documentation here to make it consistent with what is actually happening.
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.
Ah, good to know. If you wanted, you could also call np.asarray()
on them to do the conversion in Python.
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 looks like a SWIG problem — self.fields.get_array_metadata(v, collapse, snap)
is nowadays returning a tuple
, whereas the intention (and I think the original behavior) was to return a NumPy array.
We definitely want a numpy array here — a tuple is a terrible data structure for a large array. And we want to return a numpy array directly, not return a tuple and then convert to numpy.
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.
fields::get_array_metadata
returns a std::vector<double>
, which we want SWIG to convert to a NumPy array. I'm not sure why that isn't happening.
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.
According to the documentation for SWIG's std_vector.i
(which we are using), it's supposed to be using a "list object in the target language" for output typemaps.
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 was able to fix it by adding:
// use NumPy arrays for returning common std::vector types:
%typemap(out) std::vector<double> {
npy_intp vec_len = (npy_intp) $1.size();
$result = PyArray_SimpleNew(1, &vec_len, NPY_DOUBLE);
memcpy(PyArray_DATA((PyArrayObject*) $result), &$1[0], vec_len * sizeof(double));
}
to meep.i
(after %template(DoubleVector) std::vector<double>;
).
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.
We can do that in a separate PR.
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.
See #1458.
Note that until we get proper interpolation of the time-domain slices (#759), we may want to have a |
Seems like it should be easy to fix #759 nowadays, so that we can remove the |
The All the tests in the |
The latest changes also affect the call to |
…hdf5 only snaps to grid
…avity_arrayslice.py test
Would be good to re-instate the In the long run, I'm not sure that the current |
Verifying types of return values of import meep as mp
sim = mp.Simulation(cell_size=mp.Vector3(5,5,5),
resolution=20)
sim.init_sim()
(x,y,z,w) = sim.get_array_metadata(center=mp.Vector3(0,0,0.149), size=mp.Vector3(4.5,2.4,0))
print(len(x),len(y),len(z),w.shape)
print(type(x),type(y),type(z),type(w)) output
|
Note that if |
The |
All tests from the most recent commit (33dfce9) are passing on Travis (https://travis-ci.com/github/oskooi/meep/builds/211270487). |
Note that the weights returned by get_array_metadata are somewhat inconsistent. Realize that these weights include three things:
Currently, the Note that the dft_fields already include weights 3 as well, so there is the same first-order error in the current release for computing integrals of DFT fields with these integration weights. And the current release makes a first-order error in We can probably fix this in another PR. The fix is simple: this line should be changed to
|
…emove snap argument from get_array_metadata (NanoComp#1456) * fix for get_array_metadata related to collapsing of empty dimensions of grid slice * remove snap_empty_dimensions and collapse arrays in get_array_ * fix get_source_slice and get_array_metadata * update hard-coded validation binary files for cavity_arrayslice.py * remove collapse_empty_dimensions argument from tests/array_metadata.cpp * add array_to_all for parallel simulations and update docs * remove tests/array-slice-ll.cpp from make check suite because output_hdf5 only snaps to grid * add interpolation weights to slices and update hard-coded values of cavity_arrayslice.py test * re-instate snap argument for do_get_array_slice * fix bug in do_get_array_slice related to snapping * re-instate snap_empty_dimensions argument in get_array_slice_dimensions * include snap_empty_dimensions in meep.i * fixes * condense/simplify Co-authored-by: Steven G. Johnson <stevenj@alum.mit.edu>
Fixes #759.
Fixes #1431 based on the source of the bug described in #1431 (comment).
The
snap
parameter ofget_array_metadata
has been removed since it does not really serve a practical purpose compared with the argumentcollapse
which does interpolation. Also, documentation has been added for thecollapse
argument which was missing.The tests described in #1431 (comment) now produce the correct results:
Note how the sum of the weights from each of the uncollapsed dimensions (second and third columns) changes as the grid slice is swept across a distance of one pixel (first column).
Note: the documentation in
Python_User_Interface.md
has been regenerated usingmeep/doc/generate_py_api.py
which is why an unrelated change due toplot2D
(from #1446) appears.