Masks in c2x

This rather artificial example is taken from c2x's test suite.

The results of a calculation on a six atom cell of diamond are in the test suite. This cell is formed of three layers, so it should be possible to cut it precisely into thirds.

The .cell file for the calculation was:

%block LATTICE_CART
  1.7850000  -1.7850000   0.0000000
  1.7850000   0.0000000  -1.7850000
  3.5700000   3.5700000   3.5700000
%endblock LATTICE_CART

%block POSITIONS_FRAC
  C  0.000000000  0.000000000  0.000000000
  C  0.000000000  0.000000000  0.250000000
  C  0.666666667  0.666666667  0.333333333
  C  0.666666667  0.666666667  0.583333333
  C  0.333333333  0.333333333  0.666666667
  C  0.333333333  0.333333333  0.916666667
%endblock POSITIONS_FRAC

KPOINT_MP_GRID 1 1 1
KPOINT_MP_OFFSET 0 0 0

And Castep produced an integrated charge density of 24 on a 27x27x54 grid.

$ c2x --null -vc diamond6.check
First FFT grid     27 27 54
spins=1   spinors=1
Found 3D data for Density
  min=0.0877441 max=2.49012 sum=27686.4 int=24
  (integral is e per cell for charge and spin densities)

A python mask

import numpy as np
a=np.zeros((27,27,54))
a[:,:,0:18]=1
np.save("mask.npy",a,allow_pickle=False)
a=1-a
np.save("mask_inv.npy",a,allow_pickle=False)

This mask is of the same size as the FFT grid, and has ones for all elements where the third index is between 1 and 18 (assuming indices start at 1). Note python's odd convention that an index range is specified as start:end+1, and that it indexes arrays from zero.

Masking the data

$ c2x --null -vc --mask diamond6.check mask.npy 
First FFT grid     27 27 54
spins=1   spinors=1
Found 3D data for Density
  min=0 max=2.49012 sum=9228.8 int=8
  (integral is e per cell for charge and spin densities)
$ c2x --null -vc --mask diamond6.check mask_inv.npy 
First FFT grid     27 27 54
spins=1   spinors=1
Found 3D data for Density
  min=0 max=2.49012 sum=18457.6 int=16
  (integral is e per cell for charge and spin densities)

The two masked integrals of 8 and 16 are precisely one third and two-thirds of the total integral of 24, as one would hope.

Note that the mask does not have to be simply zeros and ones. It can be any real, and it is applied by multiplication. It can be presented in any grid format, so .cube is certainly acceptable. One could even mask data with itself, which will square it.