usnistgov / fipy

FiPy is a Finite Volume PDE solver written in Python
http://pages.nist.gov/fipy/en/latest
Other
504 stars 148 forks source link

Behavior of multiplying `MeshVariable` by list can be strange #957

Open guyer opened 11 months ago

guyer commented 11 months ago

It is often desired to use a scalar field as a vector; as a convection coefficient, for instance. In 1D, this can be achieved by

>>> mesh1D = fp.Grid1D(nx=5)
>>> var1D = fp.CellVariable(mesh=mesh1D, value=mesh1D.x)
>>> print(var1D)
[0.5 1.5 2.5 3.5 4.5]
>>> var1D.rank
0
>>> print(var1D * [[1]])
[[0.5 1.5 2.5 3.5 4.5]]
>>> (var1D * [[1]]).rank
1

Note that

>>> print(var1D * [1])
[0.5 1.5 2.5 3.5 4.5]
>>> (var1D * [1]).rank
0

does not work.

In 2D, FiPy is tolerant about the orientation of the "vector" list:

>>> mesh2D = fp.Grid2D(nx=2, ny=3)
>>> var2D = fp.CellVariable(mesh=mesh2D, value=mesh2D.x * mesh2D.y)
>>> print(var2D)
[0.25 0.75 0.75 2.25 1.25 3.75]
>>> var2D.rank
0
>>> print(var2D * [1,2])
[[0.25 0.75 0.75 2.25 1.25 3.75]
 [0.5  1.5  1.5  4.5  2.5  7.5 ]]
>>> (var2D * [1,2]).rank
1
>>> print(var2D * [[1],[2]])
[[0.25 0.75 0.75 2.25 1.25 3.75]
 [0.5  1.5  1.5  4.5  2.5  7.5 ]]
>>> (var2D * [[1],[2]]).rank
1

It's possible to get strange results if the vector-like list is not of the same dimension as the CellVariable:

>>> print(var2D * [[1]])
[[0.25 0.75 0.75 2.25 1.25 3.75]]
>>> (var2D * [[1]]).rank
1

Multiplying by a singly-nested list always seems to be interpreted as multiplication by a scalar:

>>> print(var2D * [1])
[0.25 0.75 0.75 2.25 1.25 3.75]
>>> (var2D * [1]).rank
0