[docs]classP3MCalculator(PMECalculator):r""" Potential using a particle-particle particle-mesh based Ewald (P3M). For getting reasonable values for the ``smearing`` of the potential class and the ``mesh_spacing`` based on a given accuracy for a specific structure you should use :func:`torchpme.tuning.tune_p3m`. This function will also find the optimal ``cutoff`` for the **neighborlist**. .. hint:: For a training exercise it is recommended only run a tuning procedure with :func:`torchpme.tuning.tune_p3m` for the largest system in your dataset. :param potential: A :py:class:`Potential` object that implements the evaluation of short and long-range potential terms. The ``smearing`` parameter of the potential determines the split between real and k-space regions. For a :py:class:`torchpme.lib.CoulombPotential` it corresponds to the smearing of the atom-centered Gaussian used to split the Coulomb potential into the short- and long-range parts. A reasonable value for most systems is to set it to ``1/5`` times the neighbor list cutoff. :param mesh_spacing: Value that determines the umber of Fourier-space grid points that will be used along each axis. If set to None, it will automatically be set to half of ``smearing``. :param interpolation_nodes: The number ``n`` of nodes used in the interpolation per coordinate axis. The total number of interpolation nodes in 3D will be ``n^3``. In general, for ``n`` nodes, the interpolation will be performed by piecewise polynomials of degree ``n - 1`` (e.g. ``n = 4`` for cubic interpolation). Only the values ``1, 2, 3, 4, 5`` are supported. :param full_neighbor_list: If set to :py:obj:`True`, a "full" neighbor list is expected as input. This means that each atom pair appears twice. If set to :py:obj:`False`, a "half" neighbor list is expected. :param prefactor: electrostatics prefactor; see :ref:`prefactors` for details and common values. For an **example** on the usage for any calculator refer to :ref:`userdoc-how-to`. """def__init__(self,potential:Potential,mesh_spacing:float,interpolation_nodes:int=4,full_neighbor_list:bool=False,prefactor:float=1.0,):self.mesh_spacing:float=mesh_spacingifinterpolation_nodesnotin[1,2,3,4,5]:raiseValueError("Only `interpolation_nodes` from 1 to 5 are allowed")self.interpolation_nodes:int=interpolation_nodessuper(PMECalculator,self).__init__(potential=potential,full_neighbor_list=full_neighbor_list,prefactor=prefactor,)ifpotential.smearingisNone:raiseValueError("Must specify smearing to use a potential with P3MCalculator")cell=torch.eye(3,device=self.potential.smearing.device,dtype=self.potential.smearing.dtype,)ns_mesh=torch.ones(3,dtype=int,device=cell.device)self.kspace_filter:P3MKSpaceFilter=P3MKSpaceFilter(cell=cell,ns_mesh=ns_mesh,interpolation_nodes=self.interpolation_nodes,kernel=self.potential,mode=0,# Green's function for point-charge potentialsdifferential_order=2,# Order of the discretization of the differential operatorfft_norm="backward",ifft_norm="forward",)self.mesh_interpolator:MeshInterpolator=MeshInterpolator(cell=cell,ns_mesh=ns_mesh,interpolation_nodes=self.interpolation_nodes,method="P3M",)