GithubHelp home page GithubHelp logo

tum-pbs / phiflow Goto Github PK

View Code? Open in Web Editor NEW
1.4K 26.0 191.0 854.82 MB

A differentiable PDE solving framework for machine learning

License: MIT License

Python 100.00%
differentiable-simulations fluid-simulations deep-learning neural-networks pde-solver

phiflow's People

Contributors

bobarna avatar brenerrr avatar danielzie avatar eliasdjo avatar gemmaellen avatar holl- avatar kbali1297 avatar marcelroed avatar mmichelis avatar phylomatx avatar the-rccg avatar thunil avatar tinkei avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phiflow's Issues

Cannot compile CUDA kernels

I'm trying to compile the CUDA kernels to use PhiFlow on the GPU, however, the compilation fails. For reference, I am using WSL2 with Ubuntu 20.04. This was the log file of the compilation:

/home/mclea/PhiFlow/phi/tf/cuda/src/helpers.h: In instantiation of ‘void copyDataToArray(const T*, cudaArray*, cudaSurfaceObject_t, cudaMemcpy3DParms, int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int) [with T = float; cudaSurfaceObject_t = long long unsigned int]’:
/home/mclea/PhiFlow/phi/tf/cuda/src/resample.cu.cc:313:21:   required from ‘void tensorflow::ResampleTextureMemory(unsigned int, int, const unsigned int*, unsigned int, unsigned int, unsigned int, unsigned int, const T*, const T*, T*, const Boundary*) [with T = float]’
/home/mclea/PhiFlow/phi/tf/cuda/src/resample.cu.cc:347:155:   required from here
/home/mclea/PhiFlow/phi/tf/cuda/src/helpers.h:323:18: warning: ‘cudaError_t cudaMemcpyToArray(cudaArray_t, size_t, size_t, const void*, size_t, cudaMemcpyKind)’ is deprecated [-Wdeprecated-declarations]
  323 |   cudaMemcpyToArray(cuArray, 0, 0, data + batch * xSize * ySize * zSize * components, xSize * ySize * zSize * components * sizeof(T), cudaMemcpyDeviceToDevice);
      |   ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime_api.h:7368:46: note: declared here
 7368 | extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, size_t count, enum cudaMemcpyKind kind);
      |                                              ^~~~~~~~~~~~~~~~~
/home/mclea/PhiFlow/phi/tf/cuda/src/helpers.h:323:18: warning: ‘cudaError_t cudaMemcpyToArray(cudaArray_t, size_t, size_t, const void*, size_t, cudaMemcpyKind)’ is deprecated [-Wdeprecated-declarations]
  323 |   cudaMemcpyToArray(cuArray, 0, 0, data + batch * xSize * ySize * zSize * components, xSize * ySize * zSize * components * sizeof(T), cudaMemcpyDeviceToDevice);
      |   ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime_api.h:7368:46: note: declared here
 7368 | extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, size_t count, enum cudaMemcpyKind kind);
      |                                              ^~~~~~~~~~~~~~~~~
/home/mclea/PhiFlow/phi/tf/cuda/src/helpers.h:323:18: warning: ‘cudaError_t cudaMemcpyToArray(cudaArray_t, size_t, size_t, const void*, size_t, cudaMemcpyKind)’ is deprecated [-Wdeprecated-declarations]
  323 |   cudaMemcpyToArray(cuArray, 0, 0, data + batch * xSize * ySize * zSize * components, xSize * ySize * zSize * components * sizeof(T), cudaMemcpyDeviceToDevice);
      |   ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime_api.h:7368:46: note: declared here
 7368 | extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, size_t count, enum cudaMemcpyKind kind);
      |                                              ^~~~~~~~~~~~~~~~~
/home/mclea/PhiFlow/phi/tf/cuda/src/helpers.h:323:18: warning: ‘cudaError_t cudaMemcpyToArray(cudaArray_t, size_t, size_t, const void*, size_t, cudaMemcpyKind)’ is deprecated [-Wdeprecated-declarations]
  323 |   cudaMemcpyToArray(cuArray, 0, 0, data + batch * xSize * ySize * zSize * components, xSize * ySize * zSize * components * sizeof(T), cudaMemcpyDeviceToDevice);
      |   ~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~           
