Merge pull request #4266 from akohlmey/geturl-command

New geturl command to download files for LAMMPS inputs on demand
This commit is contained in:
Axel Kohlmeyer
2024-08-08 13:42:21 -04:00
committed by GitHub
23 changed files with 483 additions and 44 deletions

View File

@ -510,6 +510,14 @@ if(PKG_ATC OR PKG_AWPMD OR PKG_ML-QUIP OR PKG_ML-POD OR PKG_ELECTRODE OR BUILD_T
endif() endif()
endif() endif()
find_package(CURL QUIET COMPONENTS HTTP HTTPS)
option(WITH_CURL "Enable libcurl support" ${CURL_FOUND})
if(WITH_CURL)
find_package(CURL REQUIRED COMPONENTS HTTP HTTPS)
target_compile_definitions(lammps PRIVATE -DLAMMPS_CURL)
target_link_libraries(lammps PRIVATE CURL::libcurl)
endif()
# tweak jpeg library names to avoid linker errors with MinGW cross-compilation # tweak jpeg library names to avoid linker errors with MinGW cross-compilation
set(JPEG_NAMES libjpeg libjpeg-62) set(JPEG_NAMES libjpeg libjpeg-62)
find_package(JPEG QUIET) find_package(JPEG QUIET)

View File

@ -8,7 +8,8 @@ explains how to do this for building both with CMake and make.
* `FFT library`_ for use with the :doc:`kspace_style pppm <kspace_style>` command * `FFT library`_ for use with the :doc:`kspace_style pppm <kspace_style>` command
* `Size of LAMMPS integer types and size limits`_ * `Size of LAMMPS integer types and size limits`_
* `Read or write compressed files`_ * `Read or write compressed files`_
* `Output of JPG, PNG, and move files` via the :doc:`dump image <dump_image>` or :doc:`dump movie <dump_image>` commands * `Output of JPEG, PNG, and movie files`_ via the :doc:`dump image <dump_image>` or :doc:`dump movie <dump_image>` commands
* `Support for downloading files`_
* `Memory allocation alignment`_ * `Memory allocation alignment`_
* `Workaround for long long integers`_ * `Workaround for long long integers`_
* `Exception handling when using LAMMPS as a library`_ to capture errors * `Exception handling when using LAMMPS as a library`_ to capture errors
@ -19,7 +20,7 @@ explains how to do this for building both with CMake and make.
.. _cxx11: .. _cxx11:
C++11 standard compliance C++11 standard compliance
------------------------------------------ -------------------------
A C++11 standard compatible compiler is a requirement for compiling LAMMPS. A C++11 standard compatible compiler is a requirement for compiling LAMMPS.
LAMMPS version 3 March 2020 is the last version compatible with the previous LAMMPS version 3 March 2020 is the last version compatible with the previous
@ -31,12 +32,16 @@ flags to enable C++11 compliance. Example for GNU c++ 4.8.x:
CCFLAGS = -g -O3 -std=c++11 CCFLAGS = -g -O3 -std=c++11
Individual packages may require compliance with a later C++ standard
like C++14 or C++17. These requirements will be documented with the
:doc:`individual packages <Packages_details>`.
---------- ----------
.. _fft: .. _fft:
FFT library FFT library
--------------------- -----------
When the KSPACE package is included in a LAMMPS build, the When the KSPACE package is included in a LAMMPS build, the
:doc:`kspace_style pppm <kspace_style>` command performs 3d FFTs which :doc:`kspace_style pppm <kspace_style>` command performs 3d FFTs which
@ -341,8 +346,8 @@ in whichever ``lib/gpu/Makefile`` is used must be the same as above.
.. _graphics: .. _graphics:
Output of JPG, PNG, and movie files Output of JPEG, PNG, and movie files
-------------------------------------------------- ------------------------------------
The :doc:`dump image <dump_image>` command has options to output JPEG or The :doc:`dump image <dump_image>` command has options to output JPEG or
PNG image files. Likewise, the :doc:`dump movie <dump_image>` command PNG image files. Likewise, the :doc:`dump movie <dump_image>` command
@ -356,9 +361,9 @@ requires the following settings:
.. code-block:: bash .. code-block:: bash
-D WITH_JPEG=value # yes or no -D WITH_JPEG=value # yes or no
# default = yes if CMake finds JPEG files, else no # default = yes if CMake finds JPEG development files, else no
-D WITH_PNG=value # yes or no -D WITH_PNG=value # yes or no
# default = yes if CMake finds PNG and ZLIB files, else no # default = yes if CMake finds PNG and ZLIB development files, else no
-D WITH_FFMPEG=value # yes or no -D WITH_FFMPEG=value # yes or no
# default = yes if CMake can find ffmpeg, else no # default = yes if CMake can find ffmpeg, else no
@ -446,12 +451,58 @@ during a run.
available using a compression library instead, which is what the available using a compression library instead, which is what the
:ref:`COMPRESS package <PKG-COMPRESS>` enables. :ref:`COMPRESS package <PKG-COMPRESS>` enables.
--------------------------------------------------
.. _libcurl:
Support for downloading files
-----------------------------
.. versionadded:: TBD
The :doc:`geturl command <geturl>` command uses the `the libcurl library
<https://curl.se/libcurl/>`_ to download files. This requires that
LAMMPS is compiled accordingly which needs the following settings:
.. tabs::
.. tab:: CMake build
.. code-block:: bash
-D WITH_CURL=value # yes or no
# default = yes if CMake finds CURL development files, else no
Usually these settings are all that is needed. If CMake cannot
find the graphics header, library, executable files, you can set
these variables:
.. code-block:: bash
-D CURL_INCLUDE_DIR=path # path to folder which contains curl.h header file
-D CURL_LIBRARY=path # path to libcurls.a (.so) file
.. tab:: Traditional make
.. code-block:: make
LMP_INC = -DLAMMPS_CURL <other LMP_INC settings>
CURL_INC = -I/usr/local/include # path to curl folder with curl.h
CURL_PATH = -L/usr/lib # paths to libcurl.a(.so) if make cannot find it
CURL_LIB = -lcurl # library names
As with CMake, you do not need to set ``CURL_INC`` or ``CURL_PATH``,
if make can find the libcurl header and library files in their
default system locations. You must specify ``CURL_LIB`` with a
paths or linker flags to link to libcurl.
---------- ----------
.. _align: .. _align:
Memory allocation alignment Memory allocation alignment
--------------------------------------- ---------------------------
This setting enables the use of the "posix_memalign()" call instead of This setting enables the use of the "posix_memalign()" call instead of
"malloc()" when LAMMPS allocates large chunks of memory. Vector "malloc()" when LAMMPS allocates large chunks of memory. Vector

View File

@ -54,6 +54,7 @@ table above.
* :doc:`echo <echo>` * :doc:`echo <echo>`
* :doc:`fix <fix>` * :doc:`fix <fix>`
* :doc:`fix_modify <fix_modify>` * :doc:`fix_modify <fix_modify>`
* :doc:`geturl <geturl>`
* :doc:`group <group>` * :doc:`group <group>`
* :doc:`if <if>` * :doc:`if <if>`
* :doc:`improper_coeff <improper_coeff>` * :doc:`improper_coeff <improper_coeff>`

View File

@ -45,6 +45,7 @@ Commands
fix fix
fix_modify fix_modify
fitpod_command fitpod_command
geturl
group group
group2ndx group2ndx
hyper hyper

82
doc/src/geturl.rst Normal file
View File

@ -0,0 +1,82 @@
.. index:: geturl
geturl command
==============
Syntax
""""""
.. code-block:: LAMMPS
geturl url keyword args ...
* url = URL of the file to download
* zero or more keyword argument pairs may be provided
* keyword = *output* or *verify* or *overwrite* or *verbose*
.. parsed-literal::
*output* filename = write to *filename* instead of inferring the name from the URL
*verify* yes/no = verify SSL certificate and hostname if *yes*, do not if *no*
*overwrite* yes/no = if *yes* overwrite the output file in case it exists, do not if *no*
*verbose* yes/no = if *yes* write verbose debug output from libcurl to screen, do not if *no*
Examples
""""""""
.. code-block:: LAMMPS
geturl https://www.ctcms.nist.gov/potentials/Download/1990--Ackland-G-J-Vitek-V--Cu/2/Cu2.eam.fs
geturl https://github.com/lammps/lammps/blob/develop/bench/in.lj output in.bench-lj
Description
"""""""""""
.. versionadded:: TBD
Download a file from an URL to the local disk. This is implemented with
the `libcurl library <https:://curl.se/libcurl/>`_ which supports a
large variety of protocols including "http", "https", "ftp", "scp",
"sftp", "file". The transfer will only be performed on MPI rank 0.
The *output* keyword can be used to set the filename. By default, the last part
of the URL is used.
The *verify* keyword determines whether ``libcurl`` will validate the
SSL certificate and hostname for encrypted connections. Turning this
off may be required when using a proxy or connecting to a server with a
self-signed SSL certificate.
The *overwrite* keyword determines whether a file should be overwritten if it
already exists. If the argument is *no*, then the download will be skipped
if the file exists.
The *verbose* keyword determines whether a detailed protocol of the steps
performed by libcurl is written to the screen. Using the argument *yes*
can be used to debug connection issues when the *geturl* command does not
behave as expected. If the argument is *no*, geturl will operate silently
and only report the error status number provided by libcurl, in case of a
failure.
----------
Restrictions
""""""""""""
This command is part of the EXTRA-COMMAND package. It is only enabled
if LAMMPS was built with that package. See the :doc:`Build package
<Build_package>` page for more info. It also requires that LAMMPS was
built with support for `the libcurl library
<https://curl.se/libcurl/>`_. See the page about :ref:`Compiling LAMMPS
with libcurl support <libcurl>` for further info. If support for
libcurl is not included, using *geturl* will trigger an error.
Related commands
""""""""""""""""
:doc:`shell <shell>`
Default
"""""""
*verify* = yes, *overwrite* = yes

View File

@ -1298,6 +1298,7 @@ Gershgorin
getrusage getrusage
getter getter
gettimeofday gettimeofday
geturl
gewald gewald
Gezelter Gezelter
Gflop Gflop
@ -1492,6 +1493,8 @@ hplanck
Hs Hs
hstyle hstyle
html html
http
https
hTST hTST
https https
hu hu
@ -3349,6 +3352,7 @@ Schunk
Schuring Schuring
Schwen Schwen
Sci Sci
scp
screenshot screenshot
screenshots screenshots
Scripps Scripps
@ -3389,6 +3393,7 @@ setvel
sevenbody sevenbody
sfftw sfftw
sfree sfree
sftp
Sg Sg
sgcmc sgcmc
Shan Shan
@ -3903,6 +3908,7 @@ upenn
upto upto
Urbakh Urbakh
Urbana Urbana
url
UreyBradley UreyBradley
Usabiaga Usabiaga
usec usec

View File

@ -150,6 +150,7 @@ liblammpsplugin_t *liblammpsplugin_load(const char *lib)
ADDSYM(config_has_png_support); ADDSYM(config_has_png_support);
ADDSYM(config_has_jpeg_support); ADDSYM(config_has_jpeg_support);
ADDSYM(config_has_ffmpeg_support); ADDSYM(config_has_ffmpeg_support);
ADDSYM(config_has_curl_support);
ADDSYM(config_has_exceptions); ADDSYM(config_has_exceptions);
ADDSYM(config_has_package); ADDSYM(config_has_package);

View File

@ -203,6 +203,7 @@ struct _liblammpsplugin {
int (*config_has_png_support)(); int (*config_has_png_support)();
int (*config_has_jpeg_support)(); int (*config_has_jpeg_support)();
int (*config_has_ffmpeg_support)(); int (*config_has_ffmpeg_support)();
int (*config_has_curl_support)();
int (*config_has_exceptions)(); int (*config_has_exceptions)();
int (*config_has_package)(const char *); int (*config_has_package)(const char *);

View File

@ -196,6 +196,7 @@ MODULE LIBLAMMPS
PROCEDURE, NOPASS :: config_has_jpeg_support => lmp_config_has_jpeg_support PROCEDURE, NOPASS :: config_has_jpeg_support => lmp_config_has_jpeg_support
PROCEDURE, NOPASS :: config_has_ffmpeg_support & PROCEDURE, NOPASS :: config_has_ffmpeg_support &
=> lmp_config_has_ffmpeg_support => lmp_config_has_ffmpeg_support
PROCEDURE, NOPASS :: config_has_curl_support => lmp_config_has_curl_support
PROCEDURE, NOPASS :: config_has_exceptions => lmp_config_has_exceptions PROCEDURE, NOPASS :: config_has_exceptions => lmp_config_has_exceptions
PROCEDURE, NOPASS :: config_has_package => lmp_config_has_package PROCEDURE, NOPASS :: config_has_package => lmp_config_has_package
PROCEDURE, NOPASS :: config_package_count => lammps_config_package_count PROCEDURE, NOPASS :: config_package_count => lammps_config_package_count
@ -793,6 +794,12 @@ MODULE LIBLAMMPS
INTEGER(c_int) :: lammps_config_has_ffmpeg_support INTEGER(c_int) :: lammps_config_has_ffmpeg_support
END FUNCTION lammps_config_has_ffmpeg_support END FUNCTION lammps_config_has_ffmpeg_support
FUNCTION lammps_config_has_curl_support() BIND(C)
IMPORT :: c_int
IMPLICIT NONE
INTEGER(c_int) :: lammps_config_has_curl_support
END FUNCTION lammps_config_has_curl_support
FUNCTION lammps_config_has_exceptions() BIND(C) FUNCTION lammps_config_has_exceptions() BIND(C)
IMPORT :: c_int IMPORT :: c_int
IMPLICIT NONE IMPLICIT NONE
@ -2881,6 +2888,14 @@ CONTAINS
lmp_config_has_ffmpeg_support = (has_ffmpeg_support /= 0_c_int) lmp_config_has_ffmpeg_support = (has_ffmpeg_support /= 0_c_int)
END FUNCTION lmp_config_has_ffmpeg_support END FUNCTION lmp_config_has_ffmpeg_support
! equivalent function to lammps_config_has_curl_support
LOGICAL FUNCTION lmp_config_has_curl_support()
INTEGER(c_int) :: has_curl_support
has_curl_support = lammps_config_has_curl_support()
lmp_config_has_curl_support = (has_curl_support /= 0_c_int)
END FUNCTION lmp_config_has_curl_support
! equivalent function to lammps_config_has_exceptions ! equivalent function to lammps_config_has_exceptions
LOGICAL FUNCTION lmp_config_has_exceptions() LOGICAL FUNCTION lmp_config_has_exceptions()
INTEGER(c_int) :: has_exceptions INTEGER(c_int) :: has_exceptions

View File

@ -1969,6 +1969,21 @@ class lammps(object):
# ------------------------------------------------------------------------- # -------------------------------------------------------------------------
@property
def has_curl_support(self):
""" Report whether the LAMMPS shared library was compiled with support
for downloading files through libcurl.
This is a wrapper around the :cpp:func:`lammps_config_has_curl_support`
function of the library interface.
:return: state of CURL support
:rtype: bool
"""
return self.lib.lammps_config_has_curl_support() != 0
# -------------------------------------------------------------------------
def has_package(self, name): def has_package(self, name):
""" Report if the named package has been enabled in the LAMMPS shared library. """ Report if the named package has been enabled in the LAMMPS shared library.

2
src/.gitignore vendored
View File

@ -1075,6 +1075,8 @@
/fix_wall_srd.h /fix_wall_srd.h
/fix_widom.cpp /fix_widom.cpp
/fix_widom.h /fix_widom.h
/geturl.cpp
/geturl.h
/gpu_extra.h /gpu_extra.h
/group_ndx.cpp /group_ndx.cpp
/group_ndx.h /group_ndx.h

View File

@ -0,0 +1,119 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Axel Kohlmeyer (Temple U),
------------------------------------------------------------------------- */
#include "geturl.h"
#include "comm.h"
#include "error.h"
#if defined(LAMMPS_CURL)
#include <curl/curl.h>
#endif
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
void GetURL::command(int narg, char **arg)
{
#if !defined(LAMMPS_CURL)
error->all(FLERR, "LAMMPS has not been compiled with libcurl support");
#else
if (narg < 1) utils::missing_cmd_args(FLERR, "geturl", error);
int verify = 1;
int overwrite = 1;
int verbose = 0;
// process arguments
std::string url = arg[0];
// sanity check
if ((url.find(':') == std::string::npos) || (url.find('/') == std::string::npos))
error->all(FLERR, "URL '{}' is not a supported URL", url);
std::string output = url.substr(url.find_last_of('/') + 1);
if (output.empty()) error->all(FLERR, "URL '{}' must end in a file string", url);
int iarg = 1;
while (iarg < narg) {
if (strcmp(arg[iarg], "output") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "geturl output", error);
output = arg[iarg + 1];
++iarg;
} else if (strcmp(arg[iarg], "overwrite") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "geturl overwrite", error);
overwrite = utils::logical(FLERR, arg[iarg + 1], false, lmp);
++iarg;
} else if (strcmp(arg[iarg], "verify") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "geturl verify", error);
verify = utils::logical(FLERR, arg[iarg + 1], false, lmp);
++iarg;
} else if (strcmp(arg[iarg], "verbose") == 0) {
if (iarg + 2 > narg) utils::missing_cmd_args(FLERR, "geturl verbose", error);
verbose = utils::logical(FLERR, arg[iarg + 1], false, lmp);
++iarg;
} else {
error->all(FLERR, "Unknown geturl keyword: {}", arg[iarg]);
}
++iarg;
}
// only download files from rank 0
if (comm->me != 0) return;
if (!overwrite && platform::file_is_readable(output)) return;
// open output file for writing
FILE *out = fopen(output.c_str(), "wb");
if (!out)
error->all(FLERR, "Cannot open output file {} for writing: {}", output, utils::getsyserror());
// initialize curl and perform download
CURL *curl;
curl_global_init(CURL_GLOBAL_DEFAULT);
curl = curl_easy_init();
if (curl) {
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *) out);
curl_easy_setopt(curl, CURLOPT_FILETIME, 1L);
curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
if (verbose && screen) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
curl_easy_setopt(curl, CURLOPT_STDERR, (void *) screen);
}
if (!verify) {
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
}
auto res = curl_easy_perform(curl);
if (res != CURLE_OK) {
long response = 0L;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response);
error->one(FLERR, "Download of {} failed with: {} {}", output, curl_easy_strerror(res),
response);
}
curl_easy_cleanup(curl);
}
curl_global_cleanup();
fclose(out);
#endif
}

