Multidimensional array constraint issue

I was trying to implement a physics problem where constraints are in the form of 3D arrays. Following code snippet explains the problem setup (only a single constraint was used for the sake of depicting this issue).

    # grid generation
    cs_ar = np.reshape(np.array([[[c_s_0 for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))
    yp_ar = np.reshape(np.array([[[i*dy_a for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))
    xp_ar = np.reshape(np.array([[[j*dx_a for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))
    tp_ar0 = np.reshape(np.array([[[0.0 for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))

    #Constraint
    IC_an = PointwiseConstraint.from_numpy(
        nodes=nodes,
        invar={"x":xp_ar, "y":yp_ar, "t":tp_ar0},
        outvar={"c_s":cs_ar},
        batch_size=4,
    )
    domain.add_constraint(IC_an, "IC_an")

But the execution is stalling before the training starts

[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - Arch Node: battery_network has been converted to a FuncArch node.
[05:49:23] - attempting to restore from: outputs/Diffusion_numpy
[05:49:23] - optimizer checkpoint not found
[05:49:23] - model battery_network.0.pth not found

The execution does not proceed after this point. I waited for more than an hour.

This issue is not present when 1D arrays as expressed below are used for specifying constraints

    cs_ar = np.reshape(np.array([c_s_0 for i in range(N_an*Np_an*1)]), (N_an*Np_an*1,1))
    yp_ar = np.reshape(np.array([c_s_0 for i in range(N_an*Np_an*1)]), (N_an*Np_an*1,1))
    xp_ar = np.reshape(np.array([c_s_0 for i in range(N_an*Np_an*1)]), (N_an*Np_an*1,1))
    tp_ar0 = np.reshape(np.array([0.0 for i in range(N_an*Np_an*1)]), (N_an*Np_an*1,1))

I tried to implement the same constraint with 2D arrays of the form

    cs_ar = np.reshape(np.array([[c_s_0 for i in range(Np_an)] for j in range(N_an)]), (N_an,Np_an,1))
    yp_ar = np.reshape(np.array([[c_s_0 for i in range(Np_an)] for j in range(N_an)]), (N_an,Np_an,1))
    xp_ar = np.reshape(np.array([[c_s_0 for i in range(Np_an)] for j in range(N_an)]), (N_an,Np_an,1))
    tp_ar0 = np.reshape(np.array([[c_s_0 for i in range(Np_an)] for j in range(N_an)]), (N_an,Np_an,1))

and got the following error.

[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:16] - Arch Node: battery_network has been converted to a FuncArch node.
[04:19:17] - attempting to restore from: outputs/Diffusion_numpy
[04:19:17] - optimizer checkpoint not found
[04:19:17] - model battery_network.0.pth not found
Error executing job with overrides: []
An error occurred during Hydra's exception formatting:
AssertionError()
Traceback (most recent call last):
  File "/opt/conda/lib/python3.8/site-packages/hydra/_internal/utils.py", line 252, in run_and_report
    assert mdl is not None
AssertionError

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "Battery_numpy.py", line 278, in <module>
    run()
  File "/modulus/modulus/hydra/utils.py", line 91, in func_decorated
    _run_hydra(
  File "/opt/conda/lib/python3.8/site-packages/hydra/_internal/utils.py", line 377, in _run_hydra
    run_and_report(
  File "/opt/conda/lib/python3.8/site-packages/hydra/_internal/utils.py", line 294, in run_and_report
    raise ex
  File "/opt/conda/lib/python3.8/site-packages/hydra/_internal/utils.py", line 211, in run_and_report
    return func()
  File "/opt/conda/lib/python3.8/site-packages/hydra/_internal/utils.py", line 378, in <lambda>
    lambda: hydra.run(
  File "/opt/conda/lib/python3.8/site-packages/hydra/_internal/hydra.py", line 111, in run
    _ = ret.return_value
  File "/opt/conda/lib/python3.8/site-packages/hydra/core/utils.py", line 233, in return_value
    raise self._return_value
  File "/opt/conda/lib/python3.8/site-packages/hydra/core/utils.py", line 160, in run_job
    ret.return_value = task_function(task_cfg)
  File "Battery_numpy.py", line 272, in run
    slv.solve()
  File "/modulus/modulus/solver/solver.py", line 159, in solve
    self._train_loop(sigterm_handler)
  File "/modulus/modulus/trainer.py", line 593, in _train_loop
    self._record_constraints()
  File "/modulus/modulus/trainer.py", line 275, in _record_constraints
    self.record_constraints()
  File "/modulus/modulus/solver/solver.py", line 116, in record_constraints
    self.domain.rec_constraints(self.network_dir)
  File "/modulus/modulus/domain/domain.py", line 45, in rec_constraints
    constraint.save_batch(constraint_data_dir + key)
  File "/modulus/modulus/domain/constraint/continuous.py", line 77, in save_batch
    var_to_polyvtk(save_var, filename)
  File "/modulus/modulus/utils/io/vtk.py", line 945, in var_to_polyvtk
    points = np.concatenate(points, axis=1)
  File "<__array_function__ internals>", line 180, in concatenate
ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 3 dimension(s) and the array at index 2 has 2 dimension(s)

Is it because multidimensional arrays are not supported in modulus constraints?

a physics problem where constraints are in the form of 3D arrays

3D arrays are like cube or cuboid. Is that what you are saying?

ValueError: all the input arrays must have same number of dimensions, but the array at index 0 has 3 dimension(s) and the array at index 2 has 2 dimension(s)

The error tells you that xp_ar, yp_ar and tp_ar0 have different dimensions. This will obviosuly give you an error. If your constraints are u(x,y,t)at specific spatiotemporal locations just create a 2D array with size n*3. Where n is the number of BC points.
In your case, you need three 1D arrays for each x,y,t location. And right now xp_ar, yp_ar and tp_ar0 are definitely not 1D.

3D arrays are like cube or cuboid. Is that what you are saying?

Yes. If you look at the following constraints

    # grid generation
    cs_ar = np.reshape(np.array([[[c_s_0 for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))
    yp_ar = np.reshape(np.array([[[i*dy_a for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))
    xp_ar = np.reshape(np.array([[[j*dx_a for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))
    tp_ar0 = np.reshape(np.array([[[0.0 for i in range(Np_an)] for j in range(N_an)]for k in range(1)]), (1,N_an,Np_an,1))

    #Constraint
    IC_an = PointwiseConstraint.from_numpy(
        nodes=nodes,
        invar={"x":xp_ar, "y":yp_ar, "t":tp_ar0},
        outvar={"c_s":cs_ar},
        batch_size=4,
    )
    domain.add_constraint(IC_an, "IC_an")

there must be a 3D mesh grid for c_s(x,y,t), which in turn means that a 3D array is required to store values at each of the points. This mesh gird will also mean that the arrays xp_ar, yp_ar and tp_ar0 must be 3D as they are a part of the same constraint “IC_an” (all arrays must be of the same dimension for a particular constraint).

The error tells you that xp_ar , yp_ar and tp_ar0 have different dimensions. This will obviosuly give you an error.

You can look at the dimensions of arrays. All of them are the same (definition of arrays in “grid_generation” code snippet). Also, the code stalls without giving error for the 3D array case. Error is observed only when 2D arrays are used.

In your case, you need three 1D arrays for each x,y,t location. And right now xp_ar , yp_ar and tp_ar0 are definitely not 1D.

I think this won’t work in my case as the function c_s(x,y,t) is part of the same constraint. All arrays must have the same dimension.

For documentation Modulus uses 1D arrays for its point constraints:

1 Like