/usr/local/cuda/bin/../targets/x86_64-linux/include/cuda_runtime_api.h:7368:46: note: declared here
 7368 | extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArray(cudaArray_t dst, size_t wOffset, size_t hOffset, const void *src, size_t count, enum cudaMemcpyKind kind);
      |                                              ^~~~~~~~~~~~~~~~~
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/notification.h:27,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/lib/core/notification.h:21,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/cancellation.h:22,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:27,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/default/notification.h:61:65: warning: ‘tensorflow::int64’ is deprecated: Use int64_t instead. [-Wdeprecated-declarations]
   61 |                                              int64 timeout_in_us);
      |                                                                 ^
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/types.h:31,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/numeric_types.h:27,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/allocator.h:26,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:26,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/default/integral_types.h:29:63: note: declared here
   29 | [[deprecated("Use int64_t instead.")]] typedef ::std::int64_t int64;
      |                                                               ^~~~~
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/notification.h:27,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/lib/core/notification.h:21,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/cancellation.h:22,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:27,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/default/notification.h:62:58: warning: ‘tensorflow::int64’ is deprecated: Use int64_t instead. [-Wdeprecated-declarations]
   62 |   bool WaitForNotificationWithTimeout(int64 timeout_in_us) {
      |                                                          ^
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/types.h:31,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/numeric_types.h:27,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/allocator.h:26,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:26,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/default/integral_types.h:29:63: note: declared here
   29 | [[deprecated("Use int64_t instead.")]] typedef ::std::int64_t int64;
      |                                                               ^~~~~
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/notification.h:27,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/lib/core/notification.h:21,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/cancellation.h:22,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:27,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/default/notification.h:81:63: warning: ‘tensorflow::int64’ is deprecated: Use int64_t instead. [-Wdeprecated-declarations]
   81 |                                            int64 timeout_in_us) {
      |                                                               ^
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/types.h:31,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/numeric_types.h:27,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/allocator.h:26,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:26,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/default/integral_types.h:29:63: note: declared here
   29 | [[deprecated("Use int64_t instead.")]] typedef ::std::int64_t int64;
      |                                                               ^~~~~
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor.h:24,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/device_base.h:26,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:29,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor_shape.h:305:22: warning: ‘tensorflow::int64’ is deprecated: Use int64_t instead. [-Wdeprecated-declarations]
  305 |   gtl::InlinedVector<int64, 4> dim_sizes() const;
      |                      ^~~~~
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/types.h:31,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/numeric_types.h:27,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/allocator.h:26,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:26,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/platform/default/integral_types.h:29:63: note: declared here
   29 | [[deprecated("Use int64_t instead.")]] typedef ::std::int64_t int64;
      |                                                               ^~~~~
In file included from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor.h:25,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/device_base.h:26,
                 from /home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/op_kernel.h:29,
                 from /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc:2:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor_types.h: In member function ‘void tensorflow::internal::MaybeWith32BitIndexingImpl<Eigen::GpuDevice>::operator()(Func, Args&& ...) const’:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor_types.h:176:25: error: use of ‘auto’ in lambda parameter declaration only available with ‘-std=c++14’ or ‘-std=gnu++14’
  176 |     auto all = [](const auto&... bool_vals) {
      |                         ^~~~
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor_types.h:176:34: error: expansion pattern ‘const int&’ contains no parameter packs
  176 |     auto all = [](const auto&... bool_vals) {
      |                                  ^~~~~~~~~
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor_types.h: In lambda function:
/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include/tensorflow/core/framework/tensor_types.h:177:22: error: ‘bool_vals’ was not declared in this scope
  177 |       for (bool b : {bool_vals...}) {
      |                      ^~~~~~~~~

/usr/local/cuda/bin/nvcc /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cu.cc -o /home/mclea/PhiFlow/phi/tf/cuda/build/resample.cu.o -std=c++11 -c -D GOOGLE_CUDA=1 -x cu -Xcompiler -fPIC --expt-relaxed-constexpr -DNDEBUG -O3 -I/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include -D_GLIBCXX_USE_CXX11_ABI=0 -DEIGEN_MAX_ALIGN_BYTES=64

gcc /home/mclea/PhiFlow/phi/tf/cuda/src/resample.cc /home/mclea/PhiFlow/phi/tf/cuda/build/resample.cu.o -o /home/mclea/PhiFlow/phi/tf/cuda/build/resample.so -std=c++11 -shared -fPIC -lcudart -O3 -L/usr/local/cuda/lib64/ -I/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow/include -D_GLIBCXX_USE_CXX11_ABI=0 -DEIGEN_MAX_ALIGN_BYTES=64 -L/home/mclea/miniconda3/envs/phi_flow/lib/python3.8/site-packages/tensorflow -l:libtensorflow_framework.so.2

I cant find why this might fail, could it be my TensorFlow version?

Sometimes GPU stuff in WSL can fail because there is no nvidia driver.

SampledField.with_values does not copy all dimensions properly

Hello,

I want to create a 2D staggered grid that contains not only the spatial dimensions, but also the temporal dimension throughout the simulation. Here's how I initialized the field, and everything seems to work correctly so far. I'm not sure if this is the optimal way to do so, so please let me know if there is a better way.

velocity_single = StaggeredGrid(0, extrapolation=extrapolation.ZERO, x=32, y=32, bounds=Box(x=32, y=32))
velocity_temporal = field.stack([Noise() @ velocity_single] * 10, dim=channel("temporal"))
print(velocity_temporal)
# StaggeredGrid[(xˢ=32, yˢ=32, vectorᶜ=x,y, temporalᶜ=10), size=(x=32, y=32), extrapolation=0]

Now I'd like to create another temporal staggered grid base on the dimension of the one I just created, but initialize all the values to 0. I attempted to use SampledField.with_values to do so, but it seems like the temporal channel dimension was not copied over.

velocity_temporal_copy = velocity_temporal.with_values(0)
print(velocity_temporal_copy)
# StaggeredGrid[(xˢ=32, yˢ=32, vectorᶜ=x,y), size=(x=32, y=32), extrapolation=0]

I'm not quite sure if this is a bug or is this the intended behaviour?

Thanks!

`.upsample2x` transposes 2d fields spatially

If we generate a random field and upsample we see that the resulting fields are transposed (if you can't see it, look at the two darker blue dots)

Screen Shot 2022-07-22 at 15 23 53

MRE

from phi.flow import *
from phi import math, field

math.seed(59)

p = CenteredGrid(
    Noise(
        batch(batch=1),
        scale=0.1,
        smoothness=3),
    x=64,
    y=64,
    bounds=Box(
        x=1.0,
        y=1.0
    )
)

half_p = field.downsample2x(p)
double_p = field.upsample2x(p)
vis.plot([
        p,
        half_p,
        field.upsample2x(half_p),
        double_p,
        field.downsample2x(double_p)
    ],
    show_color_bar=False)

vis.plot() plots with incorrect circle radius

Hi, when I plot a circle with radius 1

import phi.geom as geom
import phi.vis as vis

vis.plot(geom.Sphere(math.tensor([[0, 0]], math.instance(points=None), math.channel(vector='x,y')), math.tensor([1], math.instance(points=None))))

The result is a circle with radius \sqrt{2}/2:
radius_sqrt2_2
It seems that this is caused by the fact that the radius is converted to the diameter by multiplication with sqrt(2), instead of by multiplication with 2. Replacing 1.41 with 2.0 gives a circle of the expected size:
radius_1

Pointcloud from (native) array

Hi,

if I have a numpy / torch / tensorflow array that contains n points with dimension dim in the shape of (n, dim),
how would I initialize a PointCloud with that? The docs and tutorials are not really helpful for that, but only describe how to generate point clouds directly from phiflow Tensors.

Installation error: Command errored out with exit status 1: python setup.py egg_info

Hello,
Thank you for the amazing work.
I am trying to install the toolkit using pip as instructed, but I get the following error:

ERROR: Command errored out with exit status 1: command: /home/abushah/anaconda3/envs/cfdnet/bin/python -c 'import sys, setuptools, tokenize; sys.argv[0] = '"'"'/tmp/pip-install-bmlg0_n6/phiflow/setup.py'"'"'; __file__='"'"'/tmp/pip-install-bmlg0_n6/phiflow/setup.py'"'"';f=getattr(tokenize, '"'"'open'"'"', open)(__file__);code=f.read().replace('"'"'\r\n'"'"', '"'"'\n'"'"');f.close();exec(compile(code, __file__, '"'"'exec'"'"'))' egg_info --egg-base /tmp/pip-install-bmlg0_n6/phiflow/pip-egg-info cwd: /tmp/pip-install-bmlg0_n6/phiflow/ Complete output (5 lines): Traceback (most recent call last): File "<string>", line 1, in <module> File "/tmp/pip-install-bmlg0_n6/phiflow/setup.py", line 117, in <module> with open("documentation/Package_Info.md", "r") as readme: FileNotFoundError: [Errno 2] No such file or directory: 'documentation/Package_Info.md' ---------------------------------------- ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.

Any advice on how to resolve this?

Second Order PDEs

Hi,

I have been looking into DL with physics and came across this project. However, I am having some trouble using this for a dummy case in mind, the wave equation, which is a second-order PDE. In both examples given, first-order PDEs are used. Is this package meant to be used for second-order PDEs, and if so, would you be able to share some pointers?

Regards,
Daniel

Evaluate diffusion with non-isotropic diffusivity

Hi, first of all I love the work you are doing here. I am working on an advection-diffusion model of a scalar field C; when evaluating the diffusion term with a non-isotropic diffusivity, a vector field is returned instead of a scalar. I have discussed this issue in private with @holl-, reposting here for visibility and tracking.

Consider the following setup: $\bf{D} = (D_x , D_y , D_z)$ is a vector field, where each component is space independent for now. However, the value of each term is different. I create this using:

from phi.torch import flow as pf

Diffusivity = pf.CenteredGrid(
    values=(.1, 1., 1.),
    extrapolation=pf.extrapolation.BOUNDARY,
    bounds=conc.bounds,
    resolution=conc.resolution

where $C \equiv conc$ is a real scalar field in 3D. In diffuse.explicit the following happens:

def explicit(field: FieldType,
             diffusivity: float or math.Tensor or Field,
             dt: float or math.Tensor,
             substeps: int = 1) -> FieldType:

amount = diffusivity * dt
if isinstance(amount, Field):
    amount = amount.at(field)
for i in range(substeps):
    field += amount / substeps * laplace(field).with_extrapolation(field.extrapolation)

return field

when D is a real number, this correctly evaluates: $D \nabla^2 C$ that is a scalar. However, when using D as a vector field, although this is correctly resampled at C, it evaluates: $\bf{D} \nabla^2 C$, that is a vector. The reason is that the general diffusion term is:
$$\nabla \cdot (\bf{D} \nabla^2 C) = \partial^i (D_i \partial_i C)$$
When $D_i$ is constant, the expression reduces to $D^i \partial^2_i C$, that is a kind of "weighted" sum of each component of the vector field $\partial^2_i C$. When using the laplace() method in the code above, this evaluates first $\sum_i \partial^2_i C$, that is the origin of the issue.

As discussed, a simple solution here is to allow a weight term in the definition of the laplace() method, so that we could pass laplace(field, diffusivity) and obtain a scalar field now. Is there a simple way of implementing this? I tried a couple of options but I failed when trying to integrate with your codebase. I would truly appreciate your help.

Thank you

object rotation do not work in branch 2.3-develop

Thanks for fixing jit-compile in branch 2.3. Unfortunately object rotation does not work there. This program crashes in branch 2.3-develop

from phi.tf.flow import *
DOMAIN = dict(x=30, y=30)
DT = 0.1

def move_obstacle(obs: Obstacle):
    new_geometry = obs.geometry.shifted([1. * DT, 0])
    new_geometry = new_geometry.rotated(0.1*DT)
    return obs.copied_with(geometry=new_geometry)


obstacle = Obstacle(Box(x=(5, 11), y=(10, 16)), velocity=[0., 0], angular_velocity=tensor(0.1,))
velocity = StaggeredGrid(0, extrapolation.ZERO, **DOMAIN)
obstacle_mask = CenteredGrid(HardGeometryMask(obstacle.geometry), extrapolation.BOUNDARY, **DOMAIN)
pressure = None

@math.jit_compile
def step(velocity, obstacle):
    velocity = advect.mac_cormack(velocity, velocity, DT)
    velocity, pressure = fluid.make_incompressible(velocity, (obstacle,))
    return velocity, pressure

for _ in view(velocity, obstacle_mask, play=True, namespace=globals(), port=6006).range():
    obstacle = move_obstacle(obstacle)
    velocity, pressure = step(velocity, obstacle)
    obstacle_mask = HardGeometryMask(obstacle.geometry) @ pressure

File "/home/flow_control/obstacle_rotate.py", line 23, in
obstacle = move_obstacle(obstacle)
File "/home/flow_control/obstacle_rotate.py", line 6, in move_obstacle
new_geometry = obs.geometry.shifted([1. * DT, 0])
File "/usr/local/lib/python3.8/dist-packages/phi/geom/_geom.py", line 233, in shifted
return self.at(self.center + delta)
File "/usr/local/lib/python3.8/dist-packages/phi/geom/_transform.py", line 78, in at
return RotatedGeometry(self._geometry.at(center), self._angle)
File "/usr/local/lib/python3.8/dist-packages/phi/geom/_box.py", line 36, in at
return Cuboid(center, self._half_size)
File "/usr/local/lib/python3.8/dist-packages/phi/geom/_geom.py", line 357, in getattr
return BoundDim(self, name)
File "/usr/local/lib/python3.8/dist-packages/phi/math/magic.py", line 461, in init
raise AttributeError(f"'{type(self)}' object has no attribute '{name}'")
AttributeError: '<class 'phi.math.magic.BoundDim'>' object has no attribute '_half_size'

a problem about Vis.plot()

I am very interested in your great work. I follow your work well in coolab but I have a problem when I use 'vis.plot(gird)' in pycharm in my local computer,It crashed and said'_tkinter.TclError: invalid command name ".!navigationtoolbar2tk.!button2"',how can I sovle it ?

Plotting overlaying fields in different colors.

Cannot plot fields wrapped with vis.overlay in different colors since f03e6bd.
This used to be supported when color was an attribute of the field.
Can it be fixed, maybe with a different indexing of vis.plot's color argument?

How can I create a 3D smoke plume with Phiflow?

Hi, I want to create a 3D version of the simple smoke plume but don't know how to do it. It seems that no 3D fluid demo is included in the source code...
So I just modified a couple of settings in the 2D demo codes like this:

DOMAIN = dict(x=100, y=100, z=100, bounds=Box[0:100, 0:100, 0:100])
velocity = StaggeredGrid(0, extrapolation.ZERO, **DOMAIN)  # or use CenteredGrid
smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=100, y=100, z=100, bounds=DOMAIN['bounds'])
INFLOW = 0.2 * CenteredGrid(SoftGeometryMask(Sphere(center=(50, 10, 50), radius=5)), extrapolation.ZERO, resolution=smoke.resolution, bounds=smoke.bounds)
pressure = None

for _ in view(smoke, velocity, 'pressure', play=False, namespace=globals()).range(warmup=1):
    smoke = advect.mac_cormack(smoke, velocity, 1) + INFLOW
    buoyancy_force = smoke * (0, 0.1, 0) @ velocity  # resamples smoke to velocity sample points
    velocity = advect.semi_lagrangian(velocity, velocity, 1) + buoyancy_force
    velocity, pressure = fluid.make_incompressible(velocity, (), Solve('auto', 1e-5, 0, x0=pressure))

Compared to the original version:

DOMAIN = dict(x=64, y=64, bounds=Box[0:100, 0:100])
velocity = StaggeredGrid((0, 0), extrapolation.ZERO, **DOMAIN)  # or use CenteredGrid
smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=200, y=200, bounds=DOMAIN['bounds'])
INFLOW = 0.2 * CenteredGrid(SoftGeometryMask(Sphere(center=(50, 10), radius=5)), extrapolation.ZERO, resolution=smoke.resolution, bounds=smoke.bounds)
pressure = None

for _ in view(smoke, velocity, 'pressure', play=False, namespace=globals()).range(warmup=1):
    smoke = advect.mac_cormack(smoke, velocity, 1) + INFLOW
    buoyancy_force = smoke * (0, 0.1) @ velocity  # resamples smoke to velocity sample points
    velocity = advect.semi_lagrangian(velocity, velocity, 1) + buoyancy_force
    velocity, pressure = fluid.make_incompressible(velocity, (), Solve('auto', 1e-5, 0, x0=pressure))

It didn't work though. Does the current version of Phiflow support 3D fluids? I was wondering how to implement and debug it...
Thanks a lot!

Build on windows

First of all I want to thank you for this great library. I am trying now to build library with tf_cuda option on Win10. As I have understood from setup.py it can be compiled only with gcc. Other variable like cuda_lib is also unix specifed. I am not good at C++ programming. So I have the following question. Will be it enough to change the compiler from gcc (Linux) to to cl (Win10 Visual Studio) with adapting the line arguments? I'd appreciate any advice or tip. I am also ready to make a pull request later for win-build.

Can't sum grids depending on global_precision

Hello !
I have this error :
IncompatibleShapes: Cannot merge shapes [(xˢ=1024), (xˢ=1023)] because dimension 'x' exists with different sizes.

when I try to execute this code :

import phi
from phi import flow
from phi.field._field_math import spatial_gradient
import numpy as np
phi.math.set_global_precision(64)

N = 1024
u = np.ones(N)
u = flow.math.tensor(u, flow.spatial('x'))
u = flow.field.CenteredGrid(u, flow.extrapolation.PERIODIC, x=N, bounds=flow.Box['x', 0:2*np.pi])
dudx = spatial_gradient(u, type=flow.field.StaggeredGrid, gradient_extrapolation=flow.extrapolation.PERIODIC)[0]
dudx2 = spatial_gradient(dudx, type=flow.field.StaggeredGrid, gradient_extrapolation=flow.extrapolation.PERIODIC)[0]
print(u.shape) #(xˢ=1024)
print(dudx2.shape) #(xˢ=1024)
u + dudx2  # THIS LINE CAUSE THE ERROR

The error occurs only for bad combination of global_precision and N.
For example, it occurs with :

  • N=1024 & prec=64
  • N = 8192 & prec=64
  • N=64 & prec=32

Thank you !

Potential Bug regarding non-zero extrapolation padding in math.convolve

Hello,

I've been trying this package out and it has been a blast. Thank you for the amazing work!

I'm currently playing around with grid value convolutions and have potentially stumbled upon a bug when the padding extrapolation mode is non-ZERO. The error is AssertionError: Shape.name is only defined for shapes of rank 1. shape=(xˢ=5, yˢ=5)

Here's a piece of code to reproduce the error.

values = math.random_normal(spatial(x=64, y=64))
kernel = math.random_normal(spatial(x=5, y=5))
values_conv = math.convolve(values, kernel, extrapolation.PERIODIC)

I think a potential fix is for this line, instead of attempting to loop over a single name for dim in conv_shape.name, loop over the names of the shape for dim in conv_shape.names. I tested locally with the example above and the assertion error goes away. I'm not entirely sure if this is the intended behaviour though.

PhiFlow/phi/math/_ops.py

Lines 1759 to 1761 in 9d11b27

if extrapolation is not None and extrapolation != e_.ZERO:
value = pad(value, {dim: (kernel.shape.get_size(dim) // 2, (kernel.shape.get_size(dim) - 1) // 2)
for dim in conv_shape.name}, extrapolation)

Thanks for taking a look!

Documentation issue + no jit compilation for advection function

Hi, it's me again,
I'm still using phiflow and enjoyed it so far but I'm stuck with a documentation issue.
In the jit_compile documentation page it's written the following :
Args
f
Function to be traced. All positional arguments must be of type Tensor or PhiTreeNode returning a single Tensor or PhiTreeNode.

But I can not find any information about the PhiTreeNode class in the documentation. Would be nice to include a link to the class or to remove it from the doc if deprecated. Morever, I managed to implement a jit-compiled method which arguments weren't Tensors but CenteredGrid and int, are this special case of PhiTreeNode ?

Additionally, I'm facing a problem when trying to jit-compile the advection fonction with your wrapper. The input to the advection function is a PointCloud of Tensors I want to advect with velocity field, represented as a centered grid, and which is the second parameter of the function. Given that jited_advection = flow.math.jit_compile(flow.advect.advect) and that I try to jit-compile the advection function to improve its speed, I get the following error message which is particularly unhelpfull :

Traceback (most recent call last):    
  File "/home/rocremes/projects/snake-ai/src/snake_ai/physim/main.py", line 57, in deterministic_walk
    point_cloud : flow.PointCloud = jited_advection(point_cloud, gradient_field, time_step)
  File "/home/rocremes/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_functional.py", line 197, in __call__
    self.traces[key] = self._jit_compile(key)
  File "/home/rocremes/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_functional.py", line 171, in _jit_compile
    PHI_LOGGER.debug(f"Φ-jit: '{f_name(self.f)}' called with new key. shapes={[s.volume for s in in_key.shapes]}, args={in_key.tree}")
  File "/home/rocremes/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/field/_point_cloud.py", line 170, in __repr__
    return "PointCloud[%s]" % (self.shape,)
  File "/home/rocremes/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/field/_field.py", line 136, in __getattr__
    return BoundDim(self, name)
  File "/home/rocremes/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/magic.py", line 449, in __init__
    raise AttributeError
AttributeError

Used backend : JAX

I would love to know if it's possible to jit compile the advection function and to differentiate through it.
Thank you for the time you might take to respond.

How to assign values to new grid variables

When I using phiflow for the case of "smoke_plume", I want to save the arrays of smoke and velocity so that I can continue to calculate the solution when I need. But I don't how to assign numpy array(or tensor) into CenteredGrid and StaggeredGrid object. Could help me to fix my problem?

Here is my code:

First, I defined "smoke", "velocity" and "INFLOW" object:


smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=128, y=128, bounds=Box(x=128, y=128))
velocity = StaggeredGrid(0, extrapolation.ZERO, x=128, y=128, bounds=Box(x=128, y=128))
INFLOW_LOCATION1 = tensor([(20, 25), (50, 50), (80, 25), (110, 25)], batch('inflow_loc'), channel(vector='x,y'))
INFLOW_LOCATION2 = tensor([(110, 25), (75, 50), (45, 25), (30, 25)], batch('inflow_loc'), channel(vector='x,y'))
sphere1 = Sphere(center=INFLOW_LOCATION1, radius=10)
sphere2 = Sphere(center=INFLOW_LOCATION2, radius=10)
sphere = flow.union([sphere1, sphere2])
INFLOW = 0.6 * CenteredGrid(sphere, extrapolation.BOUNDARY, x=128, y=128, bounds=Box(x=128, y=128))

then I take some steps to calculate the velocity and smoke, and record the arrays at the same time.


@flow.math.jit_compile
def step(velocity_prev, smoke_prev, dt=1.0):
smoke_prev = advect.mac_cormack(smoke_prev, velocity_prev, dt=1) + INFLOW
buoyancy_force = smoke_prev * (0, 0.5) @ velocity_prev
velocity_prev = advect.semi_lagrangian(velocity_prev, velocity_prev, dt=1) + buoyancy_force
velocity_prev, _ = fluid.make_incompressible(velocity_prev)
return velocity_prev, smoke_prev
for i in range(100):
velocity, smoke = step(velocity, smoke)
v_array = velocity.at_centers().values.numpy("inflow_loc,y,x,vector")
smoke_array = smoke.values.numpy("inflow_loc,y,x")

and now I don't know how to use "v_array" and "smoke_array" to rebuild the "smoke", "velocity" object to continue the calculation.


Thanks for help!!!

PhiFlow Fluid usage with PyTorch

Hello, authors. First of all, thank you for your amazing work!

I can see that experimental PyTorch support has been added. I am trying to use it, but face some errors. Is it meant to be used yet? If so, could you please guide me through my error?

I am trying to use PhiFlow in a PyTorch-friendly style, and am getting an error when Fluid validates input density.

I am trying to do approximately the following:

from PhiFlow.phi.torch.flow import *
import torch
from torch.utils.data import TensorDataset, DataLoader
inputs = torch.rand(1000, 10, 10, 1)
targets = torch.rand(1000, 10, 10, 1)
dataset = TensorDataset(inputs, targets)
dataloader = DataLoader(dataset, batch_size=10)
domain = Domain([10, 10], boundaries=PERIODIC)
sz = domain.staggered_grid(0).staggered_tensor().shape
initial_velocity = torch.zeros(*sz)
initial_velocity = initial_velocity.expand(10, *initial_velocity.shape[1:])
velocity = torch.nn.Parameter(initial_velocity)
optimizer = torch.optim.Adam([velocity], lr=1e-3)
for epoch in range(10):
    for batch_index, (inputs, targets) in enumerate(dataloader):
        optimizer.zero_grad()
        domain = Domain([10, 10], boundaries=PERIODIC)
        fluid = Fluid(domain, batch_size=10, density=inputs, velocity=velocity)
        fluid.density = advect.semi_lagrangian(fluid.density, fluid.velocity, dt=1)
        fluid.density = diffuse(fluid.density, 1 * 0.1, substeps=1)
        loss = math.l2_loss(predictions, targets)
        loss.backward()
        optimizer.step()

And I get the following error:

Error stackstrace
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-1-1b5462d9cefb> in <module>()
     16         optimizer.zero_grad()
     17         domain = Domain([10, 10], boundaries=PERIODIC)
---> 18         fluid = Fluid(domain, batch_size=10, density=inputs, velocity=velocity)
     19         fluid.density = advect.semi_lagrangian(fluid.density, fluid.velocity, dt=1)
     20         fluid.density = diffuse(fluid.density, 1 * 0.1, substeps=1)

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/physics/fluid.py in __init__(self, domain, density, velocity, buoyancy_factor, tags, name, **kwargs)
     26 
     27     def __init__(self, domain, density=0.0, velocity=0.0, buoyancy_factor=0.0, tags=('fluid', 'velocityfield', 'velocity'), name='fluid', **kwargs):
---> 28         DomainState.__init__(self, **struct.kwargs(locals()))
     29 
     30     def default_physics(self): return INCOMPRESSIBLE_FLOW

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/physics/physics.py in __init__(self, batch_size, **kwargs)
     20     def __init__(self, batch_size=None, **kwargs):
     21         self._batch_size = batch_size
---> 22         struct.Struct.__init__(self, **kwargs)
     23 
     24     @struct.constant(default=())

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/struct/struct.py in __init__(self, content_type, **kwargs)
     64             trait.endow(self)
     65         if content_type is VALID:
---> 66             self.validate()
     67 
     68     @derived()

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/struct/struct.py in validate(self)
    156         """
    157         if not skip_validate() and self.__content_type__ is INVALID:
--> 158             self.__validate__()
    159             self.__content_type__ = VALID
    160             return True

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/struct/struct.py in __validate__(self)
    166             trait.pre_validate_struct(self)
    167         for item in self.__items__:
--> 168             item.validate(self)
    169         for trait in self.__traits__:
    170             trait.post_validate_struct(self)

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/struct/structdef.py in validate(self, struct)
    148             for trait in self.traits:
    149                 value = trait.pre_validated(struct, self, value)
--> 150             value = self.validation_function(struct, value)
    151             for trait in self.traits:
    152                 value = trait.post_validated(struct, self, value)

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/physics/fluid.py in density(self, density)
     36 It describes the number of particles per physical volume.
     37         """
---> 38         return self.centered_grid('density', density)
     39 
     40     @struct.variable(default=0, dependencies=DomainState.domain)

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/physics/domain.py in centered_grid(self, name, value, components, dtype)
    241     def centered_grid(self, name, value, components=1, dtype=np.float32):
    242         extrapolation = Material.extrapolation_mode(self.domain.boundaries)
--> 243         return self.domain.centered_grid(value, dtype=dtype, name=name, components=components, batch_size=self._batch_size, extrapolation=extrapolation)
    244 
    245     def staggered_grid(self, name, value, dtype=np.float32):

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/physics/domain.py in centered_grid(self, data, components, dtype, name, batch_size, extrapolation)
    138                 grid._age = 0.0
    139         else:
--> 140             grid = CenteredGrid.sample(data, self, batch_size=batch_size)
    141         assert grid.component_count == components, "Field has %d components but %d are required for '%s'" % (grid.component_count, components, name)
    142         if math.dtype(grid.data) != dtype:

~/.virtualenvs/torch1venv3/lib/python3.6/site-packages/phiflow-1.4.0-py3.6.egg/phi/physics/field/grid.py in sample(value, domain, batch_size, name)
     53         else:  # value is constant
     54             components = math.staticshape(value)[-1] if math.ndims(value) > 0 else 1
---> 55             data = math.zeros((batch_size,) + tuple(domain.resolution) + (components,)) + value
     56         return CenteredGrid(data, box=domain.box, extrapolation=Material.extrapolation_mode(domain.boundaries), name=name)
     57 

TypeError: add(): argument 'other' (position 1) must be Tensor, not numpy.ndarray

I tried to track down where exactly my Tensor becomes numpy.ndarray, but failed to do so. I am getting this error both on master and develop branches.

A couple of comments regarding the piece of code above:

  1. Import looks so because setup.py does not build phi.torch
  2. I use torch.zeros(), because math.zeros() returns numpy.ndarray

Looking forward to your answer,
Nikolai

Animations do not render

Hello there!

As I just discovered this package, I have been following Fluids Tutorial to see whether I could have a nice animation. Unfortunately, copying exactly the provided code do not display anything.

I get one error warning after running vis.plot(trajectory, animate='time') (input [7] from the tutorial):

/python3.10/site-packages/matplotlib/animation.py:887: UserWarning: Animation was deleted without rendering anything. This is most likely not intended. To prevent deletion, assign the Animation to a variable, e.g. `anim`, that exists until you have outputted the Animation using `plt.show()` or `anim.save()`.

An easy fix I used was to remove plots.close(figure) on

plots.close(figure)

Doing so, the animation displays normally.

User Specifications

  • OS: Linux Mint 21
  • Python: 3.10
  • Matplotlib: 3.5.3, 3.6.3, 3.7.2 (same error)
  • PhiFlow: 2.4.0

Please tell me if you need more information!

Smoke Plume Sim Difference between Jax and PyTorch

Hello! I'm running the simple smoke plume demo from the examples and tried comparing the results with phi.torch vs phi.jax. The top gif shows the results I'm getting with phi.jax, and the bottom show the results with phi.torch. The only difference between the runs is from phi.jaximport flow vs from phi.torch import flow. The results with torch seem correct, since they agree with the CPU results. My setup is Python 3.8.10, jax==0.3.14, jaxlib==0.3.14+cuda11.cudnn82, torch==1.12.0+cu116, cuda 11.6.

Am I doing something wrong here?

smoke_plume_jax
smoke_plume_torch

Source code:

#from phi.jax import flow
from phi.torch import flow
import matplotlib.pyplot as plt
from tqdm import tqdm
from celluloid import Camera

N_TIME_STEPS = 150


def main():
    velocity = flow.StaggeredGrid(
        values=(0.0, 0.0),
        extrapolation=0.0,
        x=64,
        y=64,
        bounds=flow.Box(x=100, y=100),
    )
    smoke = flow.CenteredGrid(
        values=0.0,
        extrapolation=flow.extrapolation.BOUNDARY,
        x=200,
        y=200,
        bounds=flow.Box(x=100, y=100),
    )
    inflow = 0.2 * flow.CenteredGrid(
        values=flow.SoftGeometryMask(
            flow.Sphere(
                x=40,
                y=9.5,
                radius=5,
            )
        ),
        extrapolation=0.0,
        bounds=smoke.bounds,
        resolution=smoke.resolution,
    )
    pressure = None

    @flow.math.jit_compile
    def step(velocity_prev, smoke_prev, pressure, dt=1.0):
        smoke_next = flow.advect.mac_cormack(smoke_prev, velocity_prev, dt) + inflow
        buoyancy_force = smoke_next * (0.0, 0.1) @ velocity     # resamples smoke to velocity sample points
        velocity_tent = flow.advect.semi_lagrangian(velocity_prev, velocity_prev, dt) + buoyancy_force * dt
        velocity_next, pressure = flow.fluid.make_incompressible(velocity_tent, (), flow.Solve('auto', 1e-5, 0, x0=pressure))
        return velocity_next, smoke_next, pressure

    plt.style.use("dark_background")
    fig = plt.figure()
    camera = Camera(fig)

    for _ in tqdm(range(N_TIME_STEPS)):
        velocity, smoke, pressure = step(velocity, smoke, pressure)
        smoke_values_extracted = smoke.values.numpy("y,x")
        plt.imshow(smoke_values_extracted, origin="lower")
        camera.snap()

    animation = camera.animate()
    animation.save('media/smoke_plume_torch.gif')
    print("Done!")


if __name__ == "__main__":
    main()

Phiflow grid to Pytorch tensor/model

Hi, I have encountered several problems while combining PhiFlow with Pytorch:

When combining PhiFlow with the self-defined PyTorch model, how to gracefully input PhiFlow grid data, and output grid data (with/without the same layout)?

  • I tried using field.native_call(model, grid) and it worked. But how can I make sure the native call processes the grid data in the right dimension I trained (e.g. 'vector, y, x' or 'vector, x, y')?

  • What if the model's output doesn't have the same layout as the input (e.g. input 'vector, y, x' output 'y, x')?

  • Also, I tried converting the PhiFlow tensor to Pytorch tensor (e.g. CenterGrid velocity.values.native("vector,y,x"), then input the Pytorch tensor into the Pytorch model. I wondered if there is a graceful way to input and output grid data for the Pytorch model.

Looking forward to your reply!

view cannot be created except in a module

the following code cannot be executed as a cell in a jupyter notebook or python REPL:

from phi.torch.flow import *
viewer = view()

We get an error in that case:

AttributeError                            Traceback (most recent call last)
Input In [3], in <cell line: 37>()
     33     viewer.info(f"Model loaded.")
     36 prediction = CenteredGrid((0, 0), extrapolation.BOUNDARY, x=64, y=64)
---> 37 viewer = view('divergence', scene=True, namespace=globals(), select='batch')
     38 save_model(0)
     39 reset()  # Ensure that the first run will be identical to every time reset() is called

File ~/Source/fno_inversion_2022/venv/lib/python3.9/site-packages/phi/vis/_vis.py:138, in view(play, gui, name, description, scene, keep_alive, select, framerate, namespace, log_performance, *fields, **config)
    100 """
    101 Show `fields` in a graphical user interface.
    102 
   (...)
    133     `Viewer`
    134 """
    135 default_namespace = get_user_namespace(1)
    136 user_namespace = default_namespace if namespace is None else DictNamespace(namespace,
    137                                                                            title=default_namespace.get_title(),
--> 138                                                                            description=default_namespace.get_description(),
    139                                                                            reference=default_namespace.get_reference())
    140 variables = _default_field_variables(user_namespace, fields)
    141 actions = dict(ACTIONS)

File ~/Source/fno_inversion_2022/venv/lib/python3.9/site-packages/phi/vis/_user_namespace.py:175, in LocalNamespace.get_description(self)
    173     return self.function.__doc__
    174 else:
--> 175     return f"Function `{self.function_name}()` in '{self.module.__file__}'"

AttributeError: 'NoneType' object has no attribute '__file__'

Presumably this is because the module is undefined when we are not in a module. Would it be of interest to replace module.__file__ with something else (a hash?) in this case?

raw pytorch tensors

supposing I'm working solely in pytorch, can you advise on the best practice / expected use of PhiFlow in these cases?

initial_smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=32, y=40, bounds=Box[0:32, 0:40])

initial_velocity = StaggeredGrid(math.zeros(batch(inflow_loc=4)), extrapolation.ZERO, x=32, y=40, bounds=Box[0:32, 0:40])

I guess I'm digging around for initial_smoke.torch_tensor() or something, I played w/initial_smoke.values() but that seems a layer up from what I'm expecting... I could of course convert between numpy and pytorch directly by fetching the numpy tensors/arrays, but that would cause undesirable fetching between cpu and gpu...aside from the obvious breaking of autograd.

Then I'm also looking for an equivalent like torch.from_numpy(some_torch_tensor) but to construct a trivial grid in order to use PhiFlow.

Essentially I'm trying to mix and match the functionality instead of completely integrating everything as PhiFlow. Will this be awkward w/how things are set up currently? Sorry if this is covered in docs somewhere, some of the examples seem broken for the moment.

Moving PyTorch backend tensors between GPU and CPU

Hello,

I'm working with PhiFlow's PyTorch backend. At the beginning of my code, I specify the GPU as my default device by the following snippet.

from phi.torch.flow import *
TORCH.set_default_device('GPU')

Suppose for example, later in my code, I'd like to track the learning history of some grids, so I'd like to move them to the CPU in order to save memory on my GPU. In native PyTorch, I'd call something like tensor.cpu() or tensor.to("cpu"). I'm wondering if there is an API in PhiFlow that does the same thing? I couldn't find it in the documentation, but I might be missing something here.

Looking at previous issues (#38), I came up with a workaround that looks something like the following, but it seems very cumbersome.

from phi.torch.flow import *
TORCH.set_default_device('GPU')

# Step 1 - Create a smoke grid on the GPU
test_smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=resolution, y=resolution, bounds=Box(x=resolution, y=resolution))
print(test_smoke.values.native(order=test_smoke.shape).device)
# cuda:0

# Step 2 - Intermediate PyTorch tensor to move to the CPU
test_smoke_pt_tensor = test_smoke.values.native(order=test_smoke.shape).to("cpu")
print(test_smoke_pt_tensor.device)
# cpu

# Step 3 - Reconstruct the grid from the CPU tensor
test_smoke_cpu = test_smoke.with_values(tensor(test_smoke_pt_tensor, test_smoke.shape))
print(test_smoke_cpu.values.native(order=test_smoke.shape).device)
# cpu

Thanks for your help!

How to convert a velocity.values to numpy array properly?

For example, in ./demos/smoke_plume.py. I try to get velocity grid values

""" Smoke Plume
Hot smoke is emitted from a circular region at the bottom.
The simulation computes the resulting air flow in a closed box.
"""
from phi.flow import *  

velocity = StaggeredGrid((0, 0), 0, x=64, y=64, bounds=Box(x=100, y=100))  # or CenteredGrid(...)
smoke = CenteredGrid(0, extrapolation.BOUNDARY, x=200, y=200, bounds=Box(x=100, y=100))
INFLOW = 0.2 * CenteredGrid(SoftGeometryMask(Sphere(x=50, y=9.5, radius=5)), 0, smoke.bounds, smoke.resolution)
pressure = None

# @math.jit_compile  # Only for PyTorch, TensorFlow and Jax
def step(v, s, p, dt=1.):
    s = advect.mac_cormack(s, v, dt) + INFLOW
    buoyancy = s * (0, 0.1) @ v  # resamples smoke to velocity sample points
    v = advect.semi_lagrangian(v, v, dt) + buoyancy * dt
    v, p = fluid.make_incompressible(v, (), Solve('auto', 1e-5, 0, x0=p))
    return v, s, p

for _ in view(smoke, velocity, 'pressure', play=False, namespace=globals()).range(warmup=1):
    velocity, smoke, pressure = step(velocity, smoke, pressure)
    if _ == 10:        
        print(velocity.values.numpy('x,y'))
        break

then it throw error:

AssertionError: Dimension (vectorᶜ=x,y) missing from 'order'. Got ('x', 'y') but tensor has shape (xˢ=(x=63, y=64), yˢ=(x=64, y=63), vectorᶜ=x,y).

so I have to get velocity Tensor values in this way, but it's so werid.

...
for _ in view(smoke, velocity, 'pressure', play=True, namespace=globals()).range(warmup=1):
    velocity, smoke, pressure = step(velocity, smoke, pressure)
    if _ == 10:
        v_x = velocity.values.unstack('vector')[0].numpy('x,y')
        v_y = velocity.values.unstack('vector')[1].numpy('x,y')
        print(v_x.shape,v_y.shape)
        break

Output:

(63, 64) (64, 63)

So, Is there any better way to get the velocity valus?

And one more question, Why the shape of grid is (63, 64) (64, 63) instead of (64, 64) (64, 64) ?
Thanks

Manual PyTorch Implementation

Currently I am trying to adapt manual_numpy_or_tf.py demo to PyTorch, with some additional changes. However, I could not make it work with PyTorch at all. The simplified steps are:

1- Create Fluid object, which will consist of numpy.ndarray by default.

FLOW = Fluid(Domain([RES] * DIM, boundaries=OPEN), batch_size=BATCH_SIZE, buoyancy_factor=0.2)

2- Copy this object to PyTorch

FLOW_TORCH = torch_from_numpy(FLOW)

3- (After some unrelated operations) Sample velocity at points of density

x_rho = DENSITY.points.data
v_rho = VELOCITY.sample_at(x_rho)

Problems occur at this stage. First of all, type of x_rho is still numpy.ndarray, not torch.Tensor.
Secondly, sample_at operation throws the error:

 File "/Users/oguzziya/miniconda3/envs/phiflow/lib/python3.6/site-packages/phi/torch/torch_backend.py", line 381, in cast
    dtype = {np.float16: torch.float16, np.float32: torch.float32, np.float64: torch.float64, np.bool: torch.bool, np.int8: torch.int8, np.int16: torch.int16, np.int32: torch.int32, np.int64: torch.int64}[dtype]
KeyError: dtype('float32')

I would be glad to hear any opinions, possible fixes, or steps that I overlook.

Thank you

Troublesome NaNs in optimizations

Hello!

I'm using PhiFlow with the torch backend to optimize a sequence of control forces in a fluid solver to match sequential frames in a hand-created morph animation, and I'm running into various issues.

It seems that for short sequences of frames, optimization finds a passable set of control forces, but for longer sequences of frames, the optimizer begins to throw NaNs and other errors associated with gradients of make_incompressible() and other things (found using torch.autograd.set_detect_anomaly(True)).

I've attached a minimal example of the issue I'm running into (using randomized tensor sequences just to keep things compact); any advice would be greatly appreciated.
minimal_err.txt

Many thanks! Phiflow is quite enjoyable to use.

`matplotlib.pyplot.show` does not show figure phiflow plots in jupyter

Possibly I am missing something obvious.

According to the manual, and also matplotlib general practice, if we want to show multiple plots we call matplotlib.pyplot.show multiple times. that does not work with figures generated from phi.vis; in fact, calling show suppresses image display:

Screen Shot 2022-07-06 at 12 05 47

If I want to plot two things from one notebook cell, what should I be doing?

python code to reproduce:

from phi.flow import *
from phi import math
from matplotlib import pyplot as plt
velocity1 = StaggeredGrid(
    Noise(),
    x=10, y=10
)
velocity2 = StaggeredGrid(
    Noise(),
    x=10, y=10
)
vis.plot(velocity1)
plt.show()
vis.plot(velocity2)
plt.show()

How to implement the karman vortex street with rotation cylinder

Hi,

I want to use the Phiflow to simulate the karman vortex street with rotation cylinder. But I don't really understand the demo https://github.com/tum-pbs/PhiFlow/blob/master/demos/karman_vortex_street.py.

Specifically, I don't understand how to set the boundary condition? For example, my boundary conditions are:

  1. (0,0) at top and bottom boundary
  2. (y^2, 0) at the left boundary
  3. tangential speed=2 in the cylinder boundary

Thanks for your wonderful tool and thanks for your help.

#enhencement - Include obstacles boundary conditions in implicit methods

Hello,
This is just a feature request to know if a function for applying obstacle boundary conditions when using diffuse.implicit method exists.
If not, is it something that will be implemented in the future ?

For now, the only way I see to solve diffusion equation in an environment with rectangular obstacles is to use explicit scheme, a binary mask for the obstacles and multiplying both at each time step. Is there already an other way ?

Thank you.

How to properly define extrapolations for a velocity field?

I'm strugling to set the extrapolations of a velocity field. For example, how to set an inflow boundary condition on the left side, and neumann conditions on the others?

Among other things, I tried this:

inflow_tensor = pf.math.tensor([1., 0.], pf.channel(vector='x,y'))
extrapolations = pf.extrapolation.combine_sides(x=(pf.extrapolation.ConstantExtrapolation(inflow_tensor), pf.extrapolation.BOUNDARY),
                                                y=(pf.extrapolation.BOUNDARY, pf.extrapolation.BOUNDARY))

But it has no effect when doing my simple fluid simulation (advect and make_incompressible)
Moreover I can't compile a function using this velocity field like this.

I know I can bypass this issue by setting a BOUNDARY extrapolation on each side and setting the velocity on the lower x at each step, like in the pipe demo, but physically it is not the same, especially in the make_incompressible step. I've been trying to dig into how extrapolations are used in calculations, but I'm not yet comfortable enough with phiflow to understand it all. ^^

What is the correct way to set extrapolations?

How to set different dx values for different dimensions in math.spatial_gradient()

Hi,

Currently, the doc says that the dx argument of the math.spatial_gradient() function is a float. However, reading into the source code, it seems that it is possible to specify different increments for different dimensions, when the dims argument contains more than 1 dimensions.

Could the doc be updated, possibly with an example to make this clearer?

JIT compilation failes when using implicit diffusion

Hello, it's me again,
I open this issue because I updated my phiflow version to 2.3.2 and tried to run the following code :

import numpy as np
import jax.numpy as jnp
import matplotlib.pyplot as plt
from snake_ai.utils import Direction
from snake_ai.physim import ConvolutionWindow, GradientField
from phi.jax import flow

@flow.math.jit_compile
def explicit_diffusion(concentration : flow.field.Field, obstacle_mask : flow.field.Field, diffusivity : float, dt : float) -> flow.field.Field:
    return (1-obstacle_mask) * flow.diffuse.explicit(concentration, diffusivity=diffusivity, dt=dt)

@flow.math.jit_compile
def implicit_diffusion(concentration : flow.field.Field, obstacle_mask : flow.field.Field, diffusivity : float, dt : float) -> flow.field.Field:
    return (1-obstacle_mask) * flow.diffuse.implicit(concentration, diffusivity=diffusivity, dt=dt)

field = flow.CenteredGrid(flow.Noise(0.1, 0.1), x=10, y=10)
obstacle = flow.Box(x=(4,6), y=(4,6))
obstacle_mask = flow.CenteredGrid(obstacle, x=10, y=10)

initial_field = (1-obstacle_mask) * field
t=0
dt = 0.1
while t < 1:
    # field = explicit_diffusion(field, obstacle_mask, diffusivity=1, dt=dt)
    field = implicit_diffusion(field, obstacle_mask, diffusivity=1, dt=dt)
    t+=dt

flow.vis.plot([initial_field, field])
plt.show()

As one can see, I'm using jax >= 0.3 as backend in order to JIT compile my code. It's a very basic exemple where I diffuse a random field while taking into account absorbing conditions on an obstacle in the center of the scene.

When I try to run the above code with the flow.diffuse.explicit method it works fine, even when I decorate the function with flow.math.jit_compile. Nevertheless, when I try to use flow.diffuse.implicit with the jit_compile decorator, I get the following exception (I removed the JAX specific stack-trace) :

The stack trace below excludes JAX-internal frames.
The preceding is the original exception that occurred, unmodified.

--------------------

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/rcremese/projects/snake-ai/src/snake_ai/draft.py", line 25, in <module>
    field = implicit_diffusion(field, obstacle_mask, diffusivity=1, dt=dt)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_functional.py", line 206, in __call__
    native_result = self.traces[key](*natives)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/jax/_jax_backend.py", line 168, in run_jit_f
    return self.as_registered.call(jit_f, *args, name=f"run jit-compiled '{f.__name__}'")
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/backend/_backend.py", line 354, in call
    return f(*args)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_functional.py", line 177, in jit_f_native
    result = self.f(**kwargs, **in_key.auxiliary_kwargs)  # Tensor or tuple/list of Tensors
  File "/home/rcremese/projects/snake-ai/src/snake_ai/draft.py", line 14, in implicit_diffusion
    return (1-obstacle_mask) * flow.diffuse.implicit(concentration, diffusivity=diffusivity, dt=dt)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/physics/diffuse.py", line 63, in implicit
    return solve_linear(sharpen, y=field, solve=solve)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_optimize.py", line 524, in solve_linear
    matrix, bias = f.sparse_matrix_and_bias(solve.x0, *f_args, **f_kwargs)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_functional.py", line 366, in sparse_matrix_and_bias
    return self._get_or_trace(key, args, kwargs)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_functional.py", line 303, in _get_or_trace
    matrix, bias = matrix_from_function(self.f, *args, **f_kwargs, auto_compress=True)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_trace.py", line 272, in matrix_from_function
    result = f(**x_kwargs, **aux_args)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/physics/diffuse.py", line 59, in sharpen
    return explicit(x, diffusivity, -dt, substeps=order)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/physics/diffuse.py", line 34, in explicit
    delta = laplace(field, weights=amount) if 'vector' in shape(amount) else amount * laplace(field)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/field/_field.py", line 227, in __mul__
    return self._op2(other, lambda d1, d2: d1 * d2)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/field/_field.py", line 295, in _op2
    other = math.tensor(other)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_tensors.py", line 1753, in tensor
    data = convert_(data, use_dlpack=False)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/backend/_backend.py", line 1515, in convert
    nparray = current_backend.numpy(tensor)
  File "/home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/jax/_jax_backend.py", line 99, in numpy
    return np.array(x)
jax._src.errors.TracerArrayConversionError: The numpy.ndarray conversion method __array__() was called on the JAX Tracer object Traced<ShapedArray(float64[], weak_type=True)>with<DynamicJaxprTrace(level=1/0)>
The error occurred while tracing the function native(implicit_diffusion) at /home/rcremese/mambaforge/envs/snake-env/lib/python3.9/site-packages/phi/math/_functional.py:173 for jit. This concrete value was not available in Python because it depends on the values of the arguments natives[0] and natives[1].
See https://jax.readthedocs.io/en/latest/errors.html#jax.errors.TracerArrayConversionError

The problem arrises only when I try to JIT-compile the function because when I remove the decorator the code works fine.
If you need any supplementary information don't hesitate to contact me.
Sincerely your.

Question about Lagrangian Fluid Simulation

Hi all,

Thanks for creating this great framework, the differentiability opens up so many possibilities! I am currently working on some control tasks where Lagrangian fluid simulation makes more sense. I know PhiFlow is a Eulerian fluid simulation, but I was wondering whether it can be somehow used for doing Lagrangian simulation. (I'm a bit new to fluid mechanics so I'm not 100% sure if this makes sense as something to do). I would really appreciate your insight. Given your familiarity with the field, I would either way appreciate any ideas on whether differentiable Lagrangian fluid simulation is possible. Or any other frameworks you know of (I know there is some work on learned simulators, but differentiable physics is naturally more robust.) Thanks very much!

Sincerely,
Arjun

trivial demo example on GPU

Curious if you have a minimal example ala https://github.com/tum-pbs/PhiFlow/blob/master/demos/smoke_plume.py that would demonstrate pushing the simulation onto the GPU backend selected. For example I'm importing phiflow like from phi.torch.flow import *, but not sure what the 'phiflow' way of making sure they're using cuda tensors under the hood. Should I just access the native tensors and overwrite them w/CUDA versions (by moving them in pytorch myself)?

Use of deprecated numpy.object

Several parts of the math package use np.object , which is deprecated in the latest version of numpy.
This results in an attribute error whenever the phiflow package is imported.
AttributeError: module 'numpy' has no attribute 'object'

The error can be fixed by changing np.object usages to np.object_ as per numpy documentation

JIT compile moving obstacles

Many thanks for your great fluid simulation package!

Is it possible to use @math.jit_compile when simulation involves moving obstacles? Currently, it becomes much slower and gives a warning: WARNING:tensorflow:6 out of the last 6 calls to <function JitFunction._jit_compile..jit_f_native at 0x7fa7a14e31f0> triggered tf.function retracing. With static obstacles jit_compile works great and gives significant speedup. See code below which is adapted from the demo example:

from phi.tf.flow import *
DOMAIN = dict(x=30, y=30)
DT = 0.1

def move_obstacle(obs: Obstacle):
    if (obs.geometry.center[0]) > 35:
        new_geometry = Box(x=(-6, 0), y=(10, 16))
    else:
        new_geometry = obs.geometry.shifted([1. * DT, 0])
    return obs.copied_with(geometry=new_geometry)


obstacle = Obstacle(Box(x=(5, 11), y=(10, 16)), velocity=[1., 0], angular_velocity=tensor(0,))
velocity = StaggeredGrid(0, extrapolation.ZERO, **DOMAIN)
obstacle_mask = CenteredGrid(HardGeometryMask(obstacle.geometry), extrapolation.BOUNDARY, **DOMAIN)
pressure = None

@math.jit_compile
def step(velocity, obstacle):
    velocity = advect.mac_cormack(velocity, velocity, DT)
    velocity, pressure = fluid.make_incompressible(velocity, (obstacle,))
    return velocity, pressure

for _ in view(velocity, obstacle_mask, play=True, namespace=globals(), port=6006).range():
    obstacle = move_obstacle(obstacle)
    velocity, pressure = step(velocity, obstacle)
    fluid.masked_laplace.tracers.clear()  # we will need to retrace because the matrix changes each step. This is not needed when JIT-compiling the physics.
    obstacle_mask = HardGeometryMask(obstacle.geometry) @ pressure

Check for obstacles instance in phi.physics.fluid.apply_boundary_conditions

Hello,
I'm kind of new using PhiFlow so I might do mistakes. But, while trying to implement a very simple 2D diffusion equation with obstacles, I faced some problems.

  • First, it's hard from the documentation to understand how to use the GeometryMask class. For exemple, figuring out what the @ symbole is used to in the creation of an obstacle mask is hard to understand from the API documentation (ex: obs_mask = SoftGeometryMask(obstacle.geometry, balance=1) @ velocity)

  • Second, there is no type checking in the apply_boundary_conditions function for the input variable, leading to a strange TypeError: 'Obstacle' object is not iterable when calling the function with only one istance of an Obstacle instead of a list of obstacles. Handling the case where there is only one obstacle might be usefull. Otherwise, a simple type check assert isinstance(obstacles, (tuple, list)) would do the job.

  • Third, why do Obstacle and apply_boundary_conditions are bounded to the physic.fluid submodule and not accessible from the flow module ? Boundary conditions and obstacles can be applied outside of a CFD problem, isn't it ?

Nevertheless, thank you for your work on all of this, I'm very existed to use your package to implement PDE with JAX !

Are there any ways to optimize inflow locations?

In this demo, it is explained to obtain grad of grid values.

However, I'd like to optimize the center location of inflow like this:

# informal code
inflow_location = tensor(...)
initial_inflow = CenteredGrid(Sphere(inflow_location, ...), ...)

inflow_location_grad = # I want this

inflow_location -= 1e-2 * inflow_location_grad

Is it possible?

Burgers' Physics: Diffusion before advection step

In the Burgers Physics class, in the step_velocity method, the advection step is performed after the diffusion step, in contrast to earlier versions. Unfortunately, I am not involved deeply enough in this topic to tell if this is a bug or intended behavior; however, reversing the order seemed to resolve an issue for me where velocity field effects were not correctly applied (see code at the end). Furthermore, the current version seemed more prone to instability issues when processing large fields (e.g. field size (128,)) with low diffusion substep counts (e. g. 1).

from phi.flow import *
import numpy as np

@struct.definition()
class GaussianClash(AnalyticField):

    def __init__(self, batch_size):
        AnalyticField.__init__(self, rank=1)
        self.batch_size = batch_size

    def sample_at(self, idx, collapse_dimensions=True):
        leftloc = np.random.uniform(0.2, 0.4, self.batch_size)
        leftamp = np.random.uniform(0, 3, self.batch_size)
        leftsig = np.random.uniform(0.05, 0.15, self.batch_size)
        rightloc = np.random.uniform(0.6, 0.8, self.batch_size)
        rightamp = np.random.uniform(-3, 0, self.batch_size)
        rightsig = np.random.uniform(0.05, 0.15, self.batch_size)
        idx = np.swapaxes(idx, 0, -1)  # batch last to match random values
        left = leftamp * np.exp(-0.5 * (idx - leftloc) ** 2 / leftsig ** 2)
        right = rightamp * np.exp(-0.5 * (idx - rightloc) ** 2 / rightsig ** 2)
        result = left + right
        result = np.swapaxes(result, 0, -1)
        return result

    @struct.constant()
    def data(self, data):
        return data


@struct.definition()
class GaussianForce(AnalyticField):
    def __init__(self, batch_size):
        AnalyticField.__init__(self, rank=1)
        self.loc = np.random.uniform(0.4, 0.6, batch_size)
        self.amp = np.random.uniform(-0.05, 0.05, batch_size) * 32
        self.sig = np.random.uniform(0.1, 0.4, batch_size)

    def sample_at(self, idx, collapse_dimensions=True):
        idx = np.swapaxes(idx, 0, -1)  # batch last to match random values
        result = self.amp * np.exp(-0.5 * (idx - self.loc) ** 2 / self.sig ** 2)
        result = np.swapaxes(result, 0, -1)
        return result

    @struct.constant()
    def data(self, data):
        return data


domain = Domain((32,), box=box[0:1])
dt = 0.03
viscosity=0.003

s0 = BurgersVelocity(domain, velocity=GaussianClash(1), viscosity=viscosity)
f = FieldEffect(GaussianForce(1), ['velocity'])
p = Burgers()


# Only one simulation step
s0_sim = p.step(s0, dt=dt)
# Simulation step with force application
s0_sim_f = p.step(s0, dt=dt, effects=(f,))        

delta = s0_sim_f.velocity.data - s0_sim.velocity.data

# Reconstructed forces
f_a = delta / dt
# Original forces of field effect
f_b = f.field.at(s0_sim.velocity).data

# Should be close to zero?
print(np.sum(np.abs(f_a - f_b)))

# Using PhiFlow 1.4.0 this produces an error < 1e-4,
# using Phiflow 1.5.1 this error usually is > 1e0

# Reversing the order of advection and diffusion in 1.5.1
# decreases the error to < 1e-4

removed matplotlib function in vis animate code

vis animate code uses figboxes on line 75.
This was deprecated in matplotlib 3.4 and has been completely removed since.

So this running this function as shown in many tutorials will raise AttributeError: 'AxesSubplot' object has no attribute 'figbox' error to the end user.

To return the original functionality the line will need to be altering following this issue on the matplotlib repo.

MPS device/MAC GPU

How hard would it be to enable the Mac M1/M2 GPU devices in phiflow? It seems that phiflow currently only searches the cuda backend for devices. Are the phiflow cuda kernels only used for tensorflow? Maybe it could allow the MPS backend in pytorch, if pytorch already includes kernels for grid interpolation?

random initialized velocity fields

I see ways to initialize velocity fields with a single shape, but can I generate several simultaneously? I'm looking to replicate some of TempoGAN's dataset with randomly initialized velocities.

Dot product of tensor with a grid

How can I write the inner product between a tensor and locations on the grid?

I have in my simulation code a function $$r(x) = e^{- C \cdot x}$$, where $C: R^{k \times d}$ where $d$ is the dimensionality of the grid/state space.

So in my code I have the following:

C = math.random_normal(batch(neurons=3), channel(vector=['x','y']))

def U_f(xs): #   
    r = lambda xx:  C.vector['x']*xx.vector['x'] + C.vector['y']*xx.vector['y']     ##here I want to rewrite this as dot product 
    U = phi.math.exp( - r(xs) )     
    return U

DOMAIN = dict(  x=nx, y=ny, bounds=Box(x=(low_x, up_x), y=(low_y, up_y) ) )

g1 = lambda xs: U_f(xs)
Ut = CenteredGrid(g1, extrapolation.ZERO, **DOMAIN)

However I would like to express the dot product $C\cdot x$ so that I wouldn't have to alter my code when I change the dimensionality of the grid.
Do you have any clue on this?

arguments of math.spatial_gradient not available in field.spatial_gradient

Hi,

Thanks for creating the tool. I'm still learning it.

I noticed that field.spatial_gradient() calls internally math.spatial_gradient(), but some arguments to the latter (e.g. difference, dims) are not available to the former. Is there any reason these are not made available? I feel that it might be helpful to be able to specify along which dimension to compute the gradients, in a forward or centered difference manner.

Also, does it make good sense to also make spatial_gradient() available as a method of the Field class?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.