diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9bc4d2d8..09a29e30 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,7 +59,8 @@ uv pip install $AMSHOME/scripting/scm/amspipe ``` or: ```bash -uv pip install $AMSHOME/scripting/wheels/amspipe-0.1-py3-none-any.whl +uv pip install --index-url "https://:@downloads.scm.com/Downloads/packages/uv/channels/2026.1/simple/" \ + scm-amspipe scm-external-engines plams ``` To run tests use: ```bash diff --git a/doc/source/components/functions.rst b/doc/source/components/functions.rst index c922c881..9357b64e 100644 --- a/doc/source/components/functions.rst +++ b/doc/source/components/functions.rst @@ -9,6 +9,7 @@ This chapter gathers information about public functions that can be used in PLAM .. autofunction:: init .. autofunction:: finish +.. autofunction:: jobs_in_directory .. autofunction:: load .. autofunction:: load_all .. autofunction:: read_molecules diff --git a/doc/source/components/settings.rst b/doc/source/components/settings.rst index 2533c495..ec72b77b 100644 --- a/doc/source/components/settings.rst +++ b/doc/source/components/settings.rst @@ -190,7 +190,16 @@ For example: config.job.pickle = False config.default_jobrunner = JobRunner(parallel=True, maxjobs=8) -The structure for the defined options on the nested settings objects is defined below. +A context manager ``config_context`` is provided to override the global ``config`` within a specific scope: + +.. autofunction:: scm.plams.core.functions.config_context + +This can be useful for temporarily disabling or changing global settings. +If you use this context manager, obtain ``config`` with the ``get_config`` function: + +.. autofunction:: scm.plams.core.functions.get_config + +The structure for all the defined options on the nested settings objects is defined below. .. autoclass:: ConfigSettings diff --git a/doc/source/components/utils.rst b/doc/source/components/utils.rst index 01938b5a..de7ad6d0 100644 --- a/doc/source/components/utils.rst +++ b/doc/source/components/utils.rst @@ -57,6 +57,8 @@ the :ref:`BalanceReactionEquationsExample` example. .. autofunction:: scm.plams.tools.reaction.balance +.. autoclass:: scm.plams.tools.reaction.ReactionEquation + Older functions: diff --git a/doc/source/examples/IonicConductivityFromMD.rst b/doc/source/examples/IonicConductivityFromMD.rst index 46d15fba..e9b761e5 100644 --- a/doc/source/examples/IonicConductivityFromMD.rst +++ b/doc/source/examples/IonicConductivityFromMD.rst @@ -5,16 +5,38 @@ Ionic conductivity from ams.rkf trajectory First, an ams.rkf trajectory with ions in the system needs to be calculated, as is done, for example, in the `Ionic Conductivity Tutorial <../../Tutorials/MolecularDynamicsAndMonteCarlo/IonicConductivity.html>`__. -Next, the ionic conductivity for the ions in the solution can be computed. The below script first identifies the ions in the molecular system, and guesses their charges (in the case of metals it uses a simple charge equilibration scheme). It then runs the AMS trajectory analysis tool to compute the ionic conductivity for these ions. +Next, the ionic conductivity for the ions in the solution can be computed. The script below first identifies the ions in the molecular system and guesses their charges (for metals, it uses a simple charge equilibration scheme). It then runs the AMS trajectory analysis tool to compute the ionic conductivity for these ions. **Example usage:** (:download:`Download get_ionic_conductivity.py <../../../examples/IonicConductivity/get_ionic_conductivity.py>`) -.. code-block:: none +.. code-block:: bash $AMSBIN/amspython get_ionic_conductivity.py /path/to/ams.rkf -To create an example ams.rkf file, a PLAMS script can be found here (:download:`Download NaClwater.py <../../../examples/IonicConductivity/NaClwater.py>`). This script is designed for efficiency. For a more reliable setup, follow the `Ionic Conductivity Tutorial <../../Tutorials/MolecularDynamicsAndMonteCarlo/IonicConductivity.html>`__. +To create an example ``ams.rkf`` file, you can use this PLAMS script (:download:`Download NaClwater.py <../../../examples/IonicConductivity/NaClwater.py>`). This script is designed for efficiency. For a more reliable setup, follow the `Ionic Conductivity Tutorial <../../Tutorials/MolecularDynamicsAndMonteCarlo/IonicConductivity.html>`__. .. literalinclude:: ../../../examples/IonicConductivity/get_ionic_conductivity.py - :language: python - + :language: python + +**Results** + +If you have used the ``ams.rkf`` generated from running ``$AMSBIN/amspython NaClwater.py``, +the output from ``get_ionic_conductivity.py`` should look something like: + +.. parsed-literal:: + Average temperature 298.166533 K + Ion N Charge + Na 5 1.00000 + Cl 5 -1.00000 + [20.02|15:06:43] JOB plamsjob STARTED + [20.02|15:06:43] JOB plamsjob RUNNING + [20.02|15:06:43] JOB plamsjob FINISHED + [20.02|15:06:43] JOB plamsjob SUCCESSFUL + Na 2.4739268145933062e-09 m2/s + [20.02|15:06:43] JOB plamsjob STARTED + [20.02|15:06:43] Renaming job plamsjob to plamsjob.002 + [20.02|15:06:43] JOB plamsjob.002 RUNNING + [20.02|15:06:43] JOB plamsjob.002 FINISHED + [20.02|15:06:43] JOB plamsjob.002 SUCCESSFUL + Cl 3.2624546292849828e-09 m2/s + Ionic conductivity: 2.6075090545e+01 Siemens/m diff --git a/doc/source/general.rst b/doc/source/general.rst index 3ae36419..a85b59e8 100644 --- a/doc/source/general.rst +++ b/doc/source/general.rst @@ -109,6 +109,47 @@ The latest (unreleased) development version can be downloaded from the `trunk br Once the downloaded zip file has been extracted, navigate to its location and run ``pip install .`` to install into your Python environment. +What's new in PLAMS for AMS2026? +-------------------------------------- + +Added +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Improved molecular visualization. The :func:`~scm.plams.tools.view.view` function allows visualization of molecules and chemical systems using AMSView, which can be easily rendered in a Jupyter notebook or saved as images. +* Improvements to the |JobAnalysis| tool for collecting and analyzing job results, with additional methods: + * :meth:`~scm.plams.tools.job_analysis.JobAnalysis.add_rkf_field` to simplify adding values from an RKF file to the analysis + * :meth:`~scm.plams.tools.job_analysis.JobAnalysis.get_settings_field_key` and :meth:`~scm.plams.tools.job_analysis.JobAnalysis.get_rkf_field_key` methods to simplify getting the keys for analysis fields +* Additional functionality to assist with workflows: + * :func:`~scm.plams.core.functions.jobs_in_directory` context manager to allow jobs to run in a subdirectory of the PLAMS working directory + * :meth:`~scm.plams.core.basejob.Job.delete` and :meth:`~scm.plams.core.basejob.Job.rename` methods for deleting/renaming job files and directories + * :meth:`~scm.plams.core.settings.JobSettings.on_status_change` callback, available on global ``config``, which fires any time a job status is updated and allows notifications when jobs finish or error + * :func:`~scm.plams.core.functions.config_context` context manager and :func:`~scm.plams.core.functions.get_config` function allow context-based override of global ``config`` settings +* Additional methods to get results from AMS calculations: + * :meth:`~scm.plams.interfaces.adfsuite.ams.AMSResults.get_pvdos` method to get partial vibrational spectra + * :meth:`~scm.plams.interfaces.adfsuite.ams.AMSResults.get_main_engine_name` + * :meth:`~scm.plams.interfaces.adfsuite.ams.AMSResults.get_reduced_masses` +* Dedicated job for Energy Decomposition Analysis in BAND |BANDFragmentJob| +* Method :meth:`~scm.plams.tools.reaction.balance` to find a balanced :class:`~scm.plams.tools.reaction.ReactionEquation` +* Many type hints added across the code to aid scripting through an IDE + +Changed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* :class:`~scm.plams.interfaces.adfsuite.amsanalysis.AMSAnalysisJob` has PISA support, accepts multiple |AMSJob| instances as input, and no longer overwrites user-supplied input settings +* :meth:`~scm.plams.interfaces.adfsuite.ams.AMSResults.get_normal_modes` explicitly gives the option to return mass-weighted Hessian eigenvectors +* |JobAnalysis| returns an updated copy on modification instead of performing operations in-place +* :func:`~scm.plams.interfaces.molecule.packmol.packmol` function made more flexible, now accepting a single ``None`` value for ``n_molecules`` if two of ``n_atoms``, ``density`` and ``box_bounds`` are specified (the missing value is then auto-calculated) + +Fixed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* Method to guess density in :func:`~scm.plams.interfaces.molecule.packmol.packmol_around` changed to resolve large underestimations in molecular volumes + +Deprecated +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* :func:`~scm.plams.core.functions.add_to_class` decorator is deprecated in favor of using standalone functions or subclasses + What's new in PLAMS for AMS2025? -------------------------------------- diff --git a/src/scm/plams/core/functions.py b/src/scm/plams/core/functions.py index ac856541..ef8f0fb7 100644 --- a/src/scm/plams/core/functions.py +++ b/src/scm/plams/core/functions.py @@ -40,25 +40,27 @@ @contextmanager def config_context() -> Generator[ConfigSettings, None, None]: """ - Enter a context with a |config| specific only to the current context. + Enter a context with a ``config`` specific only to the current context. - The global |config| will be copied into a new |ConfigSettings|, which can then be modified independently of the global instance. + The global ``config`` will be copied into a new |ConfigSettings|, which can then be modified independently of the global instance. - The |config| for this context can be retrieved using the function :func:`get_config`. + The ``config`` for this context can be retrieved using the function :func:`get_config`. + + .. note:: - .. note:: Starting a new thread creates a new context, so the context configuration will not automatically be used in the new thread. To copy over the parent thread context to the new thread, instead use :class:`~scm.plams.core.threading_utils.ContextAwareThread` - .. code:: python - >>> with config_context() as cfg: - >>> cfg.log.stdout = 0 - >>> print(f"Stdout logging inside context disabled: {get_config().log.stdout == 0}") - >>> print(f"Stdout logging outside context disabled: {get_config().log.stdout == 0}") - Stdout logging inside context disabled: True - Stdout logging outside context disabled: False + .. code:: python + + >>> with config_context() as cfg: + >>> cfg.log.stdout = 0 + >>> print(f"Stdout logging inside context disabled: {get_config().log.stdout == 0}") + >>> print(f"Stdout logging outside context disabled: {get_config().log.stdout == 0}") + Stdout logging inside context disabled: True + Stdout logging outside context disabled: False - :return: copy of the global |config| instance in a new |ConfigSettings| + :return: copy of the global ``config`` instance in a new |ConfigSettings| """ cfg: ConfigSettings = get_config().copy() token = _config.set(cfg) @@ -72,7 +74,7 @@ def get_config() -> ConfigSettings: """ Get the |ConfigSettings| for the current code context. - This will be the configuration used within a :func:`config_context` context, or otherwise the global |config|. + This will be the configuration used within a :func:`config_context` context, or otherwise the global ``config``. :return: |ConfigSettings| that should be used in the current code context """ @@ -658,6 +660,7 @@ def jobs_in_directory(path: Union[str, os.PathLike]) -> Generator[Path, None, No * The absolute path of the directory is returned on entering the context, which assumes the default |JobManager| is used. If another job manager is used within the context, the actual directory will be relative to its ``workdir``. .. code:: python + >>> with jobs_in_directory("GeometryOptimization") as go_dir: >>> with jobs_in_directory("DFTB"): >>> job1.run() @@ -671,6 +674,7 @@ def jobs_in_directory(path: Union[str, os.PathLike]) -> Generator[Path, None, No path/plams_workdir/GeometryOptimization/ML/M3GNet/job2 .. note:: + Starting a new thread creates a new context, so the context configuration will not automatically be used in the new thread. To copy over the parent thread context to the new thread, instead use :class:`~scm.plams.core.threading_utils.ContextAwareThread`