-
Notifications
You must be signed in to change notification settings - Fork 647
feat(pt): add charge density prediction support #5999
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,121 @@ | ||||||||||||||||||||||||||||||||||||||
| # SPDX-License-Identifier: LGPL-3.0-or-later | ||||||||||||||||||||||||||||||||||||||
| from typing import ( | ||||||||||||||||||||||||||||||||||||||
| Any, | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| import numpy as np | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| from deepmd.dpmodel.output_def import ( | ||||||||||||||||||||||||||||||||||||||
| FittingOutputDef, | ||||||||||||||||||||||||||||||||||||||
| ModelOutputDef, | ||||||||||||||||||||||||||||||||||||||
| OutputVariableDef, | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| from .deep_eval import ( | ||||||||||||||||||||||||||||||||||||||
| DeepEval, | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| class DeepDensity(DeepEval): | ||||||||||||||||||||||||||||||||||||||
| """Charge density evaluated on grid points. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Parameters | ||||||||||||||||||||||||||||||||||||||
| ---------- | ||||||||||||||||||||||||||||||||||||||
| model_file : Path | ||||||||||||||||||||||||||||||||||||||
| The name of the frozen model file. | ||||||||||||||||||||||||||||||||||||||
| *args : list | ||||||||||||||||||||||||||||||||||||||
| Positional arguments. | ||||||||||||||||||||||||||||||||||||||
| auto_batch_size : bool or int or AutoBatchSize, default: True | ||||||||||||||||||||||||||||||||||||||
| If True, automatic batch size will be used. If int, it will be used | ||||||||||||||||||||||||||||||||||||||
| as the initial batch size. | ||||||||||||||||||||||||||||||||||||||
| neighbor_list : ase.neighborlist.NewPrimitiveNeighborList, optional | ||||||||||||||||||||||||||||||||||||||
| The ASE neighbor list class to produce the neighbor list. If None, the | ||||||||||||||||||||||||||||||||||||||
| neighbor list will be built natively in the model. | ||||||||||||||||||||||||||||||||||||||
| **kwargs : dict | ||||||||||||||||||||||||||||||||||||||
| Keyword arguments. | ||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||||||||||||||||
| def output_def(self) -> ModelOutputDef: | ||||||||||||||||||||||||||||||||||||||
| """Get the output definition of this model. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| The density is predicted on grid points rather than on atoms, but it | ||||||||||||||||||||||||||||||||||||||
| is declared with the same per-site output definition as the fitting | ||||||||||||||||||||||||||||||||||||||
| net of the model. | ||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||
| return ModelOutputDef( | ||||||||||||||||||||||||||||||||||||||
| FittingOutputDef( | ||||||||||||||||||||||||||||||||||||||
| [ | ||||||||||||||||||||||||||||||||||||||
| OutputVariableDef( | ||||||||||||||||||||||||||||||||||||||
| "density", | ||||||||||||||||||||||||||||||||||||||
| [1], | ||||||||||||||||||||||||||||||||||||||
| reducible=True, | ||||||||||||||||||||||||||||||||||||||
| r_differentiable=True, | ||||||||||||||||||||||||||||||||||||||
| c_differentiable=True, | ||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| def eval( | ||||||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||||||
| coords: np.ndarray, | ||||||||||||||||||||||||||||||||||||||
| cells: np.ndarray | None, | ||||||||||||||||||||||||||||||||||||||
| atom_types: list[int] | np.ndarray, | ||||||||||||||||||||||||||||||||||||||
| grid: np.ndarray, | ||||||||||||||||||||||||||||||||||||||
| fparam: np.ndarray | None = None, | ||||||||||||||||||||||||||||||||||||||
| aparam: np.ndarray | None = None, | ||||||||||||||||||||||||||||||||||||||
| mixed_type: bool = False, | ||||||||||||||||||||||||||||||||||||||
| **kwargs: dict[str, Any], | ||||||||||||||||||||||||||||||||||||||
| ) -> np.ndarray: | ||||||||||||||||||||||||||||||||||||||
| """Evaluate the density on grid points. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Parameters | ||||||||||||||||||||||||||||||||||||||
| ---------- | ||||||||||||||||||||||||||||||||||||||
| coords : np.ndarray | ||||||||||||||||||||||||||||||||||||||
| The coordinates of the atoms, in shape (nframes, natoms, 3). | ||||||||||||||||||||||||||||||||||||||
| cells : np.ndarray | ||||||||||||||||||||||||||||||||||||||
| The cell vectors of the system, in shape (nframes, 9). If the system | ||||||||||||||||||||||||||||||||||||||
| is not periodic, set it to None. | ||||||||||||||||||||||||||||||||||||||
| atom_types : list[int] or np.ndarray | ||||||||||||||||||||||||||||||||||||||
| The types of the atoms. If mixed_type is False, the shape is (natoms,); | ||||||||||||||||||||||||||||||||||||||
| otherwise, the shape is (nframes, natoms). | ||||||||||||||||||||||||||||||||||||||
| grid : np.ndarray | ||||||||||||||||||||||||||||||||||||||
| The coordinates of the grid points, in shape (nframes, ngrid, 3). | ||||||||||||||||||||||||||||||||||||||
| fparam : np.ndarray, optional | ||||||||||||||||||||||||||||||||||||||
| The frame parameters, by default None. | ||||||||||||||||||||||||||||||||||||||
| aparam : np.ndarray, optional | ||||||||||||||||||||||||||||||||||||||
| The atomic parameters, by default None. | ||||||||||||||||||||||||||||||||||||||
| mixed_type : bool, optional | ||||||||||||||||||||||||||||||||||||||
| Whether the atom_types is mixed type, by default False. | ||||||||||||||||||||||||||||||||||||||
| **kwargs : dict[str, Any] | ||||||||||||||||||||||||||||||||||||||
| Keyword arguments. | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| Returns | ||||||||||||||||||||||||||||||||||||||
| ------- | ||||||||||||||||||||||||||||||||||||||
| density | ||||||||||||||||||||||||||||||||||||||
| The density on the grid points, in shape (nframes, ngrid). | ||||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||||
| ( | ||||||||||||||||||||||||||||||||||||||
| coords, | ||||||||||||||||||||||||||||||||||||||
| cells, | ||||||||||||||||||||||||||||||||||||||
| atom_types, | ||||||||||||||||||||||||||||||||||||||
| fparam, | ||||||||||||||||||||||||||||||||||||||
| aparam, | ||||||||||||||||||||||||||||||||||||||
| nframes, | ||||||||||||||||||||||||||||||||||||||
| natoms, | ||||||||||||||||||||||||||||||||||||||
| ) = self._standard_input(coords, cells, atom_types, fparam, aparam, mixed_type) | ||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+99
to
+107
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win Remove the unused Ruff reports RUF059 at Line 106. Proposed fix- natoms,
+ _,📝 Committable suggestion
Suggested change
🧰 Tools🪛 Ruff (0.16.2)[warning] 106-106: Unpacked variable Prefix it with an underscore or any other dummy variable pattern (RUF059) 🤖 Prompt for AI AgentsSources: Coding guidelines, Linters/SAST tools |
||||||||||||||||||||||||||||||||||||||
| results = self.deep_eval.eval( | ||||||||||||||||||||||||||||||||||||||
| coords, | ||||||||||||||||||||||||||||||||||||||
| cells, | ||||||||||||||||||||||||||||||||||||||
| atom_types, | ||||||||||||||||||||||||||||||||||||||
| False, | ||||||||||||||||||||||||||||||||||||||
| fparam=fparam, | ||||||||||||||||||||||||||||||||||||||
| aparam=aparam, | ||||||||||||||||||||||||||||||||||||||
| grid=np.array(grid), | ||||||||||||||||||||||||||||||||||||||
| **kwargs, | ||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||
| return results["density"].reshape(nframes, -1) | ||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||
| __all__ = ["DeepDensity"] | ||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -212,6 +212,11 @@ def eval( | |||||||||||||||||
| aparam=aparam, | ||||||||||||||||||
| **kwargs, | ||||||||||||||||||
| ) | ||||||||||||||||||
| # TODO: if the grid is requested, we can directly return it without reshaping to energy, force and virial. We can also consider to return the grid in a separate key in the results dict, instead of reshaping it to energy, force and virial. | ||||||||||||||||||
| if "grid" in kwargs: | ||||||||||||||||||
| result = results["density"].reshape(nframes, -1) | ||||||||||||||||||
| return result | ||||||||||||||||||
|
Comment on lines
+215
to
+218
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Use the same non-null grid condition as If a caller passes Proposed fix- if "grid" in kwargs:
+ if kwargs.get("grid") is not None:📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||
|
|
||||||||||||||||||
| energy = results["energy_redu"].reshape(nframes, 1) | ||||||||||||||||||
| force = results["energy_derv_r"].reshape(nframes, natoms, 3) | ||||||||||||||||||
| virial = results["energy_derv_c_redu"].reshape(nframes, 9) | ||||||||||||||||||
|
|
||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| # SPDX-License-Identifier: LGPL-3.0-or-later | ||
| """Testing of models predicting charge density on grid points.""" | ||
|
|
||
| from deepmd.infer.model_test.base import ( | ||
| ChunkContext, | ||
| ModelTester, | ||
| _write_per_frame_details, | ||
| ) | ||
| from deepmd.utils.data import ( | ||
| DeepmdData, | ||
| ) | ||
| from deepmd.utils.eval_metrics import ( | ||
| mae, | ||
| rmse, | ||
| ) | ||
|
|
||
| __all__ = ["DensityTester"] | ||
|
|
||
|
|
||
| class DensityTester(ModelTester): | ||
| """Test a model of charge density on grid points.""" | ||
|
|
||
| report = ( | ||
| ("mae_density", "DENSITY MAE : {} units"), | ||
| ("rmse_density", "DENSITY RMSE : {} units"), | ||
| ) | ||
|
|
||
| def add_data_requirements(self, data: DeepmdData) -> None: | ||
| """Declare the labels a density test consumes.""" | ||
| dp = self.dp | ||
| # The grid and the density are defined on grid points rather than on | ||
| # atoms, and their extent (ngrid) is not known until the data is | ||
| # loaded. They are declared "atomic" so the loader keeps the | ||
| # frame-major layout without reshaping to natoms; see the grid/density | ||
| # early return in DeepmdData._load_data. | ||
| data.add("grid", 3, atomic=True, must=True, high_prec=True) | ||
| data.add("density", 1, atomic=True, must=True, high_prec=True) | ||
| if dp.get_dim_fparam() > 0: | ||
| data.add( | ||
| "fparam", dp.get_dim_fparam(), atomic=False, must=True, high_prec=False | ||
| ) | ||
| if dp.get_dim_aparam() > 0: | ||
| data.add( | ||
| "aparam", dp.get_dim_aparam(), atomic=True, must=True, high_prec=False | ||
| ) | ||
|
|
||
| def evaluate_chunk( | ||
| self, | ||
| data: DeepmdData, | ||
| test_data: dict, | ||
| context: ChunkContext, | ||
| ) -> dict[str, tuple[float, float]]: | ||
| """Evaluate one chunk of a density test.""" | ||
| dp = self.dp | ||
| mixed_type = data.mixed_type | ||
| nframes = test_data["box"].shape[0] | ||
|
|
||
| coord = test_data["coord"].reshape([nframes, -1]) | ||
| box = test_data["box"] if data.pbc else None | ||
| if mixed_type: | ||
| atype = test_data["type"].reshape([nframes, -1]) | ||
| else: | ||
| atype = test_data["type"][0] | ||
| fparam = test_data["fparam"] if dp.get_dim_fparam() > 0 else None | ||
| aparam = test_data["aparam"] if dp.get_dim_aparam() > 0 else None | ||
| grid = test_data["grid"] | ||
|
|
||
| prediction = dp.eval( | ||
| coord, | ||
| box, | ||
| atype, | ||
| grid, | ||
| fparam=fparam, | ||
| aparam=aparam, | ||
| mixed_type=mixed_type, | ||
| ).reshape(nframes, -1) | ||
| label = test_data["density"].reshape(nframes, -1) | ||
|
|
||
| diff = prediction - label | ||
| errors: dict[str, tuple[float, float]] = { | ||
| "mae_density": (mae(diff), diff.size), | ||
| "rmse_density": (rmse(diff), diff.size), | ||
| } | ||
|
|
||
| if context.detail_path is not None: | ||
| _write_per_frame_details( | ||
| context, | ||
| suffix="density", | ||
| reference=label, | ||
| prediction=prediction, | ||
| ) | ||
|
|
||
| return errors |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -20,6 +20,9 @@ | |||||||||||||||||||||||||||||||||||||||||||||
| OutputVariableCategory, | ||||||||||||||||||||||||||||||||||||||||||||||
| OutputVariableDef, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| from deepmd.infer.deep_density import ( | ||||||||||||||||||||||||||||||||||||||||||||||
| DeepDensity, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| from deepmd.infer.deep_dipole import ( | ||||||||||||||||||||||||||||||||||||||||||||||
| DeepDipole, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -440,6 +443,8 @@ def model_type(self) -> type["DeepEvalWrapper"]: | |||||||||||||||||||||||||||||||||||||||||||||
| return DeepWFC | ||||||||||||||||||||||||||||||||||||||||||||||
| elif "population" in model_output_type: | ||||||||||||||||||||||||||||||||||||||||||||||
| return DeepPopulation | ||||||||||||||||||||||||||||||||||||||||||||||
| elif "density" in model_output_type: | ||||||||||||||||||||||||||||||||||||||||||||||
| return DeepDensity | ||||||||||||||||||||||||||||||||||||||||||||||
| elif self.get_var_name() in model_output_type: | ||||||||||||||||||||||||||||||||||||||||||||||
| return DeepProperty | ||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -552,6 +557,17 @@ def eval( | |||||||||||||||||||||||||||||||||||||||||||||
| coords, atom_types, len(atom_types.shape) > 1 | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| request_defs = self._get_request_defs(atomic) | ||||||||||||||||||||||||||||||||||||||||||||||
| if "grid" in kwargs and kwargs["grid"] is not None: | ||||||||||||||||||||||||||||||||||||||||||||||
| out = self._eval_func(self._eval_model_density, numb_test, natoms)( | ||||||||||||||||||||||||||||||||||||||||||||||
| coords, | ||||||||||||||||||||||||||||||||||||||||||||||
| cells, | ||||||||||||||||||||||||||||||||||||||||||||||
| atom_types, | ||||||||||||||||||||||||||||||||||||||||||||||
| np.array(kwargs["grid"]), | ||||||||||||||||||||||||||||||||||||||||||||||
| fparam, | ||||||||||||||||||||||||||||||||||||||||||||||
| aparam, | ||||||||||||||||||||||||||||||||||||||||||||||
| request_defs, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| return {"density": out} | ||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+560
to
+570
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win Return the density array instead of the one-item tuple.
Proposed fix- return {"density": out}
+ return {"density": out[0]}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||
| if "spin" not in kwargs or kwargs["spin"] is None: | ||||||||||||||||||||||||||||||||||||||||||||||
| out = self._eval_func(self._eval_model, numb_test, natoms)( | ||||||||||||||||||||||||||||||||||||||||||||||
| coords, cells, atom_types, fparam, aparam, request_defs, charge_spin | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -916,6 +932,80 @@ def _eval_model_spin( | |||||||||||||||||||||||||||||||||||||||||||||
| ) # this is kinda hacky | ||||||||||||||||||||||||||||||||||||||||||||||
| return tuple(results) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def _eval_model_density( | ||||||||||||||||||||||||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||||||||||||||||||||||||
| coords: np.ndarray, | ||||||||||||||||||||||||||||||||||||||||||||||
| cells: np.ndarray | None, | ||||||||||||||||||||||||||||||||||||||||||||||
| atom_types: np.ndarray, | ||||||||||||||||||||||||||||||||||||||||||||||
| grid: np.ndarray, | ||||||||||||||||||||||||||||||||||||||||||||||
| fparam: np.ndarray | None, | ||||||||||||||||||||||||||||||||||||||||||||||
| aparam: np.ndarray | None, | ||||||||||||||||||||||||||||||||||||||||||||||
| request_defs: list[OutputVariableDef], | ||||||||||||||||||||||||||||||||||||||||||||||
| ) -> tuple[np.ndarray, ...]: | ||||||||||||||||||||||||||||||||||||||||||||||
| model = self.dp.to(DEVICE) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| nframes = coords.shape[0] | ||||||||||||||||||||||||||||||||||||||||||||||
| if len(atom_types.shape) == 1: | ||||||||||||||||||||||||||||||||||||||||||||||
| natoms = len(atom_types) | ||||||||||||||||||||||||||||||||||||||||||||||
| atom_types = np.tile(atom_types, nframes).reshape(nframes, -1) | ||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||
| natoms = len(atom_types[0]) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| coord_input = torch.tensor( | ||||||||||||||||||||||||||||||||||||||||||||||
| coords.reshape([nframes, natoms, 3]), | ||||||||||||||||||||||||||||||||||||||||||||||
| dtype=GLOBAL_PT_FLOAT_PRECISION, | ||||||||||||||||||||||||||||||||||||||||||||||
| device=DEVICE, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| type_input = torch.tensor(atom_types, dtype=torch.long, device=DEVICE) | ||||||||||||||||||||||||||||||||||||||||||||||
| grid_input = torch.tensor( | ||||||||||||||||||||||||||||||||||||||||||||||
| grid.reshape([nframes, -1, 3]), | ||||||||||||||||||||||||||||||||||||||||||||||
| dtype=GLOBAL_PT_FLOAT_PRECISION, | ||||||||||||||||||||||||||||||||||||||||||||||
| device=DEVICE, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| ngrid = grid_input.shape[1] | ||||||||||||||||||||||||||||||||||||||||||||||
| if cells is not None: | ||||||||||||||||||||||||||||||||||||||||||||||
| box_input = torch.tensor( | ||||||||||||||||||||||||||||||||||||||||||||||
| cells.reshape([nframes, 3, 3]), | ||||||||||||||||||||||||||||||||||||||||||||||
| dtype=GLOBAL_PT_FLOAT_PRECISION, | ||||||||||||||||||||||||||||||||||||||||||||||
| device=DEVICE, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||
| box_input = None | ||||||||||||||||||||||||||||||||||||||||||||||
| if fparam is not None: | ||||||||||||||||||||||||||||||||||||||||||||||
| fparam_input = to_torch_tensor( | ||||||||||||||||||||||||||||||||||||||||||||||
| fparam.reshape(nframes, self.get_dim_fparam()) | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||
| fparam_input = None | ||||||||||||||||||||||||||||||||||||||||||||||
| if aparam is not None: | ||||||||||||||||||||||||||||||||||||||||||||||
| aparam_input = to_torch_tensor( | ||||||||||||||||||||||||||||||||||||||||||||||
| aparam.reshape(nframes, natoms, self.get_dim_aparam()) | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||
| aparam_input = None | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| do_atomic_virial = any( | ||||||||||||||||||||||||||||||||||||||||||||||
| x.category == OutputVariableCategory.DERV_C_REDU for x in request_defs | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| batch_output = model( | ||||||||||||||||||||||||||||||||||||||||||||||
| coord_input, | ||||||||||||||||||||||||||||||||||||||||||||||
| type_input, | ||||||||||||||||||||||||||||||||||||||||||||||
| grid=grid_input, | ||||||||||||||||||||||||||||||||||||||||||||||
| box=box_input, | ||||||||||||||||||||||||||||||||||||||||||||||
| do_atomic_virial=do_atomic_virial, | ||||||||||||||||||||||||||||||||||||||||||||||
| fparam=fparam_input, | ||||||||||||||||||||||||||||||||||||||||||||||
| aparam=aparam_input, | ||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||
| if isinstance(batch_output, tuple): | ||||||||||||||||||||||||||||||||||||||||||||||
| batch_output = batch_output[0] | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| results = [] | ||||||||||||||||||||||||||||||||||||||||||||||
| pt_name = "density" | ||||||||||||||||||||||||||||||||||||||||||||||
| density_shape = [nframes, ngrid] | ||||||||||||||||||||||||||||||||||||||||||||||
| out = batch_output[pt_name].reshape(density_shape).detach().cpu().numpy() | ||||||||||||||||||||||||||||||||||||||||||||||
| results.append(out) | ||||||||||||||||||||||||||||||||||||||||||||||
| return tuple(results) | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
| def _get_output_shape( | ||||||||||||||||||||||||||||||||||||||||||||||
| self, odef: OutputVariableDef, nframes: int, natoms: int | ||||||||||||||||||||||||||||||||||||||||||||||
| ) -> list[int]: | ||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fitting implementation declares
densityas non-reducible and non-differentiable, but this evaluator inventsdensity_redu, coordinate-derivative, and cell-derivative definitions. In the PyTorch density path that also makes_get_request_defs()setdo_atomic_virial=Trueeven though no density virial exists. Please keep the public evaluator contract identical toDensityFittingNet.output_def().