View File

@ -0,0 +1,34 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/, Sandia National Laboratories
LAMMPS development team: developers@lammps.org
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#ifdef COMMAND_CLASS
// clang-format off
CommandStyle(geturl,GetURL);
// clang-format on
#else
#ifndef LMP_GETURL_H
#define LMP_GETURL_H
#include "command.h"
namespace LAMMPS_NS {
class GetURL : public Command {
public:
GetURL(class LAMMPS *lmp) : Command(lmp) {};
void command(int, char **) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -35,9 +35,9 @@ LMP_INC = -DLAMMPS_GZIP -DLAMMPS_MEMALIGN=64 # -DLAMMPS_CXX98
# MPI wrapper compiler/linker can provide this info # MPI wrapper compiler/linker can provide this info
# can point to dummy MPI library in src/STUBS as in Makefile.serial # can point to dummy MPI library in src/STUBS as in Makefile.serial
# use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts # use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts
# INC = path for mpi.h, MPI compiler settings # MPI_INC = path for mpi.h, MPI compiler settings
# PATH = path for MPI library # MPI_PATH = path for MPI library
# LIB = name of MPI library # MPI_LIB = name of MPI library
MPI_INC = -DMPICH_SKIP_MPICXX -DOMPI_SKIP_MPICXX=1 MPI_INC = -DMPICH_SKIP_MPICXX -DOMPI_SKIP_MPICXX=1
MPI_PATH = MPI_PATH =
@ -46,9 +46,9 @@ MPI_LIB =
# FFT library # FFT library
# see discussion in Section 3.5.2 of manual # see discussion in Section 3.5.2 of manual
# can be left blank to use provided KISS FFT library # can be left blank to use provided KISS FFT library
# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings # FFT_INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings
# PATH = path for FFT library # FFT_PATH = path for FFT library
# LIB = name of FFT library # FFT_LIB = name of FFT library
FFT_INC = FFT_INC =
FFT_PATH = FFT_PATH =
@ -57,14 +57,25 @@ FFT_LIB =
# JPEG and/or PNG library # JPEG and/or PNG library
# see discussion in Section 3.5.4 of manual # see discussion in Section 3.5.4 of manual
# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC # only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC
# INC = path(s) for jpeglib.h and/or png.h # JPG_INC = path(s) for jpeglib.h and/or png.h
# PATH = path(s) for JPEG library and/or PNG library # JPG_PATH = path(s) for JPEG library and/or PNG library
# LIB = name(s) of JPEG library and/or PNG library # JPG_LIB = name(s) of JPEG library and/or PNG library
JPG_INC = JPG_INC =
JPG_PATH = JPG_PATH =
JPG_LIB = JPG_LIB =
# CURL library
# see discussion in Section 3.5.6 of manual
# only needed if -DLAMMPS_CURL listed with LMP_INC
# CURL_INC = path(s) for curl/curl.h
# CURL_PATH = path(s) for CURL library
# CURL_LIB = name(s) of CURL library, e.g. -lcurl
CURL_INC =
CURL_PATH =
CURL_LIB =
# library for loading shared objects (defaults to -ldl, should be empty on Windows) # library for loading shared objects (defaults to -ldl, should be empty on Windows)
# uncomment to change the default # uncomment to change the default
@ -77,9 +88,9 @@ JPG_LIB =
include Makefile.package.settings include Makefile.package.settings
include Makefile.package include Makefile.package
EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC) EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(CURL_INC) $(PKG_SYSINC)
EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH) EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(CURL_PATH) $(PKG_SYSPATH)
EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) $(DYN_LIB) EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(CURL_LIB) $(PKG_SYSLIB) $(DYN_LIB)
EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS) EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS)
EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS) EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS)

View File

@ -35,35 +35,46 @@ LMP_INC = -DLAMMPS_GZIP -DLAMMPS_MEMALIGN=64 # -DLAMMPS_CXX98
# MPI wrapper compiler/linker can provide this info # MPI wrapper compiler/linker can provide this info
# can point to dummy MPI library in src/STUBS as in Makefile.serial # can point to dummy MPI library in src/STUBS as in Makefile.serial
# use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts # use -D MPICH and OMPI settings in INC to avoid C++ lib conflicts
# INC = path for mpi.h, MPI compiler settings # MPI_INC = path for mpi.h, MPI compiler settings
# PATH = path for MPI library # MPI_PATH = path for MPI library
# LIB = name of MPI library # MPI_LIB = name of MPI library
MPI_INC = -I../STUBS MPI_INC = -I../STUBS
MPI_PATH = -L../STUBS MPI_PATH = -L../STUBS
MPI_LIB = -lmpi_stubs MPI_LIB = -lmpi_stubs
# FFT library # FFT library
# see discussion in Section 3.5.2 of manual # see discussion in Section 3.5.2 of manual
# can be left blank to use provided KISS FFT library # can be left blank to use provided KISS FFT library
# INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings # FFT_INC = -DFFT setting, e.g. -DFFT_FFTW, FFT compiler settings
# PATH = path for FFT library # FFT_PATH = path for FFT library
# LIB = name of FFT library # FFT_LIB = name of FFT library
FFT_INC = FFT_INC =
FFT_PATH = FFT_PATH =
FFT_LIB = FFT_LIB =
# JPEG and/or PNG library # JPEG and/or PNG library
# see discussion in Section 3.5.4 of manual # see discussion in Section 3.5.4 of manual
# only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC # only needed if -DLAMMPS_JPEG or -DLAMMPS_PNG listed with LMP_INC
# INC = path(s) for jpeglib.h and/or png.h # JPG_INC = path(s) for jpeglib.h and/or png.h
# PATH = path(s) for JPEG library and/or PNG library # JPG_PATH = path(s) for JPEG library and/or PNG library
# LIB = name(s) of JPEG library and/or PNG library # JPG_LIB = name(s) of JPEG library and/or PNG library
JPG_INC = JPG_INC =
JPG_PATH = JPG_PATH =
JPG_LIB = JPG_LIB =
# CURL library
# see discussion in Section 3.5.6 of manual
# only needed if -DLAMMPS_CURL listed with LMP_INC
# CURL_INC = path(s) for curl/curl.h
# CURL_PATH = path(s) for CURL library
# CURL_LIB = name(s) of CURL library, e.g. -lcurl
CURL_INC =
CURL_PATH =
CURL_LIB =
# library for loading shared objects (defaults to -ldl, should be empty on Windows) # library for loading shared objects (defaults to -ldl, should be empty on Windows)
# uncomment to change the default # uncomment to change the default
@ -77,9 +88,9 @@ JPG_LIB =
include Makefile.package.settings include Makefile.package.settings
include Makefile.package include Makefile.package
EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(PKG_SYSINC) EXTRA_INC = $(LMP_INC) $(PKG_INC) $(MPI_INC) $(FFT_INC) $(JPG_INC) $(CURL_INC) $(PKG_SYSINC)
EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(PKG_SYSPATH) EXTRA_PATH = $(PKG_PATH) $(MPI_PATH) $(FFT_PATH) $(JPG_PATH) $(CURL_PATH) $(PKG_SYSPATH)
EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(PKG_SYSLIB) $(DYN_LIB) EXTRA_LIB = $(PKG_LIB) $(MPI_LIB) $(FFT_LIB) $(JPG_LIB) $(CURL_LIB) $(PKG_SYSLIB) $(DYN_LIB)
EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS) EXTRA_CPP_DEPENDS = $(PKG_CPP_DEPENDS)
EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS) EXTRA_LINK_DEPENDS = $(PKG_LINK_DEPENDS)

View File

@ -296,6 +296,7 @@ void Info::command(int narg, char **arg)
if (has_png_support()) fputs("-DLAMMPS_PNG\n",out); if (has_png_support()) fputs("-DLAMMPS_PNG\n",out);
if (has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",out); if (has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",out);
if (has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",out); if (has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",out);
if (has_curl_support()) fputs("-DLAMMPS_CURL\n",out);
if (has_fft_single_support()) fputs("-DFFT_SINGLE\n",out); if (has_fft_single_support()) fputs("-DFFT_SINGLE\n",out);
#if defined(LAMMPS_BIGBIG) #if defined(LAMMPS_BIGBIG)
@ -857,6 +858,8 @@ bool Info::is_available(const char *category, const char *name)
return has_jpeg_support(); return has_jpeg_support();
} else if (strcmp(name,"ffmpeg") == 0) { } else if (strcmp(name,"ffmpeg") == 0) {
return has_ffmpeg_support(); return has_ffmpeg_support();
} else if (strcmp(name,"curl") == 0) {
return has_curl_support();
} else if (strcmp(name,"fft_single") == 0) { } else if (strcmp(name,"fft_single") == 0) {
return has_fft_single_support(); return has_fft_single_support();
} else if (strcmp(name,"exceptions") == 0) { } else if (strcmp(name,"exceptions") == 0) {
@ -1077,6 +1080,14 @@ bool Info::has_ffmpeg_support() {
#endif #endif
} }
bool Info::has_curl_support() {
#ifdef LAMMPS_CURL
return true;
#else
return false;
#endif
}
bool Info::has_fft_single_support() { bool Info::has_fft_single_support() {
#ifdef FFT_SINGLE #ifdef FFT_SINGLE
return true; return true;

View File

@ -28,7 +28,7 @@ namespace LAMMPS_NS {
class Info : public Command { class Info : public Command {
public: public:
Info(class LAMMPS *lmp) : Command(lmp){}; Info(class LAMMPS *lmp) : Command(lmp) {};
void command(int, char **) override; void command(int, char **) override;
bool is_active(const char *, const char *); bool is_active(const char *, const char *);
@ -42,6 +42,7 @@ class Info : public Command {
static bool has_png_support(); static bool has_png_support();
static bool has_jpeg_support(); static bool has_jpeg_support();
static bool has_ffmpeg_support(); static bool has_ffmpeg_support();
static bool has_curl_support();
static bool has_fft_single_support(); static bool has_fft_single_support();
static bool has_exceptions(); static bool has_exceptions();
static bool has_package(const std::string &); static bool has_package(const std::string &);

View File

@ -1454,6 +1454,7 @@ void LAMMPS::print_config(FILE *fp)
if (Info::has_png_support()) fputs("-DLAMMPS_PNG\n",fp); if (Info::has_png_support()) fputs("-DLAMMPS_PNG\n",fp);
if (Info::has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",fp); if (Info::has_jpeg_support()) fputs("-DLAMMPS_JPEG\n",fp);
if (Info::has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",fp); if (Info::has_ffmpeg_support()) fputs("-DLAMMPS_FFMPEG\n",fp);
if (Info::has_curl_support()) fputs("-DLAMMPS_CURL\n",fp);
if (Info::has_fft_single_support()) fputs("-DFFT_SINGLE\n",fp); if (Info::has_fft_single_support()) fputs("-DFFT_SINGLE\n",fp);
#if defined(LAMMPS_BIGBIG) #if defined(LAMMPS_BIGBIG)
fputs("-DLAMMPS_BIGBIG\n",fp); fputs("-DLAMMPS_BIGBIG\n",fp);

View File

@ -5877,6 +5877,26 @@ int lammps_config_has_ffmpeg_support() {
/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */
/** Check if the LAMMPS library supports downloading files via libcurl
\verbatim embed:rst
.. versionadded::TBD
The LAMMPS :doc:`geturl command <geturl>` supports downloading files
through using `the libcurl library <https://curl.se/libcurl/>`_.
This function checks whether this feature was :ref:`enabled at compile
time <libcurl>` and LAMMPS linked to the libcurl library.
\endverbatim
*
* \return 1 if yes, otherwise 0
*/
int lammps_config_has_curl_support() {
return Info::has_curl_support() ? 1 : 0;
}
/* ---------------------------------------------------------------------- */
/** Check whether LAMMPS errors will throw C++ exceptions. /** Check whether LAMMPS errors will throw C++ exceptions.
* *
\verbatim embed:rst \verbatim embed:rst

View File

@ -243,6 +243,7 @@ int lammps_config_has_gzip_support();
int lammps_config_has_png_support(); int lammps_config_has_png_support();
int lammps_config_has_jpeg_support(); int lammps_config_has_jpeg_support();
int lammps_config_has_ffmpeg_support(); int lammps_config_has_ffmpeg_support();
int lammps_config_has_curl_support();
int lammps_config_has_exceptions(); int lammps_config_has_exceptions();
int lammps_config_has_package(const char *); int lammps_config_has_package(const char *);

View File

@ -23,7 +23,7 @@ Highlighter::Highlighter(QTextDocument *parent) :
"thermo|print|thermo_style|" "thermo|print|thermo_style|"
"timer|pair_write|bond_write|angle_write|dihedral_write)\\s+(\\S+)")), "timer|pair_write|bond_write|angle_write|dihedral_write)\\s+(\\S+)")),
isOutput2(QStringLiteral("^\\s*(write_dump|shell|thermo_modify)\\s+(\\S+)\\s+(\\S+)")), isOutput2(QStringLiteral("^\\s*(write_dump|shell|thermo_modify)\\s+(\\S+)\\s+(\\S+)")),
isRead(QStringLiteral("^\\s*(include|read_restart|read_data|read_dump|molecule)")), isRead(QStringLiteral("^\\s*(include|read_restart|read_data|read_dump|molecule|geturl)\\s+(\\S+)")),
isStyle(QStringLiteral("^\\s*(fix|compute|dump)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)")), isStyle(QStringLiteral("^\\s*(fix|compute|dump)\\s+(\\S+)\\s+(\\S+)\\s+(\\S+)")),
isForce(QStringLiteral( isForce(QStringLiteral(
"^\\s*(pair_style|bond_style|angle_style|dihedral_style|improper_style|kspace_style|pair_" "^\\s*(pair_style|bond_style|angle_style|dihedral_style|improper_style|kspace_style|pair_"

View File

@ -171,6 +171,7 @@ extern int lammps_config_has_gzip_support();
extern int lammps_config_has_png_support(); extern int lammps_config_has_png_support();
extern int lammps_config_has_jpeg_support(); extern int lammps_config_has_jpeg_support();
extern int lammps_config_has_ffmpeg_support(); extern int lammps_config_has_ffmpeg_support();
extern int lammps_config_has_curl_support();
extern int lammps_config_has_exceptions(); extern int lammps_config_has_exceptions();
extern int lammps_config_has_package(const char *); extern int lammps_config_has_package(const char *);
extern int lammps_config_package_count(); extern int lammps_config_package_count();
@ -359,6 +360,7 @@ extern int lammps_config_has_gzip_support();
extern int lammps_config_has_png_support(); extern int lammps_config_has_png_support();
extern int lammps_config_has_jpeg_support(); extern int lammps_config_has_jpeg_support();
extern int lammps_config_has_ffmpeg_support(); extern int lammps_config_has_ffmpeg_support();
extern int lammps_config_has_curl_support();
extern int lammps_config_has_exceptions(); extern int lammps_config_has_exceptions();
extern int lammps_config_has_package(const char *); extern int lammps_config_has_package(const char *);
extern int lammps_config_package_count(); extern int lammps_config_package_count();

View File

@ -19,6 +19,7 @@
#include "info.h" #include "info.h"
#include "input.h" #include "input.h"
#include "output.h" #include "output.h"
#include "platform.h"
#include "update.h" #include "update.h"
#include "utils.h" #include "utils.h"
#include "variable.h" #include "variable.h"
@ -214,9 +215,9 @@ TEST_F(SimpleCommandsTest, Quit)
TEST_FAILURE(".*ERROR: Expected integer .*", command("quit xxx");); TEST_FAILURE(".*ERROR: Expected integer .*", command("quit xxx"););
// the following tests must be skipped with OpenMPI or MPICH 4.1 and later due to using threads // the following tests must be skipped with OpenMPI or MPICH 4.1 and later due to using threads
if (platform::mpi_vendor() == "Open MPI") GTEST_SKIP(); if (platform::mpi_vendor() == "Open MPI") GTEST_SKIP() << "OpenMPI";
#if defined(MPICH_NUMVERSION) #if defined(MPICH_NUMVERSION)
if (MPICH_NUMVERSION >= 40100000) GTEST_SKIP(); if (MPICH_NUMVERSION >= 40100000) GTEST_SKIP() << "MPICH with threads";
#endif #endif
ASSERT_EXIT(command("quit"), ExitedWithCode(0), ""); ASSERT_EXIT(command("quit"), ExitedWithCode(0), "");
ASSERT_EXIT(command("quit 9"), ExitedWithCode(9), ""); ASSERT_EXIT(command("quit 9"), ExitedWithCode(9), "");
@ -412,7 +413,7 @@ TEST_F(SimpleCommandsTest, Plugin)
{ {
const char *bindir = getenv("LAMMPS_PLUGIN_BIN_DIR"); const char *bindir = getenv("LAMMPS_PLUGIN_BIN_DIR");
const char *config = getenv("CMAKE_CONFIG_TYPE"); const char *config = getenv("CMAKE_CONFIG_TYPE");
if (!bindir) GTEST_SKIP(); if (!bindir) GTEST_SKIP() << "LAMMPS_PLUGIN_BIN_DIR not set";
std::string loadfmt = platform::path_join("plugin load ", bindir); std::string loadfmt = platform::path_join("plugin load ", bindir);
if (config) loadfmt = platform::path_join(loadfmt, config); if (config) loadfmt = platform::path_join(loadfmt, config);
loadfmt = platform::path_join(loadfmt, "{}plugin.so"); loadfmt = platform::path_join(loadfmt, "{}plugin.so");
@ -556,6 +557,50 @@ TEST_F(SimpleCommandsTest, CiteMe)
// no new citation. no CITE-CITE-CITE- lines // no new citation. no CITE-CITE-CITE- lines
ASSERT_THAT(text, Not(ContainsRegex(".*CITE-CITE-CITE-CITE.*"))); ASSERT_THAT(text, Not(ContainsRegex(".*CITE-CITE-CITE-CITE.*")));
} }
TEST_F(SimpleCommandsTest, Geturl)
{
if (!LAMMPS::is_installed_pkg("EXTRA-COMMAND")) GTEST_SKIP();
platform::unlink("index.html");
platform::unlink("myindex.html");
if (Info::has_curl_support()) {
BEGIN_CAPTURE_OUTPUT();
command("geturl https://www.lammps.org/index.html");
command("geturl https://www.lammps.org/index.html output myindex.html");
END_CAPTURE_OUTPUT();
EXPECT_TRUE(platform::file_is_readable("index.html"));
EXPECT_TRUE(platform::file_is_readable("myindex.html"));
FILE *fp = fopen("index.html", "wb");
fputs("just testing\n", fp);
fclose(fp);
BEGIN_CAPTURE_OUTPUT();
command("geturl https://www.lammps.org/index.html overwrite no");
END_CAPTURE_OUTPUT();
char checkme[20];
fp = fopen("index.html", "rb");
fgets(checkme, 19, fp);
fclose(fp);
EXPECT_EQ(strcmp(checkme, "just testing\n"), 0);
BEGIN_CAPTURE_OUTPUT();
command("geturl https://www.lammps.org/index.html overwrite yes");
END_CAPTURE_OUTPUT();
fp = fopen("index.html", "rb");
fgets(checkme, 19, fp);
fclose(fp);
EXPECT_NE(strcmp(checkme, "just testing\n"), 0);
TEST_FAILURE(".*ERROR: Illegal geturl command: missing argument.*", command("geturl "););
TEST_FAILURE(".*ERROR: URL 'dummy' is not a supported URL.*", command("geturl dummy"););
TEST_FAILURE(".*ERROR on proc 0: Download of xxx.txt failed with: "
"HTTP response code said error 404.*",
command("geturl https://www.lammps.org/xxx.txt"););
} else {
TEST_FAILURE(".*ERROR: LAMMPS has not been compiled with libcurl support*",
command("geturl https:://www.lammps.org/index.html"););
}
platform::unlink("index.html");
platform::unlink("myindex.html");
}
} // namespace LAMMPS_NS } // namespace LAMMPS_NS
int main(int argc, char **argv) int main(int argc, char **argv)