def grid_calc(grid_obj, potential_name, ff_obj, rmass=None, T=None):
    """ 
          Calculates the energy grid using 'numba' , vectorized over the cpu

          :type grid_obj: instance of the grid object from the grid3D module.
          :param grid_obj: contains al the details for the energy grid calculation.

          :type potential_name: str
          :param potential_name: Name of the potential 'lj' or 'ljfh'

          :type ff_obj: Instance of the force field object from the forcefields module
          :param ff_obj: Contains all the mixing rules for a give functional form

          :raises: TypeError, NameError
          

          :rtype: Returns the 3D energy grid
          """
    import numpy as np
    import pyIsoP.potentials as potentials
    from tqdm import tqdm
    p = potentials.potentials()
    potential_form = getattr(p, str(potential_name))
    for k in tqdm(range(grid_obj.nz), desc=
        'Calculating grid: Current Z position'):
        for j in range(grid_obj.ny):
            for i in range(grid_obj.nx):
                grid_point = np.array([grid_obj.x_grid[i], grid_obj.y_grid[
                    j], grid_obj.z_grid[k]])
                diff_vec = grid_obj.coord - grid_point
                diff_vec = diff_vec - np.round(diff_vec)
                pbc_vec = np.dot(grid_obj.A, diff_vec.T).T
                rsq = np.sum(pbc_vec ** 2, axis=1)
                if potential_name == 'lj':
                    E = np.sum(potential_form(rsq, ff_obj.epsilon_array,
                        ff_obj.sigma_array))
                elif potential_name == 'ljfh' and T is not None and rmass is not None:
                    E = np.sum(potential_form(rsq, ff_obj.epsilon_array,
                        ff_obj.sigma_array, rmass, T))
                elif potential_name == 'ljfh' and (T is None or rmass is None):
                    raise TypeError(
                        'Missing T and rmass for Feynman-Hibbs correction')
                else:
                    raise NameError(
                        'Unknown potential: Add yours to potentials.py if need be'
                        )
                grid_obj.pot[i][j][k] = E
    grid_obj.pot_repeat = np.tile(grid_obj.pot, (grid_obj.nx_cells,
        grid_obj.ny_cells, grid_obj.nz_cells))
    return grid_obj
