Skip to content
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

Implement slicing support for LB #4143

Closed
RudolfWeeber opened this issue Mar 6, 2021 · 1 comment · Fixed by KaiserMartin/espresso#1 or #4195
Closed

Implement slicing support for LB #4143

RudolfWeeber opened this issue Mar 6, 2021 · 1 comment · Fixed by KaiserMartin/espresso#1 or #4195

Comments

@RudolfWeeber
Copy link
Contributor

i.e., lbf[4:20,:,1].velocity
or
lbf[:,:,:].velocity = np.zeros(lbf.shape))

  • the getitem() method of The LB Python class should accept slices
  • If slices are passed in, rather than an instance of LB Node, an instance of a new LBSlice class shuold be returned

An initial implementation of the LBSlice class should just act as proxy to single node getters. this can be done with 20-30 lines of Python. This will give the usability benefit immediately. A more efficient implementation can be done after the Walberla transition, if the performance increase is ever needed.

Steps:

  • In src/python/espressomd.lb.pyx, create a new class LBSlice

    • constructor should take three slice objects for x,y,z

    • indivudal properties:

    • Using those, calcualte the x,y,z dimensions of the resulting array (i.e., how many lattice sites are requested in each direction) should be (max-min)/step, or 1 if the value for the coordinate is a single int.

      • Find out the number and type of values per lb site (either hard-code 1 float for density, 3 floats for velocity, 3 ints for index, ...) or fetch the first value (e.g., lower left corner) using a single node getter
      • Shape the result array accordingly
      • Use a nested loop to fetch all the individual values and fill the result array
  • Modify the getimem() method of the lb fluid class in src/python/espresso/lb.pyx:

    If any of the arguments is an instance of slice, create an instance of LBSlice with the three arguments for x,y,z

Draft:

class LBSlice:

    def __init__(self, x,y,z, lb_fluid):
        self.x = x
        ...
        self.lb_fluid = lb_fluid
        self.dim = self.calculate_dimensions(x,y,z)

    def calculate_dimensions(x,y,z):
        # x,y,z either an instance of slcie or an int
        # Return tubple of 3 ints for the dimensions calculated from x,y,z
        return (...)

    
    def get_values(property_name, values_per_site, result_type):
        dim = self.dim
        res =  np.zeors((dim[0],dim[1],dim[22], values_per_site), dtype=result_type)
        for x in ...
           for y in ...
              for z in ...
                  res[x,y,z,:] = getattr(self.lb_fluid[x,y,z], property_name)
    def set_values(property_name, values): 
        for x in ...
           for y in ...
              for z in ...
                  setattr(self.lb_fluid[x,y,z], property_name, values[x,y,z])

    
    property velocity:
        def __get__(self):
           return self.get_vavlues("velocity", 3, float)
       def __set__(values):
           self.set_values("velocity", values)
# analogous for other properties like density
@RudolfWeeber
Copy link
Contributor Author

Coding day: Martin and Deniz

This was referenced Mar 25, 2021
@kodiakhq kodiakhq bot closed this as completed in #4195 Apr 1, 2021
kodiakhq bot added a commit that referenced this issue Apr 1, 2021
Fixes #4143

Description of changes:
- Modified __getitem__ to detect slices in input keys
- Introduced LBSlice class that calculates node indices from slice input and calls single node getter from LBFLuidRoutines class for every node in the slice.

The output is a multidimensional array containing the requested quantity and is of dimension len(slice_x)*len(slice_y)*len(slice_z)*len(quantity), where len(quantity) is the dimensions of the quantity, for example 3 in case of velocity. The output array is arranged in the way numpy cycles through slices. Therefore, when setting attributes one has to set the dimensions of the input array exactly the same way numpy cycles through the sliced nodes.
An error is issued if the dimensions of the slices and the input does not match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant