-
Notifications
You must be signed in to change notification settings - Fork 83
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
'DiscreteField' object has no attribute 'reshape' #847
Comments
You have it correct, the idea has been to have DiscreteField behave like DiscreteField.value, mainly for convenience. Would it be reasonable to simply add DiscreteField.reshape which returns reshape applied to the value? |
That works, but there might be other What's the difference between I think there is a common abstraction that could tie |
DiscreteField is a tuple of ndarrays so I'm not sure what you mean by subclassing ndarray. Everything is precomputed and DiscreteField.grad == grad(DiscreteField). DiscreteField represents a function and its derivatives evaluated at quadrature points and it does not necessarily have any connection to a Basis. |
We used to define forms like this: def laplace(u, ux, uy, uz, v, vx, vy, vz):
return ux * vx + uy * vy + uz * vz So I invented |
Then after making def laplace(U, V):
... but then I had to figure out how to access |
This might be some gap in my skfem / fem in general understanding then...
That idea, of a function somehow represented in FEM space, I thought was very closely coupled to the idea of a Basis. Are you saying that the return value of Or maybe another way of saying it is What is the intended way to move back and forth between |
I meant that when you do x = DiscreteField() what you get back is a child of ndarray. The Essentially This issue is very similar to #846 and perhaps the two should be merged. |
Ok, now I see what you mean. I'll experiment with your idea of subclassing ndarray to see if it works. It might even simplify the implementation of DiscreteField. |
I'm doing that now, I'll have a PR for you in a few. |
scikit-fem/skfem/element/discrete_field.py Lines 81 to 89 in 84ef5ad
Is not exactly how |
scikit-fem/skfem/element/discrete_field.py Lines 71 to 75 in 84ef5ad
What's the goal of this? Is the idea when you slice a x = DiscreteField(...)
x[10:20,:,:-5].grad should work as expected? |
No no, there is something known as ElementComposite which will complicate matters. I didn't remember split is done that way. I think Basis.interpolate also assumes DiscreteField being iterable. |
So for a in DiscreteField():
... should iterate over the properties in the order they're listed in the Because anyone would be expecting that to iterate over the elements of |
Unless you want to redo Basis.interpolate and all those split thingies. |
It certainly seems like the way to go... but I think I guess its somewhat semantics, but you were trying to make |
I can try it out. This is very core part of the lib so it requires some careful consideration to not break too many things. |
Possible alternative to deriving DiscreteField from ndarray: define its |
@gdmcbain delegation isn't going to fix what I think is the more fundamental issue. If f**2 # works, f seems like an ndarray
f + f # works, f seems like an ndarray
[a for a in f] # !! f doesn't act like ndarray at all !! Whether inherit or delegate, I think for df, x in zip(w.my_df, w.x): shouldn't trick me the way it does now. Re: delegate vs inherit, I have a personal preference for inherit, but I also think this is a semantic/syntactic debate. One of the trickier parts of implementation I think is supporting something like |
Also, after delegation, |
Yes I see. Anyway i've published a draft branch in #847 to experiment with in case. It's only two lines and probably backwards compatible. |
Egads, |
After #847 |
Then again many examples given in this thread are really confusing to me. Why would you want to reshape a DiscreteField? Why would you want to know it's length? It's really about defining forms conveniently and if you don't need those things inside a form definition then we can forget about it. No need to make such drastic changes for no benefit. |
Slicing and then taking grad cannot work. In general, value and grad have different shapes. So after slicing grad would need to be dropped. |
My try on this: #849 |
I went as far as I could in #849. Waiting for you to try out the branch and give feedback. The remaining irritation regarding slicing is explained in the PR. |
I admit I got a little distracted by the computer sciency aspects yesterday. I don't have good use cases for the examples I gave. I was more pointing out how the DiscreteField was not behaving like a consistent abstraction.
Well, that's how I got here. I was still abusing the Functional to make interesting plots while I worked on making a "current source" boundary condition in skfem. My main argument of these examples is that if you're going to tamper with DiscreteField, might as well make it as well behaved as possible, which I think means making it act as much like an ordinary ndarray as possible. |
Fair enough. I think #849 somehow makes sense and seems to solve some minor pains we had with the existing implementation such as
If you agree it is a reasonable approach I think I will continue by
|
I like your plan. Here are my thoughts.
I looked around at what other packages do. Both pandas and xarray use
Test case for .value! :)
pandas and xarray and even numpy itself point the way. Let the repr show, for each property that isn't None, a subset of the values with ... in between. Dont bother including anything about the attributes that are None.
One brute force approach I had is that then you slice, re-compute the derived attributes. This would probably work a lot better if things were lazy evaluated, but maybe it is still worth considering some version of this idea. While we're talking about all this, what are your thoughts on adding |
I forgot to add, since the projection is currently an ndarray, making |
But there is something important about
So somehow I want to transfer this information through
This is not exactly how you can think about it. Even though mathematically Splitting evaluation of |
x = skfem.DiscreteField(np.arange(10*11*12*3).reshape((10,11,12,3)))
print(x)
print(x.shape)
Ok so this is contrived and I don't have any code. But it's pretty :) |
I still need to think about it but in other codes this seems to be typically called |
How would this work in |
Re: slicing... what if you didn't actually slice anything. Suppose you just recorded the start, stop, and stride. Then when you do a = DiscreteField(...)
s = slice(...)
b = a[s]
b.grad you can access that slice info to properly slice grad, hess, or whatever, in a way that make sense in the context. This would require changing |
Since this library is really about "finite element assembly" I sometimes even think if having |
This does sound exactly like what we're talking about. However, they subclassed You said you like the way skfem doesn't use such opaque objects, relying instead on ndarrays and scipy. I agree with you about that.
I agree with that too. I am happy... more happy, in fact, to import scipy and use that solver. Keeping skfem data objects compatible with scipy makes them easier to understand. I don't think x_in_p1 = x_in_p0.project(basis_p1)
x_discrete_field = x_in_p0.interpolate(basis_p1.quadrature_points) which feels intuitive and readable to me. |
This leads to confusing behavior in forms.
gg
,pp
,nn
all work, butii
returns 'DiscreteField' object has no attribute 'reshape'.The "work around" or maybe the intended usage appears to be
and this might be okay, except that
strongly implies (imo) that
w['ind_p1']
is the "value". Moreoverw[ind_p0]**2
works, and returns(w[ind_p0].value)**2
making me think maybew[ind_p0]
supports anyufunc
.I think
reshape
should work.The text was updated successfully, but these errors were encountered: