Merge branch 'master' into collected-small-changes

This commit is contained in:
Axel Kohlmeyer 2020-06-15 12:12:45 -04:00
commit 9aee8d41bd
No known key found for this signature in database
GPG Key ID: D9B44E93BF0C375A
95 changed files with 788659 additions and 20 deletions

View File

@ -420,13 +420,19 @@ endforeach()
##############################################
# add lib sources of (simple) enabled packages
############################################
foreach(SIMPLE_LIB POEMS USER-ATC USER-AWPMD USER-H5MD)
foreach(SIMPLE_LIB POEMS USER-ATC USER-AWPMD USER-H5MD USER-MESONT)
if(PKG_${SIMPLE_LIB})
string(REGEX REPLACE "^USER-" "" PKG_LIB "${SIMPLE_LIB}")
string(TOLOWER "${PKG_LIB}" PKG_LIB)
file(GLOB_RECURSE ${PKG_LIB}_SOURCES
${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.c
${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.cpp)
if(PKG_LIB STREQUAL mesont)
enable_language(Fortran)
file(GLOB_RECURSE ${PKG_LIB}_SOURCES
${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.f90)
else()
file(GLOB_RECURSE ${PKG_LIB}_SOURCES
${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.c
${LAMMPS_LIB_SOURCE_DIR}/${PKG_LIB}/[^.]*.cpp)
endif()
add_library(${PKG_LIB} STATIC ${${PKG_LIB}_SOURCES})
set_target_properties(${PKG_LIB} PROPERTIES OUTPUT_NAME lammps_${PKG_LIB}${LAMMPS_MACHINE})
target_link_libraries(lammps PRIVATE ${PKG_LIB})

View File

@ -8,7 +8,7 @@ set(ALL_PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GPU
USER-ADIOS USER-ATC USER-AWPMD USER-BOCS USER-CGDNA USER-CGSDK
USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP
USER-H5MD USER-INTEL USER-LB USER-MANIFOLD USER-MEAMC USER-MESODPD
USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF USER-OMP
USER-MESONT USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF USER-OMP
USER-PHONON USER-PLUMED USER-PTM USER-QMMM USER-QTB USER-QUIP
USER-REACTION USER-REAXC USER-SCAFACOS USER-SDPD USER-SMD USER-SMTBQ
USER-SPH USER-TALLY USER-UEF USER-VTK USER-YAFF)

View File

@ -10,7 +10,7 @@ set(ALL_PACKAGES ASPHERE BODY CLASS2 COLLOID COMPRESS CORESHELL DIPOLE GPU
USER-ADIOS USER-ATC USER-AWPMD USER-BOCS USER-CGDNA USER-CGSDK
USER-COLVARS USER-DIFFRACTION USER-DPD USER-DRUDE USER-EFF USER-FEP
USER-H5MD USER-INTEL USER-LB USER-MANIFOLD USER-MEAMC USER-MESODPD
USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF USER-OMP
USER-MESONT USER-MGPT USER-MISC USER-MOFFF USER-MOLFILE USER-NETCDF USER-OMP
USER-PHONON USER-PLUMED USER-PTM USER-QMMM USER-QTB USER-QUIP
USER-REACTION USER-REAXC USER-SCAFACOS USER-SDPD USER-SMD USER-SMTBQ
USER-SPH USER-TALLY USER-UEF USER-VTK USER-YAFF)

View File

@ -3,7 +3,7 @@
set(PACKAGES_WITH_LIB COMPRESS GPU KIM KOKKOS LATTE MPIIO MSCG PYTHON
VORONOI USER-ADIOS USER-ATC USER-AWPMD USER-H5MD USER-LB
USER-MOLFILE USER-NETCDF USER-PLUMED USER-QMMM USER-QUIP
USER-MOLFILE USER-MESONT USER-NETCDF USER-PLUMED USER-QMMM USER-QUIP
USER-SCAFACOS USER-SMD USER-VTK)
foreach(PKG ${PACKAGES_WITH_LIB})

View File

@ -44,6 +44,7 @@ This is the list of packages that may require additional steps.
* :ref:`USER-COLVARS <user-colvars>`
* :ref:`USER-H5MD <user-h5md>`
* :ref:`USER-INTEL <user-intel>`
* :ref:`USER-MESONT <user-mesont>`
* :ref:`USER-MOLFILE <user-molfile>`
* :ref:`USER-NETCDF <user-netcdf>`
* :ref:`USER-PLUMED <user-plumed>`
@ -1302,6 +1303,45 @@ For KNLs:
----------
.. _user-mesont:
USER-MESONT package
-------------------------
This package includes a library written in Fortran 90 in the
``lib/mesont`` folder, so a working Fortran 90 compiler is required to
compile it. Also, the files with the force field data for running the
bundled examples are not included in the source distribution. Instead
they will be downloaded the first time this package is installed.
**CMake build**\ :
No additional settings are needed besides ``-D PKG_USER-MESONT=yes``
**Traditional make**\ :
Before building LAMMPS, you must build the *mesont* library in ``lib/mesont``\ .
You can also do it in one step from the ``lammps/src`` dir, using a command like
these, which simply invoke the ``lib/mesont/Install.py`` script with the specified
args:
.. code-block:: bash
$ make lib-mesont # print help message
$ make lib-mesont args="-m gfortran" # build with GNU g++ compiler (settings as with "make serial")
$ make lib-mesont args="-m ifort" # build with Intel icc compiler
The build should produce two files: ``lib/mesont/libmesont.a`` and
``lib/mesont/Makefile.lammps``\ . The latter is copied from an existing
``Makefile.lammps.\*`` and has settings needed to build LAMMPS with the
*mesont* library (though typically the settings contain only the Fortran
runtime library). If necessary, you can edit/create a new
``lib/mesont/Makefile.machine`` file for your system, which should
define an ``EXTRAMAKE`` variable to specify a corresponding
``Makefile.lammps.machine`` file.
----------
.. _user-molfile:
USER-MOLFILE package

View File

@ -79,6 +79,7 @@ KOKKOS, o = USER-OMP, t = OPT.
* :doc:`ke/atom/eff <compute_ke_atom_eff>`
* :doc:`ke/eff <compute_ke_eff>`
* :doc:`ke/rigid <compute_ke_rigid>`
* :doc:`mesont <compute_mesont>`
* :doc:`momentum <compute_momentum>`
* :doc:`msd <compute_msd>`
* :doc:`msd/chunk <compute_msd_chunk>`

View File

@ -180,6 +180,7 @@ OPT.
* :doc:`meam/spline (o) <pair_meam_spline>`
* :doc:`meam/sw/spline <pair_meam_sw_spline>`
* :doc:`mesocnt <pair_mesocnt>`
* :doc:`mesont/tpm <pair_mesont_tpm>`
* :doc:`mgpt <pair_mgpt>`
* :doc:`mie/cut (g) <pair_mie>`
* :doc:`mm3/switch3/coulgauss/long <pair_mm3_switch3_coulgauss_long>`

View File

@ -81,6 +81,7 @@ page gives those details.
* :ref:`USER-MANIFOLD <PKG-USER-MANIFOLD>`
* :ref:`USER-MEAMC <PKG-USER-MEAMC>`
* :ref:`USER-MESODPD <PKG-USER-MESODPD>`
* :ref:`USER-MESONT <PKG-USER-MESONT>`
* :ref:`USER-MGPT <PKG-USER-MGPT>`
* :ref:`USER-MISC <PKG-USER-MISC>`
* :ref:`USER-MOFFF <PKG-USER-MOFFF>`
@ -1712,6 +1713,56 @@ algorithm.
* examples/USER/mesodpd
* https://lammps.sandia.gov/movies.html#mesodpd
* examples/USER/meso
* http://lammps.sandia.gov/movies.html#mesodpd
----------
.. _PKG-USER-MESONT:
USER-MESONT package
-------------------
**Contents:**
USER-MESONT is a LAMMPS package for simulation of nanomechanics of
nanotubes (NTs). The model is based on a coarse-grained representation
of NTs as "flexible cylinders" consisting of a variable number of
segments. Internal interactions within a NT and the van der Waals
interaction between the tubes are described by a mesoscopic force field
designed and parameterized based on the results of atomic-level
molecular dynamics simulations. The description of the force field is
provided in the papers listed below. This package contains two
independent implementations of this model: :doc:`pair_style mesocnt
<pair_mesocnt>` is a (minimal) C++ implementation, and :doc:`pair_style
mesont/tpm <pair_mesont_tpm>` is a more general and feature rich
implementation based on a Fortran library in the ``lib/mesont`` folder.
**Download of potential files:**
The potential files for these pair styles are *very* large and thus
are not included in the regular downloaded packages of LAMMPS or the
git repositories. Instead, they will be automatically downloaded
from a web server when the package is installed for the first time.
**Authors of the *mesont* styles:**
Maxim V. Shugaev (University of Virginia), Alexey N. Volkov (University of Alabama), Leonid V. Zhigilei (University of Virginia)
**Author of the *mesocnt* pair style:**
Philipp Kloza (U Cambridge)
**Supporting info:**
* src/USER-MESONT: filenames -> commands
* src/USER-MESONT/README
* :doc:`atom_style mesont <atom_style>`
* :doc:`pair_style mesont/tpm <pair_mesont_tpm>`
* :doc:`compute mesont <compute_mesont>`
* :doc:`pair_style mesocnt <pair_mesocnt>`
* examples/USER/mesont
* tools/mesont
----------
.. _PKG-USER-MOFFF:

View File

@ -67,6 +67,8 @@ package:
+------------------------------------------------+-----------------------------------------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+---------+
| :ref:`USER-MESODPD <PKG-USER-MESODPD>` | mesoscale DPD models | :doc:`pair_style edpd <pair_mesodpd>` | USER/mesodpd | no |
+------------------------------------------------+-----------------------------------------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+---------+
| :ref:`USER-MESONT <PKG-USER-MESONT>` | mesoscopic tubular potential model for nanotubes | pair style :doc:`mesont/tpm <pair_mesont_tpm>`, :doc:`mesocnt <pair_mesocnt>` | USER/mesont | int |
+------------------------------------------------+-----------------------------------------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+---------+
| :ref:`USER-MGPT <PKG-USER-MGPT>` | fast MGPT multi-ion potentials | :doc:`pair_style mgpt <pair_mgpt>` | USER/mgpt | no |
+------------------------------------------------+-----------------------------------------------------------------+-------------------------------------------------------------------------------+------------------------------------------------------+---------+
| :ref:`USER-MISC <PKG-USER-MISC>` | single-file contributions | USER-MISC/README | USER/misc | no |

View File

@ -103,6 +103,8 @@ quantities.
+--------------+-----------------------------------------------------+--------------------------------------+
| *mdpd* | density | mDPD particles |
+--------------+-----------------------------------------------------+--------------------------------------+
| *mesont* | mass, radius, length, buckling, connections, tube id| mesoscopic nanotubes |
+--------------+-----------------------------------------------------+--------------------------------------+
| *molecular* | bonds, angles, dihedrals, impropers | uncharged molecules |
+--------------+-----------------------------------------------------+--------------------------------------+
| *peri* | mass, volume | mesoscopic Peridynamic models |
@ -347,6 +349,8 @@ dynamics (tDPD), respectively.
The *sph* style is part of the USER-SPH package for smoothed particle
hydrodynamics (SPH). See `this PDF guide <USER/sph/SPH_LAMMPS_userguide.pdf>`_ to using SPH in LAMMPS.
The *mesont* style is part of the USER-MESONT package.
The *spin* style is part of the SPIN package.
The *wavepacket* style is part of the USER-AWPMD package for the

View File

@ -235,6 +235,7 @@ The individual style names on the :doc:`Commands compute <Commands_compute>` doc
* :doc:`pair/local <compute_pair_local>` - distance/energy/force of each pairwise interaction
* :doc:`pe <compute_pe>` - potential energy
* :doc:`pe/atom <compute_pe_atom>` - potential energy for each atom
* :doc:`mesont <compute_mesont>` - Nanotube bending,stretching, and intertube energies
* :doc:`pe/mol/tally <compute_tally>` -
* :doc:`pe/tally <compute_tally>` -
* :doc:`plasticity/atom <compute_plasticity_atom>` - Peridynamic plasticity for each atom

View File

@ -0,0 +1,56 @@
.. index:: compute mesont
compute mesont command
==========================
Syntax
""""""
.. parsed-literal::
compute ID group-ID mesont mode
* ID, group-ID are documented in :doc:`compute <compute>` command
* mesont = style name of the compute command
* mode = one of estretch, ebend, etube (see details below)
Examples
""""""""
.. parsed-literal::
compute 1 all mesont estretch
Description
"""""""""""
These computes define computations for the stretching (estretch), bending
(ebend), and intertube (etube) per-node (atom) and total energies. The
evaluated value is selected by a parameter passed to the compute: estretch,
ebend, etube.
**Output info:**
These computes calculate per-node (per-atom) vectors, which can be accessed by
any command that uses per-atom values from a compute as input, and global
scalars. See the :doc:`Howto output <Howto_output>` doc page for an overview of
LAMMPS output options.
The computed values are provided in energy :doc:`units <units>`.
Restrictions
""""""""""""
These computes are part of the USER-MESONT package. They are only enabled if
LAMMPS is built with that package. See the :doc:`Build package <Build_package>`
doc page for more info. In addition, :doc:`mesont pair_style <pair_style>`
must be used.
Related commands
""""""""""""""""
:doc:`dump custom <dump>`
**Default:** none

View File

@ -30,6 +30,7 @@ Syntax
corner2x, corner2y, corner2z,
corner3x, corner3y, corner3z,
nbonds,
buckling,
vfrac, s0,
spin, eradius, ervel, erforce,
rho, drho, e, de, cv,
@ -63,6 +64,7 @@ Syntax
end12x, end12y, end12z = end points of line segment
corner123x, corner123y, corner123z = corner points of triangle
nbonds = number of bonds assigned to an atom
buckling = buckling flag used in mesoscopic simulation of nanotubes
.. parsed-literal::

214
doc/src/pair_mesont_tpm.rst Normal file
View File

@ -0,0 +1,214 @@
.. index:: pair_style mesont/tpm
pair_style mesont/tpm command
==============================
Syntax
""""""
.. parsed-literal::
pair_style mesont/tpm cut table_path BendingMode TPMType
* cut = the cutoff distance
* table_path = the path to the potential table
* BendingMode = the parameter defining the type of the bending potential for nanotubes: 0 - harmonic bending :ref:`(Srivastava) <Srivastava>`, 1 - anharmonic potential of bending and bending-buckling :ref:`(Zhigilei1) <Zhigilei1>`
* TPMType = the parameter determining the type of the inter-tube interaction term: 0 - segment-segment approach, 1 - segment-chain approach :ref:`(Zhigilei2 <Zhigilei2>`, :ref:`Zhigilei3) <Zhigilei3>`
The segment-segment approach is approximately 5 times slower than segment-chain approximation.
The parameter BendingMode also affects the calculation of the inter-tube interaction term when TPMType = 1. In this case, when BendingMode = 1, each continuous chain of segments is additionally replaced by a number of sub-chains divided by bending buckling kinks.
Examples
""""""""
.. parsed-literal::
pair_style mesont/tpm 30.0 MESONT-TABTP_10_10.xrs 0 0
Description
"""""""""""
The tubular potential model (TPM) force field is designed for mesoscopic
simulations of interacting flexible nanotubes. The force field is based on the
mesoscopic computational model suggested in Ref. :ref:`(Srivastava) <Srivastava>`.
In this model, each nanotube is represented by a chain of mesoscopic elements
in the form of stretchable cylindrical segments, where each segment consists
of multiple atoms. Each nanotube is divided into segments by a sequence of
nodes placed on the nanotube centerline. This sequence of nodes determines the
spatial position of the cylindrical segments and defines the configuration of
the entire tube.
The potential force field that controls the dynamic behavior of a system of
interacting nanotubes is given by the following equation defining the potential
energy of the system:
.. math::
U = U_{str} + U_{bnd} + U_{vdW}
where :math:`U_{str}` is the harmonic potential describing the stretching of nanotube
:ref:`(Srivastava) <Srivastava>`, :math:`U_{bnd}` is the potential for nanotube bending
:ref:`(Srivastava) <Srivastava>` and bending-buckling :ref:`(Zhigilei1) <Zhigilei1>`, and
:math:`U_{vdW}` is the potential describing van-der Waals interaction between nanotubes
:ref:`(Zhigilei2 <Zhigilei2>`, :ref:`Zhigilei3) <Zhigilei3>`. The stretching energy, :math:`U_{str}` ,
is given by the sum of stretching energies of individual nanotube segments.
The bending energy, :math:`U_{bnd}` , is given by the sum of bending energies in all
internal nanotube nodes. The tube-tube interaction energy, :math:`U_{vdW}` , is calculated
based on the tubular potential method suggested in Ref. :ref:`(Zhigilei2) <Zhigilei2>`.
The tubular potential method is briefly described below.
The interaction between two straight nanotubes of arbitrary length and
orientation is described by the approximate tubular potential developed in
:ref:`(Zhigilei3) <Zhigilei3>`. This potential approximates the results of direct
integration of carbon-carbon interatomic potential over the surfaces of the
interacting nanotubes, with the force sources homogeneously distributed over
the nanotube surfaces. The input data for calculation of tubular potentials
are partially tabulated. For single-walled CNTs of arbitrary chirality, the
tabulated potential data can be generated in the form of ASCII files
TPMSSTP.xrs and TPMA.xrs by the stand-alone code TMDPotGen included in the
tool directory of LAMMPS release. The potential provided with LAMMPS release,
MESONT-TABTP_10_10.xrs, is tabulated for (10,10) nanotubes.
Calculations of the interaction between curved or bent nanotubes are performed
on either segment-segment or segment-chain basis. In the first case, activated
when parameter TPMType is equal to 0, the tubular potential is calculated for
each pair of interacting mesoscopic segments. In this case, however, small
potential barriers for inter-tube sliding are introduced. While relatively
small, these barriers are still larger than the ones that originate from the
atomic-scale corrugation in atomistic modeling of inter-tube interaction. The
latter are too weak to prevent room-temperature rearrangements of defect-free
CNT, while the artificial mesoscopic barriers due to the segment-segment
interaction can impede sliding of nanotubes with respect to each other and
affect the kinetics of structural rearrangements in a system of nanotubes at
moderate mesoscopic temperatures. In the second case, activated when parameter
TPMType is equal to 1, the inter-tube interaction term is calculated based on
the segment-chain approach. In this case, for each NT segment, the list of its
neighboring segments is divided into short continuous chains of segments
belonging to individual nanotubes. For each pair of a segment and a chain, the
curved chain is approximated by a straight equivalent nanotube based on the
weighted approach suggested in Ref. :ref:`(Zhigilei2) <Zhigilei2>`. Finally, the
interaction between the segment and straight equivalent chain is calculated
based on the tubular potential. In this case, and in the absence of bending
buckling (i.e., when parameter BendingMode is equal to 0), the tubular
potential method ensures the absence of corrugation of the effective inter-tube
interaction potential for curved nanotubes and eliminates any barriers for the
inter-tube sliding. As a result, the tubular potential method can describe the
spontaneous self-assembly of nanotubes into continuous networks of bundles
:ref:`(Zhigilei1 <Zhigilei1>`, :ref:`Zhigilei3) <Zhigilei3>`.
----------
The TMD force field has been used for generation of nanotube films, fibers,
and vertically aligned forests of nanotubes. Mesoscopic dynamic simulations
were used to prepare realistic structures of continuous networks of nanotube
bundles and to study their structural and mechanical properties
:ref:`(Zhigilei1 <Zhigilei1>`, :ref:`Zhigilei3 <Zhigilei3>`, :ref:`Zhigilei4 <Zhigilei4>`,
:ref:`Zhigilei5 <Zhigilei5>`, :ref:`Zhigilei6) <Zhigilei6>`. With
additional models for heat transfer, this force filed was also used to
study the thermal transport properties of carbon nanotube films
:ref:`(Zhigilei7 <Zhigilei7>`, :ref:`Zhigilei8 <Zhigilei8>`, :ref:`Zhigilei8) <Zhigilei8>`.
The methods for modeling of
the mechanical energy dissipation into heat (energy exchange between the
dynamic degrees of freedom of the mesoscopic model and the energy of atomic
vibrations that are not explicitly represented in the model)
:ref:`(Zhigilei10) <Zhigilei10>` and mesoscopic description of covalent cross-links
between nanotubes :ref:`(Banna) <Banna>` have also been developed but are not
included in this first release of the LAMMPS implementation of the force field.
Further details can be found in references provided below.
The MESONT package also provides TMDGen code designed to generate initial samples
composed of straight and dispersed nanotubes of given chirality and length at a
given material density, which is available in tools directory. In the generated
samples, nanotubes are distributed with random positions and orientations. Both
periodic and free boundary conditions are available along each axis of the
system of coordinates. All parameters in the sample files generated with TMDGen
are given in metal :doc:`units <units>`.
Restrictions
""""""""""""
This pair style is a part of the USER-MSEONT package, and it is only enabled if
LAMMPS is built with that package. See the :doc:`Build package <Build_package>`
doc page for more information.
This pair potential requires use of :doc:`mesont atomic style <atom_style>`.
This pair potential requires the :doc:`newton <newton>` setting to be "on" for
pair interactions.
The cutoff distance should be set to be at least :math:`max\left[2L,\sqrt{L^2/2+(2R+T_{cut})^2}\right]` ,
where L is the maximum segment length, R is the maximum tube radius, and
:math:`T_{cut}` = 10.2 A is the maximum distance between the surfaces of interacting
segments. Because of the use of extended chain concept at CNT ends, the recommended
cutoff is 3L.
The MESONT-TABTP_10_10.xrs potential file provided with LAMMPS (see the
potentials directory) is parameterized for metal :doc:`units <units>`.
You can use the carbon nanotube mesoscopic force field with any LAMMPS units,
but you would need to create your own TPMSSTP.xrs and TPMA.xrs potential files
with coefficients listed in appropriate units, if your simulation
does not use "metal" units.
The chirality parameters set during system generation must match the values
specified during generation of the potential tables.
Related commands
""""""""""""""""
:doc:`pair_coeff <pair_coeff>`
----------
.. _Srivastava:
**(Srivastava)** Zhigilei, Wei, Srivastava, Phys. Rev. B 71, 165417 (2005).
.. _Zhigilei1:
**(Zhigilei1)** Volkov and Zhigilei, ACS Nano 4, 6187 (2010).
.. _Zhigilei2:
**(Zhigilei2)** Volkov, Simov, Zhigilei, ASME paper IMECE2008, 68021 (2008).
.. _Zhigilei3:
**(Zhigilei3)** Volkov, Zhigilei, J. Phys. Chem. C 114, 5513 (2010).
.. _Zhigilei4:
**(Zhigilei4)** Wittmaack, Banna, Volkov, Zhigilei, Carbon 130, 69 (2018).
.. _Zhigilei5:
**(Zhigilei5)** Wittmaack, Volkov, Zhigilei, Compos. Sci. Technol. 166, 66 (2018).
.. _Zhigilei6:
**(Zhigilei6)** Wittmaack, Volkov, Zhigilei, Carbon 143, 587 (2019).
.. _Zhigilei7:
**(Zhigilei7)** Volkov, Zhigilei, Phys. Rev. Lett. 104, 215902 (2010).
.. _Zhigilei8:
**(Zhigilei8)** Volkov, Shiga, Nicholson, Shiomi, Zhigilei, J. Appl. Phys. 111, 053501 (2012).
.. _Zhigilei9:
**(Zhigilei9)** Volkov, Zhigilei, Appl. Phys. Lett. 101, 043113 (2012).
.. _Zhigilei10:
**(Zhigilei10)** Jacobs, Nicholson, Zemer, Volkov, Zhigilei, Phys. Rev. B 86, 165414 (2012).
.. _Banna:
**(Banna)** Volkov, Banna, Comp. Mater. Sci. 176, 109410 (2020).

View File

@ -245,6 +245,7 @@ accelerated styles exist.
* :doc:`meam/sw/spline <pair_meam_sw_spline>` - splined version of MEAM with a Stillinger-Weber term
* :doc:`mesocnt <pair_mesocnt>` - mesoscale model for (carbon) nanotubes
* :doc:`mgpt <pair_mgpt>` - simplified model generalized pseudopotential theory (MGPT) potential
* :doc:`mesont/tpm <pair_mesont_tpm>` - nanotubes mesoscopic force field
* :doc:`mie/cut <pair_mie>` - Mie potential
* :doc:`mm3/switch3/coulgauss/long <pair_mm3_switch3_coulgauss_long>` - smoothed MM3 vdW potential with Gaussian electrostatics
* :doc:`momb <pair_momb>` - Many-Body Metal-Organic (MOMB) force field

View File

@ -65,6 +65,7 @@ Alejandre
Aleksei
alessandro
Alessandro
Alexey
ali
aliceblue
Allinger
@ -183,6 +184,7 @@ Balasubramanian
Balatsky
Ballenegger
Bammann
Banna
Barashev
barostat
Barostats
@ -204,6 +206,7 @@ bcolor
bdiam
bdw
Beckman
behaviour
Belak
Bellott
benchmarking
@ -339,6 +342,7 @@ cdennist
cdof
ceil
Ceil
centerline
centro
centroid
Centroid
@ -718,6 +722,7 @@ eatom
Eb
Eba
Ebeling
ebend
ebond
ebook
ebt
@ -839,6 +844,7 @@ Eshelby
eshelby
eskm
esph
estretch
esu
esub
esw
@ -850,6 +856,7 @@ ethernet
etol
etot
etotal
etube
Eulerian
eulerian
eulerimplicit
@ -1266,6 +1273,7 @@ interlayer
intermolecular
Interparticle
interstitials
intertube
Intr
intra
intralayer
@ -1426,6 +1434,7 @@ kk
Klahn
Klapp
Kloss
Kloza
kmax
Kmax
KMP
@ -1759,6 +1768,8 @@ meso
mesocnt
MESODPD
mesodpd
MESONT
mesont
mesoparticle
mesoscale
mesoscopic
@ -1933,9 +1944,12 @@ Nangletypes
nano
nanoindentation
Nanoletters
nanomechanics
nanometer
nanometers
nanoparticles
Nanotube
nanotube
nanotubes
Narulkar
nasa
@ -2264,6 +2278,7 @@ Pettifor
pfactor
pgi
ph
Philipp
Phillpot
Philos
phiphi
@ -2642,6 +2657,7 @@ Schulten
Schunk
Schuring
Schwen
screenshot
screenshots
Scripta
sdk
@ -2687,10 +2703,12 @@ Shenderova
Shi
Shiga
Shinoda
Shiomi
shlib
SHM
shm
shockvel
Shugaev
si
SiC
Siepmann
@ -2771,6 +2789,7 @@ src
srd
sright
Srinivasan
Srivastava
Srolovitz
srp
srun
@ -2887,6 +2906,7 @@ tdamp
tdpd
tDPD
Tdrude
Technol
Telsa
tempCorrCoeff
templated
@ -2972,6 +2992,7 @@ Toukmaji
Toxvaerd
tpa
tpc
tpm
tptask
tqx
tqy
@ -3223,6 +3244,7 @@ Wildcard
Wirnsberger
wirtes
witin
Wittmaack
wn
Wolde
workflow
@ -3314,6 +3336,7 @@ ZBL
Zc
zcm
Zeeman
Zemer
Zepeda
zflag
Zhang

View File

@ -0,0 +1 @@
../../../potentials/C_10_10.mesocnt

View File

@ -0,0 +1,19 @@
=== USER-MESONT examples ===
===============================
The files in this folder provide examples of using the CNT
mesoscopic force field (USER-MESONT).
Contributing author: Maxim Shugaev (UVA), mvs9t@virginia.edu
"bundle" is an example with a single bundle composed of 7 nanotubes
using the mesont/tpm pair style
"film" is an example with a film composed of 396 200-nm-long
nanotubes (79596 nodes) using the mesont/tpm pair style
Contributing author: Philipp Kloza (U Cambridge), pak37@cam.ac.uk
"cnt" is an example showing CNT aerogel formation
using the mesocnt pair style

View File

@ -0,0 +1 @@
../../../potentials/TABTP_10_10.mesont

View File

@ -0,0 +1,93 @@
77 atoms
1 atom types
-143.89 143.89 xlo xhi
-143.89 143.89 ylo yhi
0 220 zlo zhi
Masses
1 1.0
Atoms
1 1 1 11 2 5860.43 6.785 20 0 0 0 0 0 0 0
2 1 1 1 3 5860.43 6.785 20 0 0 0 20 0 0 0
3 1 1 2 4 5860.43 6.785 20 0 0 0 40 0 0 0
4 1 1 3 5 5860.43 6.785 20 0 0 0 60 0 0 0
5 1 1 4 6 5860.43 6.785 20 0 0 0 80 0 0 0
6 1 1 5 7 5860.43 6.785 20 0 0 0 100 0 0 0
7 1 1 6 8 5860.43 6.785 20 0 0 0 120 0 0 0
8 1 1 7 9 5860.43 6.785 20 0 0 0 140 0 0 0
9 1 1 8 10 5860.43 6.785 20 0 0 0 160 0 0 0
10 1 1 9 11 5860.43 6.785 20 0 0 0 180 0 0 0
11 1 1 10 1 5860.43 6.785 20 0 0 0 200 0 0 0
12 2 1 22 13 5860.43 6.785 20 0 16.6992 0 0 0 0 0
13 2 1 12 14 5860.43 6.785 20 0 16.6992 0 20 0 0 0
14 2 1 13 15 5860.43 6.785 20 0 16.6992 0 40 0 0 0
15 2 1 14 16 5860.43 6.785 20 0 16.6992 0 60 0 0 0
16 2 1 15 17 5860.43 6.785 20 0 16.6992 0 80 0 0 0
17 2 1 16 18 5860.43 6.785 20 0 16.6992 0 100 0 0 0
18 2 1 17 19 5860.43 6.785 20 0 16.6992 0 120 0 0 0
19 2 1 18 20 5860.43 6.785 20 0 16.6992 0 140 0 0 0
20 2 1 19 21 5860.43 6.785 20 0 16.6992 0 160 0 0 0
21 2 1 20 22 5860.43 6.785 20 0 16.6992 0 180 0 0 0
22 2 1 21 12 5860.43 6.785 20 0 16.6992 0 200 0 0 0
23 3 1 33 24 5860.43 6.785 20 0 8.3496 14.4619 0 0 0 0
24 3 1 23 25 5860.43 6.785 20 0 8.3496 14.4619 20 0 0 0
25 3 1 24 26 5860.43 6.785 20 0 8.3496 14.4619 40 0 0 0
26 3 1 25 27 5860.43 6.785 20 0 8.3496 14.4619 60 0 0 0
27 3 1 26 28 5860.43 6.785 20 0 8.3496 14.4619 80 0 0 0
28 3 1 27 29 5860.43 6.785 20 0 8.3496 14.4619 100 0 0 0
29 3 1 28 30 5860.43 6.785 20 0 8.3496 14.4619 120 0 0 0
30 3 1 29 31 5860.43 6.785 20 0 8.3496 14.4619 140 0 0 0
31 3 1 30 32 5860.43 6.785 20 0 8.3496 14.4619 160 0 0 0
32 3 1 31 33 5860.43 6.785 20 0 8.3496 14.4619 180 0 0 0
33 3 1 32 23 5860.43 6.785 20 0 8.3496 14.4619 200 0 0 0
34 4 1 44 35 5860.43 6.785 20 0 -8.3496 14.4619 0 0 0 0
35 4 1 34 36 5860.43 6.785 20 0 -8.3496 14.4619 20 0 0 0
36 4 1 35 37 5860.43 6.785 20 0 -8.3496 14.4619 40 0 0 0
37 4 1 36 38 5860.43 6.785 20 0 -8.3496 14.4619 60 0 0 0
38 4 1 37 39 5860.43 6.785 20 0 -8.3496 14.4619 80 0 0 0
39 4 1 38 40 5860.43 6.785 20 0 -8.3496 14.4619 100 0 0 0
40 4 1 39 41 5860.43 6.785 20 0 -8.3496 14.4619 120 0 0 0
41 4 1 40 42 5860.43 6.785 20 0 -8.3496 14.4619 140 0 0 0
42 4 1 41 43 5860.43 6.785 20 0 -8.3496 14.4619 160 0 0 0
43 4 1 42 44 5860.43 6.785 20 0 -8.3496 14.4619 180 0 0 0
44 4 1 43 34 5860.43 6.785 20 0 -8.3496 14.4619 200 0 0 0
45 5 1 55 46 5860.43 6.785 20 0 -16.6992 0 0 0 0 0
46 5 1 45 47 5860.43 6.785 20 0 -16.6992 0 20 0 0 0
47 5 1 46 48 5860.43 6.785 20 0 -16.6992 0 40 0 0 0
48 5 1 47 49 5860.43 6.785 20 0 -16.6992 0 60 0 0 0
49 5 1 48 50 5860.43 6.785 20 0 -16.6992 0 80 0 0 0
50 5 1 49 51 5860.43 6.785 20 0 -16.6992 0 100 0 0 0
51 5 1 50 52 5860.43 6.785 20 0 -16.6992 0 120 0 0 0
52 5 1 51 53 5860.43 6.785 20 0 -16.6992 0 140 0 0 0
53 5 1 52 54 5860.43 6.785 20 0 -16.6992 0 160 0 0 0
54 5 1 53 55 5860.43 6.785 20 0 -16.6992 0 180 0 0 0
55 5 1 54 45 5860.43 6.785 20 0 -16.6992 0 200 0 0 0
56 6 1 66 57 5860.43 6.785 20 0 -8.3496 -14.4619 0 0 0 0
57 6 1 56 58 5860.43 6.785 20 0 -8.3496 -14.4619 20 0 0 0
58 6 1 57 59 5860.43 6.785 20 0 -8.3496 -14.4619 40 0 0 0
59 6 1 58 60 5860.43 6.785 20 0 -8.3496 -14.4619 60 0 0 0
60 6 1 59 61 5860.43 6.785 20 0 -8.3496 -14.4619 80 0 0 0
61 6 1 60 62 5860.43 6.785 20 0 -8.3496 -14.4619 100 0 0 0
62 6 1 61 63 5860.43 6.785 20 0 -8.3496 -14.4619 120 0 0 0
63 6 1 62 64 5860.43 6.785 20 0 -8.3496 -14.4619 140 0 0 0
64 6 1 63 65 5860.43 6.785 20 0 -8.3496 -14.4619 160 0 0 0
65 6 1 64 66 5860.43 6.785 20 0 -8.3496 -14.4619 180 0 0 0
66 6 1 65 56 5860.43 6.785 20 0 -8.3496 -14.4619 200 0 0 0
67 7 1 77 68 5860.43 6.785 20 0 8.3496 -14.4619 0 0 0 0
68 7 1 67 69 5860.43 6.785 20 0 8.3496 -14.4619 20 0 0 0
69 7 1 68 70 5860.43 6.785 20 0 8.3496 -14.4619 40 0 0 0
70 7 1 69 71 5860.43 6.785 20 0 8.3496 -14.4619 60 0 0 0
71 7 1 70 72 5860.43 6.785 20 0 8.3496 -14.4619 80 0 0 0
72 7 1 71 73 5860.43 6.785 20 0 8.3496 -14.4619 100 0 0 0
73 7 1 72 74 5860.43 6.785 20 0 8.3496 -14.4619 120 0 0 0
74 7 1 73 75 5860.43 6.785 20 0 8.3496 -14.4619 140 0 0 0
75 7 1 74 76 5860.43 6.785 20 0 8.3496 -14.4619 160 0 0 0
76 7 1 75 77 5860.43 6.785 20 0 8.3496 -14.4619 180 0 0 0
77 7 1 76 67 5860.43 6.785 20 0 8.3496 -14.4619 200 0 0 0

79612
examples/USER/mesont/data.film Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,29 @@
processors 1 1 *
newton on
units metal
lattice sc 1.0
boundary fs fs p
neighbor 1.0 bin
neigh_modify every 5 delay 0 check yes
atom_style mesont
# cut, path, BendingMode, TPMType
pair_style mesont/tpm 45.0 MESONT-TABTP_10_10.xrs 0 0
read_data data.bundle
pair_coeff * *
velocity all create 6000.0 2019
timestep 0.005
fix 1 all nve
thermo 10
reset_timestep 0
compute Es all mesont estretch
compute Eb all mesont ebend
compute Et all mesont etube
compute B all property/atom buckling
thermo_style custom step time temp etotal ke pe c_Es c_Eb c_Et
#dump out_dump all custom 50 dump.bundle id type x y z c_Es c_Eb c_Et c_B ix iy iz
run 100

View File

@ -0,0 +1,28 @@
newton on
units metal
lattice sc 1.0
boundary p p fs
neighbor 1.0 bin
neigh_modify every 5 delay 0 check yes
atom_style mesont
# cut, path, BendingMode, TPMType
pair_style mesont/tpm 30.0 MESONT-TABTP_10_10.xrs 1 0
read_data data.film
pair_coeff * *
velocity all create 600.0 2019
timestep 0.01
fix 1 all nve
thermo 10
reset_timestep 0
compute Es all mesont estretch
compute Eb all mesont ebend
compute Et all mesont etube
compute B all property/atom buckling
thermo_style custom step time temp etotal ke pe c_Es c_Eb c_Et
#dump out_dump all custom 10 dump.film id type x y z c_Es c_Eb c_Et c_B ix iy iz
run 20

View File

@ -0,0 +1,90 @@
LAMMPS (5 May 2020)
processors 1 1 *
newton on
units metal
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
boundary fs fs p
neighbor 1.0 bin
neigh_modify every 5 delay 0 check yes
atom_style mesont
# cut, path, BendingMode, TPMType
pair_style mesont/tpm 45.0 MESONT-TABTP_10_10.xrs 0 0
read_data data.bundle
orthogonal box = (-143.89 -143.89 0) to (143.89 143.89 220)
1 by 1 by 1 MPI processor grid
reading atoms ...
77 atoms
read_data CPU = 0.000613213 secs
pair_coeff * *
velocity all create 6000.0 2019
timestep 0.005
fix 1 all nve
thermo 10
reset_timestep 0
compute Es all mesont estretch
compute Eb all mesont ebend
compute Et all mesont etube
compute B all property/atom buckling
thermo_style custom step time temp etotal ke pe c_Es c_Eb c_Et
#dump out_dump all custom 50 dump.bundle id type x y z c_Es c_Eb c_Et c_B ix iy iz
run 100
Neighbor list info ...
update every 5 steps, delay 0 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 46
ghost atom cutoff = 46
binsize = 23, bins = 7 7 10
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair mesont/tpm, perpetual
attributes: full, newton on, ghost
pair build: full/bin/ghost
stencil: full/ghost/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 4.675 | 4.675 | 4.675 Mbytes
Step Time Temp TotEng KinEng PotEng c_Es c_Eb c_Et
0 0 6000 -201.86935 58.942626 -260.81198 0 0 -260.81198
10 0.05 5114.1875 -201.86234 50.240607 -252.10295 4.8334861 2.3998206 -259.33626
20 0.1 3437.2958 -201.8522 33.767207 -235.61941 11.42384 8.3426957 -255.38594
30 0.15 2430.6571 -201.85242 23.878219 -225.73064 10.346152 14.72688 -250.80367
40 0.2 2154.4755 -201.85683 21.165074 -223.0219 6.8146112 18.325709 -248.16222
50 0.25 2021.7899 -201.85503 19.861601 -221.71663 9.2972022 17.644143 -248.65798
60 0.3 2234.553 -201.85193 21.951737 -223.80367 13.541921 13.673721 -251.01931
70 0.35 3099.6503 -201.85721 30.450255 -232.30747 11.833679 9.0583807 -253.19953
80 0.4 3849.9855 -201.8635 37.821376 -239.68487 7.9899173 6.4332848 -254.10807
90 0.45 3618.1311 -201.85967 35.543692 -237.40336 9.2616931 7.0452637 -253.71032
100 0.5 2866.2722 -201.85273 28.157602 -230.01033 12.204916 10.284525 -252.49977
Loop time of 0.419735 on 1 procs for 100 steps with 77 atoms
Performance: 102.922 ns/day, 0.233 hours/ns, 238.245 timesteps/s
99.8% CPU use with 1 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.41922 | 0.41922 | 0.41922 | 0.0 | 99.88
Neigh | 5.8174e-05 | 5.8174e-05 | 5.8174e-05 | 0.0 | 0.01
Comm | 7.0333e-05 | 7.0333e-05 | 7.0333e-05 | 0.0 | 0.02
Output | 0.00017667 | 0.00017667 | 0.00017667 | 0.0 | 0.04
Modify | 0.00011945 | 0.00011945 | 0.00011945 | 0.0 | 0.03
Other | | 8.702e-05 | | | 0.02
Nlocal: 77 ave 77 max 77 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 35 ave 35 max 35 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 0 ave 0 max 0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs: 2222 ave 2222 max 2222 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 2222
Ave neighs/atom = 28.8571
Neighbor list builds = 1
Dangerous builds = 0
Total wall time: 0:00:01

View File

@ -0,0 +1,90 @@
LAMMPS (5 May 2020)
processors 1 1 *
newton on
units metal
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
boundary fs fs p
neighbor 1.0 bin
neigh_modify every 5 delay 0 check yes
atom_style mesont
# cut, path, BendingMode, TPMType
pair_style mesont/tpm 45.0 MESONT-TABTP_10_10.xrs 0 0
read_data data.bundle
orthogonal box = (-143.89 -143.89 0) to (143.89 143.89 220)
1 by 1 by 4 MPI processor grid
reading atoms ...
77 atoms
read_data CPU = 0.000590563 secs
pair_coeff * *
velocity all create 6000.0 2019
timestep 0.005
fix 1 all nve
thermo 10
reset_timestep 0
compute Es all mesont estretch
compute Eb all mesont ebend
compute Et all mesont etube
compute B all property/atom buckling
thermo_style custom step time temp etotal ke pe c_Es c_Eb c_Et
#dump out_dump all custom 50 dump.bundle id type x y z c_Es c_Eb c_Et c_B ix iy iz
run 100
Neighbor list info ...
update every 5 steps, delay 0 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 46
ghost atom cutoff = 46
binsize = 23, bins = 7 7 10
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair mesont/tpm, perpetual
attributes: full, newton on, ghost
pair build: full/bin/ghost
stencil: full/ghost/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 4.671 | 4.671 | 4.671 Mbytes
Step Time Temp TotEng KinEng PotEng c_Es c_Eb c_Et
0 0 6000 -201.86935 58.942626 -260.81198 0 0 -260.81198
10 0.05 5114.1875 -201.86234 50.240607 -252.10295 4.8334861 2.3998206 -259.33626
20 0.1 3437.2958 -201.8522 33.767207 -235.61941 11.42384 8.3426957 -255.38594
30 0.15 2430.6571 -201.85242 23.878219 -225.73064 10.346152 14.72688 -250.80367
40 0.2 2154.4755 -201.85683 21.165074 -223.0219 6.8146112 18.325709 -248.16222
50 0.25 2021.7899 -201.85503 19.861601 -221.71663 9.2972022 17.644143 -248.65798
60 0.3 2234.553 -201.85193 21.951737 -223.80367 13.541921 13.673721 -251.01931
70 0.35 3099.6503 -201.85721 30.450255 -232.30747 11.833679 9.0583807 -253.19953
80 0.4 3849.9855 -201.8635 37.821376 -239.68487 7.9899173 6.4332848 -254.10807
90 0.45 3618.1311 -201.85967 35.543692 -237.40336 9.2616931 7.0452637 -253.71032
100 0.5 2866.2722 -201.85273 28.157602 -230.01033 12.204916 10.284525 -252.49977
Loop time of 0.145545 on 4 procs for 100 steps with 77 atoms
Performance: 296.815 ns/day, 0.081 hours/ns, 687.071 timesteps/s
95.9% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 0.046723 | 0.097529 | 0.14388 | 11.0 | 67.01
Neigh | 2.5511e-05 | 2.8729e-05 | 3.171e-05 | 0.0 | 0.02
Comm | 0.00058556 | 0.045174 | 0.098462 | 16.5 | 31.04
Output | 0.0001483 | 0.0010182 | 0.002851 | 3.5 | 0.70
Modify | 3.8147e-05 | 4.065e-05 | 4.4107e-05 | 0.0 | 0.03
Other | | 0.001755 | | | 1.21
Nlocal: 19.25 ave 21 max 16 min
Histogram: 1 0 0 0 0 0 1 0 0 2
Nghost: 33.25 ave 40 max 28 min
Histogram: 2 0 0 0 0 0 0 1 0 1
Neighs: 0 ave 0 max 0 min
Histogram: 4 0 0 0 0 0 0 0 0 0
FullNghs: 555.5 ave 606 max 460 min
Histogram: 1 0 0 0 0 0 1 0 0 2
Total # of neighbors = 2222
Ave neighs/atom = 28.8571
Neighbor list builds = 1
Dangerous builds = 0
Total wall time: 0:00:01

View File

@ -0,0 +1,81 @@
LAMMPS (5 May 2020)
newton on
units metal
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
boundary p p fs
neighbor 1.0 bin
neigh_modify every 5 delay 0 check yes
atom_style mesont
# cut, path, BendingMode, TPMType
pair_style mesont/tpm 30.0 MESONT-TABTP_10_10.xrs 1 0
read_data data.film
orthogonal box = (-2500 -2500 -300) to (2500 2500 402.42)
1 by 1 by 1 MPI processor grid
reading atoms ...
79596 atoms
read_data CPU = 0.0860629 secs
pair_coeff * *
velocity all create 600.0 2019
timestep 0.01
fix 1 all nve
thermo 10
reset_timestep 0
compute Es all mesont estretch
compute Eb all mesont ebend
compute Et all mesont etube
compute B all property/atom buckling
thermo_style custom step time temp etotal ke pe c_Es c_Eb c_Et
#dump out_dump all custom 10 dump.film id type x y z c_Es c_Eb c_Et c_B ix iy iz
run 20
Neighbor list info ...
update every 5 steps, delay 0 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 31
ghost atom cutoff = 31
binsize = 15.5, bins = 323 323 26
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair mesont/tpm, perpetual
attributes: full, newton on, ghost
pair build: full/bin/ghost
stencil: full/ghost/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 37.43 | 37.43 | 37.43 Mbytes
Step Time Temp TotEng KinEng PotEng c_Es c_Eb c_Et
0 0 600 1347.2158 6173.0767 -4825.8609 28.669574 21.29406 -4875.8245
10 0.1 389.40755 1373.7864 4006.4045 -2632.6181 848.00267 1404.4323 -4885.053
20 0.2 313.65714 1399.9427 3227.0494 -1827.1067 1201.1732 1882.1342 -4910.4141
Loop time of 10.2438 on 1 procs for 20 steps with 79596 atoms
Performance: 1.687 ns/day, 14.228 hours/ns, 1.952 timesteps/s
99.0% CPU use with 1 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 10.226 | 10.226 | 10.226 | 0.0 | 99.82
Neigh | 0 | 0 | 0 | 0.0 | 0.00
Comm | 0.00081086 | 0.00081086 | 0.00081086 | 0.0 | 0.01
Output | 0.00046563 | 0.00046563 | 0.00046563 | 0.0 | 0.00
Modify | 0.015165 | 0.015165 | 0.015165 | 0.0 | 0.15
Other | | 0.001869 | | | 0.02
Nlocal: 79596 ave 79596 max 79596 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Nghost: 1879 ave 1879 max 1879 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Neighs: 0 ave 0 max 0 min
Histogram: 1 0 0 0 0 0 0 0 0 0
FullNghs: 642270 ave 642270 max 642270 min
Histogram: 1 0 0 0 0 0 0 0 0 0
Total # of neighbors = 642270
Ave neighs/atom = 8.06912
Neighbor list builds = 0
Dangerous builds = 0
Total wall time: 0:00:11

View File

@ -0,0 +1,81 @@
LAMMPS (5 May 2020)
newton on
units metal
lattice sc 1.0
Lattice spacing in x,y,z = 1 1 1
boundary p p fs
neighbor 1.0 bin
neigh_modify every 5 delay 0 check yes
atom_style mesont
# cut, path, BendingMode, TPMType
pair_style mesont/tpm 30.0 MESONT-TABTP_10_10.xrs 1 0
read_data data.film
orthogonal box = (-2500 -2500 -300) to (2500 2500 402.42)
2 by 2 by 1 MPI processor grid
reading atoms ...
79596 atoms
read_data CPU = 0.0704217 secs
pair_coeff * *
velocity all create 600.0 2019
timestep 0.01
fix 1 all nve
thermo 10
reset_timestep 0
compute Es all mesont estretch
compute Eb all mesont ebend
compute Et all mesont etube
compute B all property/atom buckling
thermo_style custom step time temp etotal ke pe c_Es c_Eb c_Et
#dump out_dump all custom 10 dump.film id type x y z c_Es c_Eb c_Et c_B ix iy iz
run 20
Neighbor list info ...
update every 5 steps, delay 0 steps, check yes
max neighbors/atom: 2000, page size: 100000
master list distance cutoff = 31
ghost atom cutoff = 31
binsize = 15.5, bins = 323 323 26
1 neighbor lists, perpetual/occasional/extra = 1 0 0
(1) pair mesont/tpm, perpetual
attributes: full, newton on, ghost
pair build: full/bin/ghost
stencil: full/ghost/bin/3d
bin: standard
Per MPI rank memory allocation (min/avg/max) = 12.81 | 12.81 | 12.83 Mbytes
Step Time Temp TotEng KinEng PotEng c_Es c_Eb c_Et
0 0 600 1347.2158 6173.0767 -4825.8609 28.669574 21.29406 -4875.8245
10 0.1 389.40755 1373.7864 4006.4045 -2632.6181 848.00267 1404.4323 -4885.053
20 0.2 313.65714 1399.9427 3227.0494 -1827.1067 1201.1732 1882.1342 -4910.4141
Loop time of 3.67186 on 4 procs for 20 steps with 79596 atoms
Performance: 4.706 ns/day, 5.100 hours/ns, 5.447 timesteps/s
95.8% CPU use with 4 MPI tasks x no OpenMP threads
MPI task timing breakdown:
Section | min time | avg time | max time |%varavg| %total
---------------------------------------------------------------
Pair | 2.7317 | 3.1286 | 3.6556 | 18.8 | 85.20
Neigh | 0 | 0 | 0 | 0.0 | 0.00
Comm | 0.0036943 | 0.53094 | 0.92822 | 45.8 | 14.46
Output | 0.00026512 | 0.00035298 | 0.00055647 | 0.0 | 0.01
Modify | 0.010463 | 0.010884 | 0.011153 | 0.3 | 0.30
Other | | 0.001109 | | | 0.03
Nlocal: 19899 ave 21951 max 18667 min
Histogram: 1 1 0 1 0 0 0 0 0 1
Nghost: 970.75 ave 1031 max 920 min
Histogram: 1 0 0 1 1 0 0 0 0 1
Neighs: 0 ave 0 max 0 min
Histogram: 4 0 0 0 0 0 0 0 0 0
FullNghs: 160568 ave 181723 max 147382 min
Histogram: 1 0 2 0 0 0 0 0 0 1
Total # of neighbors = 642270
Ave neighs/atom = 8.06912
Neighbor list builds = 0
Dangerous builds = 0
Total wall time: 0:00:04

View File

@ -1 +0,0 @@
../../../../potentials/C_10_10.mesocnt

13
lib/mesont/.depend Normal file
View File

@ -0,0 +1,13 @@
CNTPot.o: CNTPot.f90 TPMLib.o
ExportCNT.o: ExportCNT.f90 CNTPot.o TPMLib.o TubePotMono.o TPMForceField.o
LinFun2.o: LinFun2.f90
Spline1.o: Spline1.f90
Spline2.o: Spline2.f90 Spline1.o
TPMForceField.o: TPMForceField.f90 CNTPot.o TPMM0.o TPMM1.o
TPMGeom.o: TPMGeom.f90 TPMLib.o
TPMLib.o: TPMLib.f90
TPMM0.o: TPMM0.f90 TubePotMono.o
TPMM1.o: TPMM1.f90 TubePotMono.o
TubePotBase.o: TubePotBase.f90 TPMLib.o
TubePotMono.o: TubePotMono.f90 TPMLib.o TPMGeom.o TubePotBase.o TubePotTrue.o LinFun2.o Spline2.o
TubePotTrue.o: TubePotTrue.f90 TPMGeom.o TubePotBase.o

1
lib/mesont/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
*.mod

714
lib/mesont/CNTPot.f90 Normal file
View File

@ -0,0 +1,714 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module CNTPot !*************************************************************************************
!
! Mesoscopic potential for internal modes in CNTs.
!
!---------------------------------------------------------------------------------------------------
!
! Carbon nanotubes internal potentials:
! CNTSTRH0, harmonic stretching potential of type 0 with constant Young's modulus
! CNTSTRH1, harmonic stretching potential of type 1 with variable Young's modulus
! CNTSTRNH0, non-harmonic stretching with fracture potential of type 0
! CNTSTRNH1, non-harmonic stretching with fracture potential of type 1
! CNTBNDH, harmonic bending potential
! CNTBNDHB, harmonic bending-buckling potential
! CNTBNDHBF, harmonic bending-buckling potential with fracture
! CNTTRS, torsion potential
! CNTBRT, breathing potential
!
! The functional form and force constants of harmonic stretching, bending and
! torsion potentials are taken from:
! L.V. Zhigilei, Ch. Wei, D. Srivastava, Phys. Rev. B 71, 165417 (2005)
!
! The model of stress-strain curve for the non-harmonic potential with fracture
! is developed and parameterized using the following constants
! -- Young's modulus
! -- maximum linear strain (only for the NH potential of type 1)
! -- tensile strength (or fracture strain)
! -- strain at failure (or fracture strain)
! -- maximum strain.
! All these parameters are assumed to be independent of CNT radius or chriality type.
! In this model, the true strain at failure CNTSTREft and true tensile strength
! CNTSTRSft are slightly different from the imposed values CNTSTREf and CNTSTRSf.
!
! The non-harmonic stretching potentials of types 0 and 1 are different from
! each other by the functional form of the stress-strain curve
!
! Different parameterizations of CNTSTRH0, CNTSTRNH0 and CNTSTRNH1 potentials can be chosen,
! see subroutine CNTSTRSetParameterization
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!***************************************************************************************************
use TPMLib
use iso_c_binding, only : c_int, c_double, c_char
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
integer(c_int), parameter :: CNTPOT_STRETCHING = 0
integer(c_int), parameter :: CNTPOT_SBUCKLING = 1
integer(c_int), parameter :: CNTPOT_SFRACTURE = 2
integer(c_int), parameter :: CNTPOT_BENDING = 3
integer(c_int), parameter :: CNTPOT_BBUCKLING = 4
integer(c_int), parameter :: CNTPOT_BFRACTURE = 5
! Harmonic stretching model (constant Young's modulus)
integer(c_int), parameter :: CNTSTRMODEL_H0 = 0
! Harmonic stretching model (Young's modulus depends on radius)
integer(c_int), parameter :: CNTSTRMODEL_H1 = 1
! Non-harmonic stretching with fracture, potential of type 0
integer(c_int), parameter :: CNTSTRMODEL_NH0F = 2
! Non-harmonic stretching without fracture, potential of type 1
integer(c_int), parameter :: CNTSTRMODEL_NH1 = 3
! Non-harmonic stretching with fracture, potential of type 1
integer(c_int), parameter :: CNTSTRMODEL_NH1F = 4
! Harmonic stretching model + axial buckling
integer(c_int), parameter :: CNTSTRMODEL_H1B = 5
! Harmonic stretching model + axial buckling + hysteresis
integer(c_int), parameter :: CNTSTRMODEL_H1BH = 6
integer(c_int), parameter :: CNTBNDMODEL_H = 0 ! Harmonic bending model
integer(c_int), parameter :: CNTBNDMODEL_HB = 1 ! Harmonic bending - buckling model
integer(c_int), parameter :: CNTBNDMODEL_HBF = 2 ! Harmonic bending - buckling - fracture model
integer(c_int), parameter :: CNTBNDMODEL_HBH = 3 ! Harmonic bending - buckling + Hysteresis
integer(c_int), parameter :: CNTPOTNMAX = 4000 ! Maximum number of points in the interpolation tables
!---------------------------------------------------------------------------------------------------
! Parameters of potentials
!---------------------------------------------------------------------------------------------------
! Stretching potential
! Type of the bending model
integer(c_int) :: CNTSTRModel = CNTSTRMODEL_H1
! Type of parameterization
integer(c_int) :: CNTSTRParams = 0
! Type of dependence of the Young's modulus on tube radius
integer(c_int) :: CNTSTRYMT = 0
! Parameters of non-harmonic potential and fracture model
real(c_double) :: CNTSTRR0 = 6.8d+00 ! Reference radius of nanotubes (A)
! (this parameter is not used for the model
! parametrization, but only for calculation of the
! force constant in eV/A)
real(c_double) :: CNTSTRD0 = 3.4d+00 ! CNT wall thickness (A)
real(c_double) :: CNTSTREmin = -0.4d+00 ! Minimum strain in tabulated potential
real(c_double) :: CNTSTREmax = 0.13d+00 ! Maximum strain in tabulated potential.
! Simultaneously, U=0 if E> CNTSTREmax
real(c_double) :: CNTSTREl = 5.0d-02 ! Maximum linear strain
real(c_double) :: CNTSTREf = 12.0d-02 ! Strain at failure
real(c_double) :: CNTSTRS0 = 0.850e+12 ! Young's modulus (Pa)
real(c_double) :: CNTSTRSl ! Maximum linear stress (Pa)
real(c_double) :: CNTSTRSf = 75.0d+09 ! Tensile strength (Pa)
real(c_double) :: CNTSTRF0 ! Elastic force constant (eV/A**2)
real(c_double) :: CNTSTRFl ! Maximal linear force, (eV/A**2)
real(c_double) :: CNTSTRFf ! Tensile force at failure (eV/A**2)
real(c_double) :: CNTSTRSi ! Maximum stress (not used in the model) (Pa)
real(c_double) :: CNTSTRDf ! dF/dE at failure
real(c_double) :: CNTSTRAA, CNTSTRBB !
real(c_double) :: CNTSTRAAA, CNTSTRBBB ! Auxiliary constants
real(c_double) :: CNTSTRUl, CNTSTRUf !
! Axial buckling - hysteresis approach
real(c_double) :: CNTSTREc = -0.0142d+00 ! The minimum buckling strain
real(c_double) :: CNTSTREc1 = -0.04d+00 ! Critical axial buckling strain
real(c_double) :: CNTSTREc2 = -0.45d+00 ! Maximum buckling strain
! Bending potential
integer(c_int) :: CNTBNDModel = CNTBNDMODEL_H ! Type of the bending model
! Buckling model parameters
real(c_double) :: CNTBNDN = 1.0d+00 ! Buckling exponent
real(c_double) :: CNTBNDB = 0.68d+00 ! Buckling number
real(c_double) :: CNTBNDR = 275.0d+00 ! Critical radius of curvature (A)
! This is the mean value for (10,10) SWCNT
real(c_double) :: CNTBNDTF = M_PI * 120.0d+00 / 180.0d+00 ! Fracture buckling angle (rad)
real(c_double) :: CNTBNDN1
real(c_double) :: CNTBNDC2
contains !******************************************************************************************
!---------------------------------------------------------------------------------------------------
! Stretching potential
!---------------------------------------------------------------------------------------------------
subroutine CNTSTRSetParameterization ( PType ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This subroutine setups parameters for further parameterization of stretching models
! References:
! [1] Yu M.-F. et al., Phys. Rev. Lett. 84(24), 5552 (2000)
! [2] Liew K.M. et al., Acta Materialia 52, 2521 (2004)
! [3] Mielke S.L. et al., Chem. Phys. Lett. 390, 413 (2004)
! [4] Zhigilei L.V. et al., Phys. Rev. B 71, 165417 (2005)
! [5] Kelly B.T., Physics of graphite, 1981
!-------------------------------------------------------------------------------------------
integer(c_int), intent(in) :: PType
!-------------------------------------------------------------------------------------------
select case ( PType )
case ( 0 ) ! This parametrization is based on averaged exp. data of Ref. [1]
CNTSTRR0 = 6.8d+00 ! Ref. [1]
CNTSTRD0 = 3.4d+00 ! Ref. [1]
CNTSTREmin = -0.4d+00 ! Chosen arbitrary
CNTSTREmax = 3.64d-02 ! = CNTSTREf + 0.005
CNTSTREl = 2.0d-02 ! Chosen arbitrary
CNTSTREf = 3.14d-02 ! Ref. [1]
CNTSTRS0 = 1.002e+12 ! Ref. [1]
CNTSTRSf = 30.0d+09 ! Ref. [1]
case ( 1 ) ! This parameterization is taken from Ref. [2] for (10,10) CNTs.
! These values are obtained in MD simulations with REBO potential.
! Values of Young's modulus, tensile strength and stress here
! are close to those obtained in Ref. [3] for pristine (defectless)
! (5,5) CNT in semi-empirical QM calculations based on PM3 model
CNTSTRR0 = 6.785d+00 ! Calculated with the usual formula for (10,10) CNT
CNTSTRD0 = 3.35d+00 ! Ref. [2]
CNTSTREmin = -0.4d+00 ! Chosen arbitrary
CNTSTREmax = 28.4d-02 ! = CNTSTREf + 0.005
CNTSTREl = 5.94d-02 ! Ref. [2]
CNTSTREf = 27.9d-02 ! Corresponds to maximum strain in Ref. [2]
CNTSTRS0 = 1.031e+12 ! Ref. [2]
CNTSTRSf = 148.5d+09 ! Corresponds to tensile strength in Ref. [2]
case ( 2 ) ! This parametrization is taken from Ref. [3] for (5,5) CNTs
! with one atom vacancy defect obtained with the semi-empirical QM PM3 model
CNTSTRR0 = 3.43d+00 ! Ref. [3]
CNTSTRD0 = 3.4d+00 ! Ref. [3]
CNTSTREmin = -0.4d+00 ! Chosen arbitrary
CNTSTREmax = 15.8d-02 ! = CNTSTREf + 0.005
CNTSTREl = 6.00d-02 ! Chosen similar to Ref. [2]
CNTSTREf = 15.3d-02 ! Ref. [3]
CNTSTRS0 = 1.100e+12 ! Ref. [3]
CNTSTRSf = 100.0d+09 ! Ref. [3]
case ( 3 ) ! This special parameterization changes only the value of Young's modulus
! in accordance with the stretching constant in Ref. [4]
CNTSTRS0 = ( 86.64d+00 + 100.56d+00 * CNTSTRR0 ) * K_MDFU &
/ ( M_2PI * CNTSTRR0 * CNTSTRD0 * 1.0d-20 ) ! Ref. [4]
case ( 4 ) ! This special parameterization changes only the value of Young's modulus
! making it equal to the in-plane Young's modulus of graphite
CNTSTRR0 = 6.785d+00 ! Calculated with the usual formula for (10,10) CNT
CNTSTRD0 = 3.4d+00 ! Ref. [1]
CNTSTRS0 = 1.06e+12 ! Ref. [5]
end select
end subroutine CNTSTRSetParameterization !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Stretching without fracture, harmonic potential
!
integer(c_int) function CNTSTRH0Calc ( U, dUdL, L, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Young's modulus is independent of R.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: U, dUdL
real(c_double), intent(in) :: L, R0, L0
real(c_double) :: E
!-------------------------------------------------------------------------------------------
E = ( L - L0 ) / L0
dUdL = R0 * CNTSTRF0 * E
U = 0.5d+00 * L0 * E * dUdL
CNTSTRH0Calc = CNTPOT_STRETCHING
end function CNTSTRH0Calc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function CNTSTRH1Calc ( U, dUdL, L, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Young's modulus depends on R, see [4].
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: U, dUdL
real(c_double), intent(in) :: L, R0, L0
real(c_double) :: E, K
!-------------------------------------------------------------------------------------------
E = ( L - L0 ) / L0
K = 86.64d+00 + 100.56d+00 * R0
dUdL = K * E
U = 0.5d+00 * L0 * E * dUdL
CNTSTRH1Calc = CNTPOT_STRETCHING
end function CNTSTRH1Calc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Stretching without fracture, harmonic potential, with axial buckling without hysteresis
!
integer(c_int) function CNTSTRH1BCalc ( U, dUdL, L, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Young's modulus depends on R, see [4].
! Axial buckling without hysteresis.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: U, dUdL
real(c_double), intent(in) :: L, R0, L0
real(c_double) :: E, K, Kbcl, dUbcl, d, ud
!-------------------------------------------------------------------------------------------
E = ( L - L0 ) / L0
K = 86.64d+00 + 100.56d+00 * R0
Kbcl = -10.98d+00 * L0
if ( E .gt. CNTSTREc ) then ! Harmonic stretching
dUdL = K * E
U = 0.5d+00 * L0 * E * dUdL
CNTSTRH1BCalc = CNTPOT_STRETCHING
else if ( E .gt. CNTSTREc2 ) then ! Axial buckling
dUbcl = 0.5d+00 * L0 * K * CNTSTREc * CNTSTREc - Kbcl * CNTSTREc
U = Kbcl * E + dUbcl
dUdL = Kbcl / L0
CNTSTRH1BCalc = CNTPOT_STRETCHING
else ! Return to harmonic potential
d = -0.0142794
dUdL = K * ( d + E - CNTSTREc2 )
dUbcl = 0.5d+00 * L0 * K * CNTSTREc * CNTSTREc - Kbcl * CNTSTREc + Kbcl * CNTSTREc2
Ud = 0.5d+00 * L0 * K * d * d
U = 0.5d+00 * L0 * (d+E-CNTSTREc2) * dUdL + dUbcl - Ud
CNTSTRH1BCalc = CNTPOT_STRETCHING
end if
end function CNTSTRH1BCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Stretching without fracture, harmonic potential, with axial buckling with hysteresis
!
integer(c_int) function CNTSTRH1BHCalc ( U, dUdL, L, R0, L0, ABF, Ebuc ) !!!!!!!!!!!!!!!!!!!
! Young's modulus depends on R, see [4]
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: U, dUdL, Ebuc
real(c_double), intent(in) :: L, R0, L0
integer(c_int), intent(in) :: ABF
!-------------------------------------------------------------------------------------------
real(c_double) :: E, K, dUbcl, Ebcl, Kbcl, Edu
real(c_double) :: C, DE, t
!-------------------------------------------------------------------------------------------
E = ( L - L0 ) / L0
K = 86.64d+00 + 100.56d+00 * R0
Kbcl = -10.98d+00 * L0
if ( E .gt. CNTSTREc ) then ! Harmonic potential - no buckling
dUdL = K * E
U = 0.5d+00 * L0 * E * dUdL
CNTSTRH1BHCalc = CNTPOT_STRETCHING
Ebuc = 0.0d+00
else if ( E .gt. CNTSTREc1 ) then ! Above minimal buckling strain, but not at critical strain
if ( ABF .eq. 0 ) then ! Not buckled. Continue harmonic potential
dUdL = K * E
U = 0.5d+00 * L0 * E * dUdL
CNTSTRH1BHCalc = CNTPOT_STRETCHING
Ebuc = 0.0d+00
else ! Relaxing from buckled state. Use buckling potential
dUbcl = 0.5d+00 * L0 * K * CNTSTREc * CNTSTREc - Kbcl * CNTSTREc
U = Kbcl * E + dUbcl
dUdL = Kbcl / L0
CNTSTRH1BHCalc = CNTPOT_SBUCKLING
Ebuc = 0.0d+00
end if
else if( E .gt. CNTSTREc2 ) then ! Axial buckling strain region
if ( ABF .eq. 0 ) then ! Newly buckled
dUbcl = 0.5d+00 * L0 * K * CNTSTREc * CNTSTREc - Kbcl * CNTSTREc
U = Kbcl * E + dUbcl
dUdL = Kbcl / L0
CNTSTRH1BHCalc = CNTPOT_SBUCKLING
Ebuc = 0.5d+00 * L0 * K * CNTSTREc1 * CNTSTREc1 - Kbcl * CNTSTREc1 - dUbcl
else ! Already buckled
dUbcl = 0.5d+00 * L0 * K * CNTSTREc * CNTSTREc - Kbcl * CNTSTREc
U = Kbcl * E + dUbcl
dUdL = Kbcl / L0
CNTSTRH1BHCalc = CNTPOT_SBUCKLING
Ebuc = 0.0d+00
end if
else ! Maximum strain and return to harmonic potential
dUdL = K * E
U = 0.5d+00 * L0 * E * dUdL
CNTSTRH1BHCalc = CNTPOT_STRETCHING
Ebuc = 0.0d+00
end if
end function CNTSTRH1BHCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Stretching with fracture, non-harmonic potential of type 0
!
integer(c_int) function CNTSTRNH0FCalc ( U, dUdL, L, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdL
real(c_double), intent(in) :: L, R0, L0
real(c_double) :: E, DE, t
!-------------------------------------------------------------------------------------------
E = ( L - L0 ) / L0
if ( E < CNTSTREf ) then
dUdL = ( CNTSTRAA - CNTSTRBB * E ) * E
U = ( CNTSTRAAA - CNTSTRBBB * E ) * E * E
CNTSTRNH0FCalc = CNTPOT_STRETCHING
else
dUdL = 0.0d+00
U = 0.0d+00
CNTSTRNH0FCalc = CNTPOT_SFRACTURE
end if
U = L0 * R0 * U
dUdL = R0 * dUdL
end function CNTSTRNH0FCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CNTSTRNH0Init () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) :: S
!-------------------------------------------------------------------------------------------
S = M_2PI * CNTSTRD0 * 1.0e-20 / K_MDFU
CNTSTRSl = CNTSTRS0 * CNTSTREl
CNTSTRF0 = CNTSTRS0 * S
CNTSTRFl = CNTSTRSl * S
CNTSTRFf = CNTSTRSf * S
CNTSTRAA = CNTSTRF0
CNTSTRBB = ( CNTSTRF0 * CNTSTREf - CNTSTRFf ) / ( CNTSTREf * CNTSTREf )
CNTSTRAAA= CNTSTRAA / 2.0d+00
CNTSTRBBB= CNTSTRAA / 3.0d+00
CNTSTRUl = 0.0d+00
CNTSTRUf = ( CNTSTRAAA - CNTSTRBBB * CNTSTREf ) * CNTSTREf * CNTSTREf
! These two values are not defined yet
CNTSTRSi = 0.0d+00
CNTSTRDf = 0.0d+00
end subroutine CNTSTRNH0Init !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Stretching without fracture, non-harmonic potential of type 1
!
integer(c_int) function CNTSTRNH1Calc ( U, dUdL, L, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdL
real(c_double), intent(in) :: L, R0, L0
real(c_double) :: E, C, DE, t
!-------------------------------------------------------------------------------------------
E = ( L - L0 ) / L0
if ( E < CNTSTREl ) then
dUdL = CNTSTRF0 * E
U = 0.5d+00 * E * dUdL
CNTSTRNH1Calc = CNTPOT_STRETCHING
else
DE = E - CNTSTREl
C = 1.0 + CNTSTRBB * DE
dUdL = CNTSTRFl + CNTSTRAA * ( 1.0d+00 - 1.0d+00 / C )
U = CNTSTRUl + CNTSTRAAA * DE - CNTSTRBBB * dlog ( C )
end if
CNTSTRNH1Calc = CNTPOT_STRETCHING
U = L0 * R0 * U
dUdL = R0 * dUdL
end function CNTSTRNH1Calc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Stretching with fracture, non-harmonic potential of type 1
!
integer(c_int) function CNTSTRNH1FCalc ( U, dUdL, L, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdL
real(c_double), intent(in) :: L, R0, L0
real(c_double) :: E, C, DE, t
!-------------------------------------------------------------------------------------------
E = ( L - L0 ) / L0
if ( E < CNTSTREl ) then
dUdL = CNTSTRF0 * E
U = 0.5d+00 * E * dUdL
CNTSTRNH1FCalc = CNTPOT_STRETCHING
else if ( E < CNTSTREf ) then
DE = E - CNTSTREl
C = 1.0 + CNTSTRBB * DE
dUdL = CNTSTRFl + CNTSTRAA * ( 1.0d+00 - 1.0d+00 / C )
U = CNTSTRUl + CNTSTRAAA * DE - CNTSTRBBB * dlog ( C )
CNTSTRNH1FCalc = CNTPOT_STRETCHING
else
dUdL = 0.0d+00
U = 0.0d+00
CNTSTRNH1FCalc = CNTPOT_SFRACTURE
end if
U = L0 * R0 * U
dUdL = R0 * dUdL
end function CNTSTRNH1FCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CNTSTRNH1Init () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) :: S, C, E, t
integer(c_int) :: i, CaseID
!-------------------------------------------------------------------------------------------
S = M_2PI * CNTSTRD0 * 1.0e-20 / K_MDFU
CNTSTRSl = CNTSTRS0 * CNTSTREl
CNTSTRF0 = CNTSTRS0 * S
CNTSTRFl = CNTSTRSl * S
CNTSTRFf = CNTSTRSf * S
CNTSTRAA = ( CNTSTRFf - CNTSTRFl ) * ( CNTSTREf * CNTSTRF0 - CNTSTRFl ) / ( CNTSTREf * CNTSTRF0 - CNTSTRFf )
CNTSTRBB = CNTSTRF0 / CNTSTRAA
CNTSTRAAA= CNTSTRFl + CNTSTRAA
CNTSTRBBB= CNTSTRAA / CNTSTRBB
CNTSTRSi = CNTSTRSl + CNTSTRAA / S
C = 1.0 + CNTSTRBB * ( CNTSTREf - CNTSTREl )
CNTSTRDf = CNTSTRF0 / C / C
CNTSTRUl = 0.5d+00 * CNTSTRFl * CNTSTREl
CNTSTRUf = CNTSTRUl + ( CNTSTRFl + CNTSTRAA ) * ( CNTSTREf - CNTSTREl ) - CNTSTRAA * dlog ( C ) / CNTSTRBB
end subroutine CNTSTRNH1Init !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! General
!
integer(c_int) function CNTSTRCalc ( U, dUdL, L, R0, L0 , ABF, Ebuc ) !!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdL, Ebuc
real(c_double), intent(in) :: L, R0, L0
integer(c_int), intent(in) :: ABF
!-------------------------------------------------------------------------------------------
Ebuc = 0.0d+00
select case ( CNTSTRModel )
case ( CNTSTRMODEL_H0 )
CNTSTRCalc = CNTSTRH0Calc ( U, dUdL, L, R0, L0 )
case ( CNTSTRMODEL_H1 )
CNTSTRCalc = CNTSTRH1Calc ( U, dUdL, L, R0, L0 )
case ( CNTSTRMODEL_NH0F )
CNTSTRCalc = CNTSTRNH0FCalc ( U, dUdL, L, R0, L0 )
case ( CNTSTRMODEL_NH1 )
CNTSTRCalc = CNTSTRNH1Calc ( U, dUdL, L, R0, L0 )
case ( CNTSTRMODEL_NH1F )
CNTSTRCalc = CNTSTRNH1FCalc ( U, dUdL, L, R0, L0 )
case ( CNTSTRMODEL_H1B )
CNTSTRCalc = CNTSTRH1BCalc ( U, dUdL, L, R0, L0 )
case ( CNTSTRMODEL_H1BH )
CNTSTRCalc = CNTSTRH1BHCalc ( U, dUdL, L, R0, L0, ABF, Ebuc )
end select
end function CNTSTRCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CNTSTRInit ( STRModel, STRParams, YMType, Rref ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int), intent(in) :: STRModel, STRParams, YMType
real(c_double), intent(in) :: Rref
!-------------------------------------------------------------------------------------------
CNTSTRModel = STRModel
CNTSTRParams = STRParams
CNTSTRYMT = YMType
if ( STRModel .ne. CNTSTRMODEL_H1 ) then
call CNTSTRSetParameterization ( STRParams )
if ( YMType == 2 ) then
call CNTSTRSetParameterization ( 4 )
else if ( YMType == 1 ) then
CNTSTRR0 = Rref
call CNTSTRSetParameterization ( 3 )
end if
if ( STRModel == CNTSTRMODEL_NH0F ) then
call CNTSTRNH0Init ()
else
call CNTSTRNH1Init ()
end if
end if
end subroutine CNTSTRInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Bending potentials
!---------------------------------------------------------------------------------------------------
subroutine BendingGradients ( K, G0, G1, G2, R0, R1, R2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(inout) :: K
real(c_double), dimension(0:2), intent(inout) :: G0, G1, G2
real(c_double), dimension(0:2), intent(in) :: R0, R1, R2
real(c_double), dimension(0:2) :: DR0, DR2
real(c_double) :: L0, L2
!-------------------------------------------------------------------------------------------
DR0 = R0 - R1
DR2 = R2 - R1
L0 = S_V3norm3 ( DR0 )
L2 = S_V3norm3 ( DR2 )
DR0 = DR0 / L0
DR2 = DR2 / L2
K = S_V3xV3 ( DR0, DR2 )
G0 = DR2 - K * DR0
G2 = DR0 - K * DR2
G0 = G0 / L0
G2 = G2 / L2
G1 = - ( G0 + G2 )
end subroutine BendingGradients !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function CNTBNDHCalc ( U, dUdC, C, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Bending model of type 0:Harmonic bending potential.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: U, dUdC
real(c_double), intent(in) :: C, R0, L0
real(c_double) :: E, K
!-------------------------------------------------------------------------------------------
E = 1.0d+00 - C
K = 2.0d+00 * ( 63.8d+00 * R0**2.93d+00 ) / L0
U = K * ( 1.0d+00 + C ) / E
dUdC = 2.0d+00 * K / ( E * E )
CNTBNDHCalc = CNTPOT_BENDING
end function CNTBNDHCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function CNTBNDHBCalc ( U, dUdC, C, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Bending model of type 1: Harmonic bending potential with buckling.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: U, dUdC
real(c_double), intent(in) :: C, R0, L0
real(c_double) :: E1, E2, C2, Kbnd, Kbcl, Theta, DUbcl
!-------------------------------------------------------------------------------------------
E1 = 1.0d+00 - C
E2 = 1.0d+00 + C
! Calculate the square of curvature
C2 = 4.0d+00 * E2 / ( L0 * L0 * E1 )
! Check the condition for buckling
if ( C2 .ge. CNTBNDC2 ) then ! Buckling takes place
Theta= M_PI - acos ( C )
Kbnd = 63.8d+00 * R0**2.93d+00
Kbcl = CNTBNDB * Kbnd / CNTBNDR
DUbcl= Kbnd * ( CNTBNDB * ( M_PI - 2.0d+00 * atan ( 2.0 * CNTBNDR / L0 ) ) - 0.5d+00 * L0 / CNTBNDR ) &
/ CNTBNDR
U = Kbcl * abs( Theta )**CNTBNDN - DUbcl
dUdC = Kbcl * CNTBNDN * abs( Theta )**CNTBNDN1 / sqrt ( 1.0d+00 - C * C )
CNTBNDHBCalc = CNTPOT_BBUCKLING
else ! Harmonic bending
Kbnd = 2.0d+00 * ( 63.8d+00 * R0**2.93d+00 ) / L0
U = Kbnd * E2 / E1
dUdC = 2.0d+00 * Kbnd / ( E1 * E1 )
CNTBNDHBCalc = CNTPOT_BENDING
end if
end function CNTBNDHBCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function CNTBNDHBFCalc ( U, dUdC, C, R0, L0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdC
real(c_double), intent(in) :: C, R0, L0
real(c_double) :: E1, E2, C2, Kbnd, Kbcl, Theta, DUbcl
!-------------------------------------------------------------------------------------------
E1 = 1.0d+00 - C
E2 = 1.0d+00 + C
! Calculate the square of curvature
C2 = 4.0d+00 * E2 / ( L0 * L0 * E1 )
! Check the condition for buckling
if ( C2 .ge. CNTBNDC2 ) then ! Buckling takes place
Theta= M_PI - acos ( C )
if ( Theta > CNTBNDTF ) then ! Fracture takes place
U = 0.0d+00
dUdC = 0.0d+00
CNTBNDHBFCalc = CNTPOT_BFRACTURE
else
Kbnd = 63.8d+00 * R0**2.93d+00
Kbcl = CNTBNDB * Kbnd / CNTBNDR
DUbcl= Kbnd * ( CNTBNDB * ( M_PI - 2.0d+00 * atan ( 2.0 * CNTBNDR / L0 ) ) - &
0.5d+00 * L0 / CNTBNDR ) / CNTBNDR
U = Kbcl * abs ( Theta )**CNTBNDN - DUbcl
dUdC = Kbcl * CNTBNDN * abs ( Theta )**CNTBNDN1 / sqrt ( 1.0d+00 - C * C )
CNTBNDHBFCalc = CNTPOT_BBUCKLING
end if
else ! Harmonic bending
Kbnd = 2.0d+00 * ( 63.8d+00 * R0**2.93d+00 ) / L0
U = Kbnd * E2 / E1
dUdC = 2.0d+00 * Kbnd / ( E1 * E1 )
CNTBNDHBFCalc = CNTPOT_BENDING
end if
end function CNTBNDHBFCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function CNTBNDHBHCalc ( U, dUdC, C, R0, L0, BBF, Ebuc ) !!!!!!!!!!!!!!!!!!!!
! Bending model of type 1: Harmonic bending potential with buckling with hysteresis approach.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: U, dUdC, Ebuc
real(c_double), intent(in) :: C , R0, L0
integer(c_int), intent(in) :: BBF
real(c_double) :: E1, E2, C2, Kbnd, Kbcl,Theta,DUbcl, Ubcl, Cmin,Rmax
!-------------------------------------------------------------------------------------------
Rmax = 340.0d+00
Cmin = 1.0/(Rmax*Rmax)
E1 = 1.0d+00 - C
E2 = 1.0d+00 + C
! Calculate the square of curvature
C2 = 4.0d+00 * E2 / ( L0 * L0 * E1 )
Theta = M_PI - acos ( C )
if ( C2 .lt. Cmin ) then ! Harmonic bending
Kbnd = 2.0d+00 * ( 63.8d+00 * R0**2.93d+00 ) / L0
U = Kbnd * E2 / E1
dUdC = 2.0d+00 * Kbnd / ( E1 * E1 )
CNTBNDHBHCalc = CNTPOT_BENDING
Ebuc = 0.0
else if ( C2 .ge. Cmin .and. C2 .lt. CNTBNDC2 ) then ! Potential depends on buckling flag of a node
if ( BBF .eq. 0 ) then ! Not buckled yet. Continue harmonic bending
Kbnd = 2.0d+00 * ( 63.8d+00 * R0**2.93d+00 ) / L0
U = Kbnd * E2 / E1
dUdC = 2.0d+00 * Kbnd / ( E1 * E1 )
CNTBNDHBHCalc = CNTPOT_BENDING
Ebuc = 0.0d+00
else ! Already has been buckled or is buckled. Use buckling potential until Cmin.
Theta= M_PI - acos ( C )
Kbnd = 63.8d+00 * R0**2.93d+00
Kbcl = CNTBNDB * Kbnd / CNTBNDR
DUbcl= 2.0d+00*Kbnd * &
(1.0d+00+cos(l0/Rmax+M_PI))/(1.0d+00-cos(l0/Rmax+M_PI))/L0-Kbcl*abs(l0/Rmax)**CNTBNDN
U = Kbcl * abs( Theta )**CNTBNDN + DUbcl
dUdC = Kbcl * CNTBNDN * abs( Theta )**CNTBNDN1 / sqrt ( 1.0d+00 - C * C )
Ebuc = 0.0d+00
CNTBNDHBHCalc = CNTPOT_BBUCKLING
end if
else ! Greater than buckling critical point
if ( BBF .eq. 1 ) then ! Already buckled
Theta= M_PI - acos ( C )
Kbnd = 63.8d+00 * R0**2.93d+00
Kbcl = CNTBNDB * Kbnd / CNTBNDR
DUbcl= 2.0d+00*Kbnd * &
(1.0d+00+cos(l0/Rmax+M_PI))/(1.0d+00-cos(l0/Rmax+M_PI))/L0-Kbcl*abs(l0/Rmax)**CNTBNDN
U = Kbcl * abs( Theta )**CNTBNDN + DUbcl
dUdC = Kbcl * CNTBNDN * abs( Theta )**CNTBNDN1 / sqrt ( 1.0d+00 - C * C )
Ebuc = 0.0d00
CNTBNDHBHCalc = CNTPOT_BBUCKLING
else ! Newly buckled
Theta= M_PI - acos ( C )
Kbnd = 63.8d+00 * R0**2.93d+00
Kbcl = CNTBNDB * Kbnd / CNTBNDR
DUbcl= 2.0d+00*Kbnd * &
(1.0d+00+cos(l0/Rmax+M_PI))/(1.0d+00-cos(l0/Rmax+M_PI))/L0-Kbcl*abs(l0/Rmax)**CNTBNDN
U = Kbcl * abs( Theta )**CNTBNDN + DUbcl
dUdC = Kbcl * CNTBNDN * abs( Theta )**CNTBNDN1 / sqrt ( 1.0d+00 - C * C )
Ebuc = 2.0d+00*Kbnd * (1.0d+00+cos(l0/CNTBNDR+M_PI)) / (1.0d+00-cos(l0/CNTBNDR+M_PI))/L0 &
- Kbcl * abs ( l0 / CNTBNDR ) ** CNTBNDN - dUbcl
CNTBNDHBHCalc = CNTPOT_BBUCKLING
end if
end if
end function CNTBNDHBHCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! General
!
integer(c_int) function CNTBNDCalc ( U, dUdC, C, R0, L0, BBF, Ebuc ) !!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdC, Ebuc
real(c_double), intent(in) :: C, R0, L0
integer(c_int), intent(in) :: BBF
!-------------------------------------------------------------------------------------------
Ebuc = 0.0d+00
select case ( CNTBNDModel )
case ( CNTBNDMODEL_H )
CNTBNDCalc = CNTBNDHCalc ( U, dUdC, C, R0, L0 )
case ( CNTBNDMODEL_HB )
CNTBNDCalc = CNTBNDHBCalc ( U, dUdC, C, R0, L0 )
case ( CNTBNDMODEL_HBF )
CNTBNDCalc = CNTBNDHBFCalc ( U, dUdC, C, R0, L0 )
case ( CNTBNDMODEL_HBH )
CNTBNDCalc = CNTBNDHBHCalc ( U, dUdC, C, R0, L0, BBF, Ebuc )
end select
end function CNTBNDCalc !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CNTBNDInit ( BNDModel ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int), intent(in) :: BNDModel
real(c_double) :: A, E
integer(c_int) :: i
!-------------------------------------------------------------------------------------------
CNTBNDModel= BNDModel
CNTBNDN1 = CNTBNDN - 1.0d+00
CNTBNDC2 = 1.0d+00 / ( CNTBNDR * CNTBNDR )
end subroutine CNTBNDInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Module initialization
!---------------------------------------------------------------------------------------------------
subroutine InitCNTPotModule ( STRModel, STRParams, YMType, BNDModel, Rref ) !!!!!!!!!!!!!!!!
integer(c_int), intent(in) :: STRModel, STRParams, YMType, BNDModel
real(c_double), intent(in) :: Rref
!-------------------------------------------------------------------------------------------
call CNTSTRInit ( STRModel, STRParams, YMType, Rref )
call CNTBNDInit ( BNDModel )
end subroutine InitCNTPotModule !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module CNTPot !*********************************************************************************

150
lib/mesont/ExportCNT.f90 Normal file
View File

@ -0,0 +1,150 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
!-------------------------------------------------------------------------
module ExportCNT !**********************************************************************************
use iso_c_binding
use CNTPot
use TPMLib
use TubePotMono
use TPMForceField
implicit none
contains
subroutine InitCNTPotModule_(STRModel, STRParams, YMType, BNDModel, Rref) &
bind(c, name = "mesont_lib_InitCNTPotModule")
integer(c_int), intent(in) :: STRModel, STRParams, YMType, BNDModel
real(c_double), intent(in) :: Rref
call InitCNTPotModule(STRModel, STRParams, YMType, BNDModel, Rref)
endsubroutine
subroutine TPBInit_() &
bind(c, name = "mesont_lib_TPBInit")
call TPBInit()
endsubroutine
subroutine TPMInit_(M, N) &
bind(c, name = "mesont_lib_TPMInit")
integer(c_int), intent(in) :: M, N
call TPMInit(M, N)
endsubroutine
subroutine SetTablePath_(TPMFile_, N) &
bind(c, name = "mesont_lib_SetTablePath")
integer(c_int), intent(in) :: N
character(c_char), intent(in), dimension(N) :: TPMFile_
integer :: i
do i = 1, len(TPMFile)
if (i <= N) then
TPMFile(i:i) = TPMFile_(i)
else
TPMFile(i:i) = ' '
endif
enddo
endsubroutine
function get_R_ () &
bind(c, name = "mesont_lib_get_R")
real(c_double) :: get_R_
get_R_ = TPMR1
return
endfunction
subroutine TubeStretchingForceField_(U1, U2, F1, F2, S1, S2, X1, X2, R12, L12) &
bind(c, name = "mesont_lib_TubeStretchingForceField")
! Interaction energies associated with nodes X1 and X2
real(c_double), intent(inout) :: U1, U2
! Forces exerted on nodes X1 and X2
real(c_double), intent(inout), dimension(0:2) :: F1, F2
! Contributions of nodes X1 and X2 to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2) :: S1, S2
! Coordinates of the segment nodes
real(c_double), intent(in), dimension(0:2) :: X1, X2
! Radius of a nanotube the segment (X1,X2) belongs to
real(c_double), intent(in) :: R12
! Equilibrium length of segment (X1,X2)
real(c_double), intent(in) :: L12
call TubeStretchingForceField(U1, U2, F1, F2, S1, S2, X1, X2, R12, L12)
endsubroutine
subroutine TubeBendingForceField_(U1, U2, U3, F1, F2, F3, S1, S2, S3, X1, X2, X3, R123, L123, BBF2) &
bind(c, name = "mesont_lib_TubeBendingForceField")
! Interaction energies associated with nodes X1, X2, and X3
real(c_double), intent(inout) :: U1, U2, U3
! Forces exerted on nodes X1, X2, and X3
real(c_double), intent(inout), dimension(0:2) :: F1, F2, F3
! Contributions of nodes X1, X2, and X3 to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2) :: S1, S2, S3
! Coordinates of nodes
real(c_double), intent(in), dimension(0:2) :: X1, X2, X3
! Radius of nanotube the segment (X1,X2) belongs to
real(c_double), intent(in) :: R123
! Equilibrium length of segment (X1,X2) and (X2,X3) (It is assumed to be the same for both segments)
real(c_double), intent(in) :: L123
integer(c_int), intent(inout) :: BBF2
call TubeBendingForceField(U1, U2, U3, F1, F2, F3, S1, S2, S3, X1, X2, X3, R123, L123, BBF2 )
endsubroutine
subroutine SegmentTubeForceField_(U1,U2,U,F1,F2,F,Fe,S1,S2,S,Se,X1,X2,R12,N,X,Xe,BBF,R,E1,E2,Ee,TPMType)&
bind(c, name = "mesont_lib_SegmentTubeForceField")
! Number of nodes in array X
integer(c_int), intent(in) :: N
! Interaction energies associated with nodes X1 and X2
real(c_double), intent(inout) :: U1, U2
! Interaction energies associated with nodes X
real(c_double), intent(inout), dimension(0:N-1) :: U
! Forces exerted on nodes X1 and X2
real(c_double), intent(inout), dimension(0:2) :: F1, F2
! Forces exerted on nodes X
real(c_double), intent(inout), dimension(0:2,0:N-1) :: F
! Force exerted on node Xe (can be updated only if Ee > 0)
real(c_double), intent(inout), dimension(0:2) :: Fe
! Contributions of nodes X1 and X2 to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2) :: S1, S2
! Contributions of nodes X to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2,0:N-1) :: S
! Contributions of node Xe to the virial stress tensor (can be updated only if Ee > 0)
real(c_double), intent(inout), dimension(0:2,0:2) :: Se
! Coordinates of the segment nodes
real(c_double), intent(in), dimension(0:2) :: X1, X2
! Radius of nanotube the segment (X1,X2) belongs to
real(c_double), intent(in) :: R12
! Coordinates of the nanotube nodes
real(c_double), intent(in), dimension(0:2,0:N-1) :: X
! Additional node of the extended chain if Ee > 0
real(c_double), intent(in), dimension(0:2) :: Xe
! Bending buckling flags (BBF(i) = 1 in a case of buckling in node i)
integer(c_int), intent(in), dimension(0:N-1) :: BBF
! Radius of nanotube X
real(c_double), intent(in) :: R
! E1 = 1 if the chain node 0 is a CNT end; E2 = 1 if the chain node N-1 is a CNT end;
integer(c_int), intent(in) :: E1, E2
! Parameter defining the type of the extended chain (0,1,2)
integer(c_int), intent(in) :: Ee
! Type of the tubular potential (0 or 1)
integer(c_int), intent(in) :: TPMType
call SegmentTubeForceField(U1, U2, U, F1, F2, F, Fe, S1, S2, S, Se, X1, X2, R12, N, X, Xe, BBF, R, E1, E2, Ee, TPMType)
endsubroutine
endmodule ExportCNT !*******************************************************************************

97
lib/mesont/Install.py Normal file
View File

@ -0,0 +1,97 @@
#!/usr/bin/env python
"""
Install.py tool to do a generic build of a library
soft linked to by many of the lib/Install.py files
used to automate the steps described in the corresponding lib/README
"""
from __future__ import print_function
import sys, os, subprocess
from argparse import ArgumentParser
sys.path.append('..')
from install_helpers import get_cpus, fullpath
parser = ArgumentParser(prog='Install.py',
description="LAMMPS library build wrapper script")
HELP = """
Syntax from src dir: make lib-libname args="-m machine -e suffix"
Syntax from lib dir: python Install.py -m machine -e suffix
libname = name of lib dir (e.g. atc, h5md, meam, poems, etc)
specify -m and optionally -e, order does not matter
Examples:
make lib-poems args="-m serial" # build POEMS lib with same settings as in the serial Makefile in src
make lib-colvars args="-m mpi" # build USER-COLVARS lib with same settings as in the mpi Makefile in src
make lib-meam args="-m ifort" # build MEAM lib with custom Makefile.ifort (using Intel Fortran)
"""
# parse and process arguments
parser.add_argument("-m", "--machine",
help="suffix of a <libname>/Makefile.* file used for compiling this library")
parser.add_argument("-e", "--extramake",
help="set EXTRAMAKE variable in <libname>/Makefile.<machine> to Makefile.lammps.<extramake>")
args = parser.parse_args()
# print help message and exit, if neither build nor path options are given
if not args.machine and not args.extramake:
parser.print_help()
sys.exit(HELP)
machine = args.machine
extraflag = args.extramake
if extraflag:
suffix = args.extramake
else:
suffix = 'empty'
# set lib from working dir
cwd = fullpath('.')
lib = os.path.basename(cwd)
# create Makefile.auto as copy of Makefile.machine
# reset EXTRAMAKE if requested
if not os.path.exists("Makefile.%s" % machine):
sys.exit("lib/%s/Makefile.%s does not exist" % (lib, machine))
lines = open("Makefile.%s" % machine, 'r').readlines()
fp = open("Makefile.auto", 'w')
has_extramake = False
for line in lines:
words = line.split()
if len(words) == 3 and words[0] == "EXTRAMAKE" and words[1] == '=':
has_extramake = True
if extraflag:
line = line.replace(words[2], "Makefile.lammps.%s" % suffix)
fp.write(line)
fp.close()
# make the library via Makefile.auto optionally with parallel make
n_cpus = get_cpus()
print("Building lib%s.a ..." % lib)
cmd = "make -f Makefile.auto clean; make -f Makefile.auto -j%d" % n_cpus
try:
txt = subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
print(txt.decode('UTF-8'))
except subprocess.CalledProcessError as e:
print("Make failed with:\n %s" % e.output.decode('UTF-8'))
sys.exit(1)
if os.path.exists("lib%s.a" % lib):
print("Build was successful")
else:
sys.exit("Build of lib/%s/lib%s.a was NOT successful" % (lib, lib))
if has_extramake and not os.path.exists("Makefile.lammps"):
print("WARNING: lib/%s/Makefile.lammps was NOT created" % lib)

113
lib/mesont/LinFun2.f90 Normal file
View File

@ -0,0 +1,113 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module LinFun2 !************************************************************************************
!
! Bi-linear functions and their derivatives.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use iso_c_binding, only : c_int, c_double, c_char
implicit none
contains !******************************************************************************************
real(c_double) function CalcLinFun1_0 ( i, X, N, P, F ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int), intent(in) :: i, N
real(c_double), intent(in) :: X
real(c_double), dimension(0:N-1), intent(in) :: P
real(c_double), dimension(0:N-1), intent(inout) :: F
integer(c_int) :: i1
real(c_double) :: A, A0
!-------------------------------------------------------------------------------------------
i1 = i - 1
A0 = ( P(i) - X ) / ( P(i) - P(i1) )
A = 1.0d+00 - A0
CalcLinFun1_0 = A0 * F(i1) + A * F(i)
end function CalcLinFun1_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcLinFun1_1 ( S, Sx1, i, X, N, P, F, Fx ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: S, Sx1
integer(c_int), intent(in) :: i, N
real(c_double), intent(in) :: X
real(c_double), dimension(0:N-1), intent(in) :: P
real(c_double), dimension(0:N-1), intent(inout) :: F, Fx
integer(c_int) :: i1
real(c_double) :: A, A0
!-------------------------------------------------------------------------------------------
i1 = i - 1
A0 = ( P(i) - X ) / ( P(i) - P(i1) )
A = 1.0d+00 - A0
S = A0 * F(i1) + A * F(i)
Sx1 = A0 * Fx(i1) + A * Fx(i)
end subroutine CalcLinFun1_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function CalcLinFun2_0 ( i, j, X, Y, N1, N2, P1, P2, F ) !!
integer(c_int), intent(in) :: i, j, N1, N2
real(c_double), intent(in) :: X, Y
real(c_double), dimension(0:N1-1), intent(in) :: P1
real(c_double), dimension(0:N2-1), intent(in) :: P2
real(c_double), dimension(0:N1-1,0:N2-1), intent(inout) :: F
integer(c_int) :: i1, j1
real(c_double) :: A, A0, B, B0, G, G0
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
A0 = ( P1(i) - X ) / ( P1(i) - P1(i1) )
A = 1.0d+00 - A0
B0 = ( P2(j) - Y ) / ( P2(j) - P2(j1) )
B = 1.0d+00 - B0
G = B0 * F(i,j1) + B * F(i,j)
G0 = B0 * F(i1,j1) + B * F(i1,j)
CalcLinFun2_0 = A0 * G0 + A * G
end function CalcLinFun2_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcLinFun2_1 ( S, Sx1, Sy1, i, j, X, Y, N1, N2, P1, P2, F, Fx, Fy ) !!!!!!!!!!!!
real(c_double), intent(out) :: S, Sx1, Sy1
integer(c_int), intent(in) :: i, j, N1, N2
real(c_double), intent(in) :: X, Y
real(c_double), dimension(0:N1-1), intent(in) :: P1
real(c_double), dimension(0:N2-1), intent(in) :: P2
real(c_double), dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fx, Fy
integer(c_int) :: i1, j1
real(c_double) :: A, A0, B, B0, G, G0
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
A0 = ( P1(i) - X ) / ( P1(i) - P1(i1) )
A = 1.0d+00 - A0
B0 = ( P2(j) - Y ) / ( P2(j) - P2(j1) )
B = 1.0d+00 - B0
G = B0 * F(i,j1) + B * F(i,j)
G0 = B0 * F(i1,j1) + B * F(i1,j)
S = A0 * G0 + A * G
G = B0 * Fx(i,j1) + B * Fx(i,j)
G0 = B0 * Fx(i1,j1) + B * Fx(i1,j)
Sx1 = A0 * G0 + A * G
G = B0 * Fy(i,j1) + B * Fy(i,j)
G0 = B0 * Fy(i1,j1) + B * Fy(i1,j)
Sy1 = A0 * G0 + A * G
end subroutine CalcLinFun2_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module LinFun2 !********************************************************************************

View File

@ -0,0 +1,46 @@
SHELL = /bin/sh
# which file will be copied to Makefile.lammps
EXTRAMAKE = Makefile.lammps.gfortran
# ------ FILES ------
SRC = LinFun2.f90 Spline1.f90 Spline2.f90 TPMLib.f90 TPMGeom.f90 TubePotBase.f90 TubePotTrue.f90 \
TubePotMono.f90 TPMM0.f90 TPMM1.f90 CNTPot.f90 TPMForceField.f90 ExportCNT.f90
FILES = $(SRC) Makefile
# ------ DEFINITIONS ------
LIB = libmesont.a
OBJ = $(SRC:.f90=.o)
# ------ SETTINGS ------
F90 = gfortran
F90FLAGS = -O3 -fPIC -ftree-vectorize -g
ARCHIVE = ar
ARCHFLAG = -rc
USRLIB =
SYSLIB =
# ------ MAKE PROCEDURE ------
lib: $(OBJ)
$(ARCHIVE) $(ARFLAGS) $(LIB) $(OBJ)
@cp $(EXTRAMAKE) Makefile.lammps
# ------ COMPILE RULES ------
%.o:%.f90
$(F90) $(F90FLAGS) -c $<
include .depend
# ------ CLEAN ------
clean:
-rm *.o *.mod $(LIB)
tar:
-tar -cvf ../MESONT.tar $(FILES)

46
lib/mesont/Makefile.ifort Normal file
View File

@ -0,0 +1,46 @@
SHELL = /bin/sh
# which file will be copied to Makefile.lammps
EXTRAMAKE = Makefile.lammps.ifort
# ------ FILES ------
SRC = LinFun2.f90 Spline1.f90 Spline2.f90 TPMLib.f90 TPMGeom.f90 TubePotBase.f90 TubePotTrue.f90 \
TubePotMono.f90 TPMM0.f90 TPMM1.f90 CNTPot.f90 TPMForceField.f90 ExportCNT.f90
FILES = $(SRC) Makefile
# ------ DEFINITIONS ------
LIB = libmesont.a
OBJ = $(SRC:.f90=.o)
# ------ SETTINGS ------
F90 = ifort
F90FLAGS = -O3 -fPIC -g
ARCHIVE = ar
ARCHFLAG = -rc
USRLIB =
SYSLIB =
# ------ MAKE PROCEDURE ------
lib: $(OBJ)
$(ARCHIVE) $(ARFLAGS) $(LIB) $(OBJ)
@cp $(EXTRAMAKE) Makefile.lammps
# ------ COMPILE RULES ------
%.o:%.f90
$(F90) $(F90FLAGS) -c $<
include .depend
# ------ CLEAN ------
clean:
-rm *.o *.mod $(LIB)
tar:
-tar -cvf ../MESONT.tar $(FILES)

View File

@ -0,0 +1,5 @@
# Settings that the LAMMPS build will import when this package library is used
mesont_SYSINC =
mesont_SYSLIB = -lgfortran
mesont_SYSPATH =

View File

@ -0,0 +1,5 @@
# Settings that the LAMMPS build will import when this package library is used
mesont_SYSINC =
mesont_SYSLIB = -lifcore -lsvml -limf -ldl -lstdc++
mesont_SYSPATH =

1
lib/mesont/Makefile.serial Symbolic link
View File

@ -0,0 +1 @@
Makefile.gfortran

67
lib/mesont/README Normal file
View File

@ -0,0 +1,67 @@
USER-MESONT is a LAMMPS package for simulation of nanomechanics of carbon
nanotubes (CNTs). The model is based on a coarse-grained representation
of CNTs as "flexible cylinders" consisting of a variable number of
segments. Internal interactions within a CNT and the van der Waals
interaction between the tubes are described by a mesoscopic force
field designed and parameterized based on the results of atomic-level
molecular dynamics simulations. The description of the force field
is provided in the papers listed below.
This folder contains a Fortran library implementing basic level functions
describing stretching, bending, and intertube components of the CNT tubular
potential model (TPM) mesoscopic force field.
This library was created by Alexey N. Volkov, University of Alabama,
avolkov1@ua.edu.
--
References:
L. V. Zhigilei, C. Wei, and D. Srivastava, Mesoscopic model for dynamic
simulations of carbon nanotubes, Phys. Rev. B 71, 165417, 2005.
A. N. Volkov and L. V. Zhigilei, Structural stability of carbon nanotube
films: The role of bending buckling, ACS Nano 4, 6187-6195, 2010.
A. N. Volkov, K. R. Simov, and L. V. Zhigilei, Mesoscopic model for simulation
of CNT-based materials, Proceedings of the ASME International Mechanical
Engineering Congress and Exposition (IMECE2008), ASME paper IMECE2008-68021,
2008.
A. N. Volkov and L. V. Zhigilei, Mesoscopic interaction potential for carbon
nanotubes of arbitrary length and orientation, J. Phys. Chem. C 114, 5513-5531,
2010.
B. K. Wittmaack, A. H. Banna, A. N. Volkov, L. V. Zhigilei, Mesoscopic
modeling of structural self-organization of carbon nanotubes into vertically
aligned networks of nanotube bundles, Carbon 130, 69-86, 2018.
B. K. Wittmaack, A. N. Volkov, L. V. Zhigilei, Mesoscopic modeling of the
uniaxial compression and recovery of vertically aligned carbon nanotube
forests, Compos. Sci. Technol. 166, 66-85, 2018.
B. K. Wittmaack, A. N. Volkov, L. V. Zhigilei, Phase transformation as the
mechanism of mechanical deformation of vertically aligned carbon nanotube
arrays: Insights from mesoscopic modeling, Carbon 143, 587-597, 2019.
A. N. Volkov and L. V. Zhigilei, Scaling laws and mesoscopic modeling of
thermal conductivity in carbon nanotube materials, Phys. Rev. Lett. 104,
215902, 2010.
A. N. Volkov, T. Shiga, D. Nicholson, J. Shiomi, and L. V. Zhigilei, Effect
of bending buckling of carbon nanotubes on thermal conductivity of carbon
nanotube materials, J. Appl. Phys. 111, 053501, 2012.
A. N. Volkov and L. V. Zhigilei, Heat conduction in carbon nanotube materials:
Strong effect of intrinsic thermal conductivity of carbon nanotubes, Appl.
Phys. Lett. 101, 043113, 2012.
W. M. Jacobs, D. A. Nicholson, H. Zemer, A. N. Volkov, and L. V. Zhigilei,
Acoustic energy dissipation and thermalization in carbon nanotubes: Atomistic
modeling and mesoscopic description, Phys. Rev. B 86, 165414, 2012.
A. N. Volkov and A. H. Banna, Mesoscopic computational model of covalent
cross-links and mechanisms of load transfer in cross-linked carbon nanotube
films with continuous networks of bundles, Comp. Mater. Sci. 176, 109410, 2020.

191
lib/mesont/Spline1.f90 Normal file
View File

@ -0,0 +1,191 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module Spline1 !************************************************************************************
!
! One-dimensional cubic spline function.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use iso_c_binding, only : c_int, c_double, c_char
implicit none
contains !******************************************************************************************
real(c_double) function ValueSpline1_0 ( X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1 ) !!!!!!!!!!!!
real(c_double), intent(in) :: X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1
real(c_double) :: H26, HL, HR
!-------------------------------------------------------------------------------------------
H26 = Hi_1 * Hi_1 / 6.0
Hl = X - Xi_1
Hr = Xi - X
ValueSpline1_0 = ( ( Mi_1 * Hr * Hr * Hr + Mi * Hl * Hl * Hl ) / 6.0 + ( Yi_1 - Mi_1 * H26 ) * Hr &
+ ( Yi - Mi * H26 ) * Hl ) / Hi_1
end function ValueSpline1_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine ValueSpline1_1 ( S, S1, X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1 ) !!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: S, S1
real(c_double), intent(in) :: X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1
real(c_double) :: H6, H26, HL, HR, HL2, HR2
!-------------------------------------------------------------------------------------------
H6 = Hi_1 / 6.0d+00
H26 = Hi_1 * H6
HL = X - Xi_1
HR = Xi - X
HL2 = HL * HL
HR2 = HR * HR
S = ( ( Mi_1 * HR2 * Hr + Mi * HL2 * Hl ) / 6.0 + ( Yi_1 - Mi_1 * H26 ) * HR + ( Yi - Mi * H26 ) * HL ) / Hi_1
S1 = ( ( Mi * HL2 - Mi_1 * HR2 ) / 2.0d+00 + Yi - Yi_1 ) / Hi_1 - H6 * ( Mi - Mi_1 )
end subroutine ValueSpline1_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine sprogonka3 ( N, K0, K1, K2, F, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int), intent(in) :: N
real(c_double), dimension(0:N-1), intent(in) :: K0, K1, K2
real(c_double), dimension(0:N-1), intent(inout) :: F, X
real(c_double) :: D
integer(c_int) :: i
!-------------------------------------------------------------------------------------------
X(0) = F(0) / K1(0)
F(0) = - K2(0) / K1(0)
do i = 1, N - 1
D = - ( K1(i) + F(i-1) * K0(i) )
X(i) = ( K0(i) * X(i-1) - F(i) ) / D
F(i) = K2(i) / D
end do
do i = N - 2, 0, -1
X(i) = X(i) + F(i) * X(i+1)
end do
end subroutine sprogonka3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CreateSpline1 ( CL, CR, N, P, F, M, D, K0, K1, K2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int), intent(in) :: CL, CR, N
real(c_double), dimension (0:N-1), intent(in) :: P, F
real(c_double), dimension (0:N-1), intent(inout):: M, D, K0, K1, K2
integer(c_int) :: i
real(c_double) :: Z
!-------------------------------------------------------------------------------------------
do i = 1, N - 1
K0(i) = P(i) - P(i-1)
K1(i) = ( F(i) - F(i-1) ) / K0(i)
end do
select case ( CL )
case (1)
K1(0) = 2.0d+00 / 3.0d+00
K2(0) = 1.0d+00 / 3.0d+00
D (0) = 2 * ( K1(1) - M(0) ) / K0(1)
case (2)
K1(0) = 1.0d+00
K2(0) = 0.0d+00
D(0) = M(0)
case (3)
K1(0) = 1.0d+00
K2(0) = 0.0d+00
D(0) = 0.0d+00
end select
Z = K1(N-1)
do i = 1, N - 2
D(i) = 6.0d+00 * ( K1(i+1) - K1(i) )
K2(i) = K0(i+1)
K1(i) = 2.0d+00 * ( K2(i) + K0(i) )
end do
select case ( CR )
case (1)
D(N-1) = 2.0d+00 * ( M(N-1) - Z ) / K0(N-1)
K1(N-1) = 2.0d+00 / 3.0d+00
K0(N-1) = 1.0d+00 / 3.0d+00
case (2)
K1(N-1) = 1.0d+00
K0(N-1) = 0.0d+00
D(N-1) = M(N-1)
case (3)
K1(N-1) = 1.0d+00
K0(N-1) = 0.0d+00
D(N-1) = 0.0d+00
end select
call sprogonka3 ( N, K0, K1, K2, D, M )
end subroutine CreateSpline1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function CalcSpline1_0 ( i, X, N, P, F, M ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int), intent(in) :: i, N
real(c_double), intent(in) :: X
real(c_double), dimension(0:N-1), intent(in) :: P, F, M
integer(c_int) :: j
real(c_double) :: HL, HR, H, H6, H26, HR2, HL2, HRH, HLH
!-------------------------------------------------------------------------------------------
j = i - 1
HL = X - P(j)
HR = P(i) - X
H = P(i) - P(j)
H6 = H / 6.0d+00
H26 = H * H6
HL2 = HL * HL
HR2 = HR * HR
HLH = HL / H
HRH = HR / H
CalcSpline1_0 = ( M(j) * HR2 * HRH + M(i) * HL2 * HLH ) / 6.0d+00 + ( F(j) - M(j) * H26 ) * HRH &
+ ( F(i) - M(i) * H26 ) * HLH
end function CalcSpline1_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcSpline1_1 ( S, S1, i, X, N, P, F, M ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: S, S1
integer(c_int), intent(in) :: i, N
real(c_double), intent(in) :: X
real(c_double), dimension(0:N-1), intent(in) :: P, F, M
integer(c_int) :: j
real(c_double) :: HL, HR, H, H6, H26, HR2, HL2, HRH, HLH
!-------------------------------------------------------------------------------------------
j = i - 1
HL = X - P(j)
HR = P(i) - X
H = P(i) - P(j)
H6 = H / 6.0d+00
H26 = H * H6
HL2 = HL * HL
HR2 = HR * HR
HLH = HL / H
HRH = HR / H
S = ( M(j) * HR2 * HRH + M(i) * HL2 * HLH ) / 6.0d+00 + ( F(j) - M(j) * H26 ) * HRH + ( F(i) - M(i) * H26 ) * HLH
S1 = ( ( M(i) * HL2 - M(j) * HR2 ) / 2.0d+00 + F(i) - F(j) ) / H - H6 * ( M(i) - M(j) )
end subroutine CalcSpline1_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcSpline1_2 ( S, S1, S2, i, X, N, P, F, M ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: S, S1, S2
integer(c_int), intent(in) :: i, N
real(c_double), intent(in) :: X
real(c_double), dimension(0:N-1), intent(in) :: P, F, M
integer(c_int) :: j
real(c_double) :: HL, HR, H, H6, H26, HR2, HL2, HRH, HLH
!-------------------------------------------------------------------------------------------
j = i - 1
HL = X - P(j)
HR = P(i) - X
H = P(i) - P(j)
H6 = H / 6.0d+00
H26 = H * H6
HL2 = HL * HL
HR2 = HR * HR
HLH = HL / H
HRH = HR / H
S = ( M(j) * HR2 * HRH + M(i) * HL2 * HLH ) / 6.0d+00 + ( F(j) - M(j) * H26 ) * HRH + ( F(i) - M(i) * H26 ) * HLH
S1 = ( ( M(i) * HL2 - M(j) * HR2 ) / 2.0d+00 + F(i) - F(j) ) / H - H6 * ( M(i) - M(j) )
S2 = M(j) * HRH + M(i) * HLH
end subroutine CalcSpline1_2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module Spline1 !********************************************************************************

186
lib/mesont/Spline2.f90 Normal file
View File

@ -0,0 +1,186 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module Spline2 !************************************************************************************
!
! Two-dimensional cubic spline function.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use Spline1
use iso_c_binding, only : c_int, c_double, c_char
implicit none
contains !******************************************************************************************
subroutine CreateSpline2 ( CL, CD, CR, CU, N1, N2, N, P1, P2, F, Fxx, Fyy, Fxxyy, FF, MM, DD, K0, K1, K2 )
integer(c_int), intent(in) :: CL, CD, CR, CU, N1, N2, N
real(c_double), dimension(0:N1-1), intent(in) :: P1
real(c_double), dimension(0:N2-1), intent(in) :: P2
real(c_double), dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
real(c_double), dimension(0:N-1), intent(inout) :: FF, MM, DD, K0, K1, K2
integer(c_int) :: II
!-------------------------------------------------------------------------------------------
do II = 0, N2 - 1
FF(0:N1-1) = F(0:N1-1,II)
MM(0) = Fxx(0,II)
MM(N1-1) = Fxx(N1-1,II)
call CreateSpline1 ( CL, CR, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxx(0:N1-1,II) = MM(0:N1-1)
end do
do II = 0, N1 - 1
MM(0) = Fyy(II,0)
MM(N-1) = Fyy(II,N2-1)
FF(0:N2-1) = F(II,0:N2-1)
call CreateSpline1 ( CD, CU, N2, P2, FF, MM, DD, K0, K1, K2 )
Fyy(II,0:N2-1) = MM(0:N2-1)
end do
FF(0:N1-1) = Fyy(0:N1-1,0 )
call CreateSpline1 ( 3, 3, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(0:N1-1,0) = MM(0:N1-1)
FF(0:N1-1) = Fyy(0:N1-1,N2-1 )
call CreateSpline1 ( 3, 3, N1, P1, FF, MM, DD, K0, K1, k2 )
Fxxyy(0:N1-1,N2-1) = MM(0:N1-1)
do II = 1, N1 - 2
MM(0) = Fxxyy(II,0)
MM(N-1) = Fxxyy(II,N2-1)
FF(0:N2-1) = Fxx(II,0:N2-1)
call CreateSpline1 ( 2 , 2, N2, P2, FF, MM, DD, K0, K1, K2 )
Fxxyy(II,0:N2-1) = MM(0:N2-1)
end do
end subroutine CreateSpline2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CreateSpline2Ext ( CL, CD, CR, CU, N1, N1A, N2, N2A, N, P1, P2, F, Fxx, Fyy, Fxxyy, FF, MM, DD, K0, K1, K2 )
integer(c_int), intent(in) :: CL, CD, CR, CU, N1, N1A, N2, N2A, N
real(c_double), dimension(0:N1-1), intent(in) :: P1
real(c_double), dimension(0:N2-1), intent(in) :: P2
real(c_double), dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
real(c_double), dimension(0:N-1), intent(inout) :: FF, MM, DD, K0, K1, K2
integer(c_int) :: II
!-------------------------------------------------------------------------------------------
Fxx = 0.0d+00
Fyy = 0.0d+00
Fxxyy = 0.0d+00
do II = 0, N2A
FF(0:N1-1) = F(0:N1-1,II)
MM(0) = Fxx(0,II)
MM(N1-1) = Fxx(N1-1,II)
call CreateSpline1 ( CL, CR, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxx(0:N1-1,II) = MM(0:N1-1)
end do
do II = N2A + 1, N2 - 1
FF(0:N1-N1A-1) = F(N1A:N1-1,II)
MM(0) = Fxx(N1A,II)
MM(N1-N1A-1) = Fxx(N1-1,II)
call CreateSpline1 ( CL, CR, N1 - N1A, P1, FF, MM, DD, K0, K1, K2 )
Fxx(N1A:N1-1,II) = MM(0:N1-N1A-1)
end do
do II = 0, N1A - 1
MM(0) = Fyy(II,0)
MM(N2A) = Fyy(II,N2A)
FF(0:N2A) = F(II,0:N2A)
call CreateSpline1 ( CD, CU, N2A + 1, P2, FF, MM, DD, K0, K1, K2 )
Fyy(II,0:N2A) = MM(0:N2A)
end do
do II = N1A, N1 - 1
MM(0) = Fyy(II,0)
MM(N-1) = Fyy(II,N2-1)
FF(0:N2-1) = F(II,0:N2-1)
call CreateSpline1 ( CD, CU, N2, P2, FF, MM, DD, K0, K1, K2 )
Fyy(II,0:N2-1) = MM(0:N2-1)
end do
FF(0:N1-1) = Fyy(0:N1-1,0)
call CreateSpline1 ( 3, 3, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(0:N1-1,0) = MM(0:N1-1)
FF(0:N1A) = Fyy(0:N1A,N2A)
call CreateSpline1 ( 3, 3, N1A + 1, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(0:N1A,N2A) = MM(0:N1A)
FF(0:N1-N1A-1) = Fyy(N1A:N1-1,N2-1 )
call CreateSpline1 ( 3, 3, N1-N1A, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(N1A:N1-1,N2-1) = MM(0:N1-N1A-1)
do II = 1, N1A
MM(0) = Fxxyy(II,0)
MM(N2A) = Fxxyy(II,N2A)
FF(0:N2A) = Fxx(II,0:N2A)
call CreateSpline1 ( 2 , 2, N2A + 1, P2, FF, MM, DD, K0, K1, K2 )
Fxxyy(II,0:N2A) = MM(0:N2A)
end do
do II = N1A + 1, N1 - 2
MM(0) = Fxxyy(II,0)
MM(N-1) = Fxxyy(II,N2-1)
FF(0:N2-1) = Fxx(II,0:N2-1)
call CreateSpline1 ( 2 , 2, N2, P2, FF, MM, DD, K0, K1, K2 )
Fxxyy(II,0:N2-1) = MM(0:N2-1)
end do
end subroutine CreateSpline2Ext !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function CalcSpline2_0 ( i, j, X, Y, N1, N2, P1, P2, F, Fxx, Fyy, Fxxyy ) !!!
integer(c_int), intent(in) :: i, j, N1, N2
real(c_double), intent(in) :: X, Y
real(c_double), dimension(0:N1-1), intent(in) :: P1
real(c_double), dimension(0:N2-1), intent(in) :: P2
real(c_double), dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
integer(c_int) :: i1, j1
real(c_double) :: T, Gy_0, Gy_1, Gxxy_0, Gxxy_1
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
T = P2(j) - P2(j1)
Gy_0 = ValueSpline1_0 ( Y, P2(j), P2(j1), F(i,j), F(i,j1), Fyy(i,j), Fyy(i,j1), T )
Gy_1 = ValueSpline1_0 ( Y, P2(j), P2(j1), F(i1,j), F(i1,j1), Fyy(i1,j), Fyy(i1,j1), T )
Gxxy_0 = ValueSpline1_0 ( Y, P2(j), P2(j1), Fxx(i,j), Fxx(i,j1), Fxxyy(i,j), Fxxyy(i,j1), T )
Gxxy_1 = ValueSpline1_0 ( Y, P2(j), P2(j1), Fxx(i1,j), Fxx(i1,j1), Fxxyy(i1,j), Fxxyy(i1,j1), T )
CalcSpline2_0 = ValueSpline1_0 ( X, P1(i), P1(i1), Gy_0, Gy_1,Gxxy_0, Gxxy_1, P1(i) - P1(i1) )
end function CalcSpline2_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcSpline2_1 ( S, Sx1, Sy1, i, j, X, Y, N1, N2, P1, P2, F, Fxx, Fyy, Fxxyy ) !!!
real(c_double), intent(out) :: S, Sx1, Sy1
integer(c_int), intent(in) :: i, j, N1, N2
real(c_double), intent(in) :: X, Y
real(c_double), dimension(0:N1-1), intent(in) :: P1
real(c_double), dimension(0:N2-1), intent(in) :: P2
real(c_double), dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
integer(c_int) :: i1, j1
real(c_double) :: T, Gy_0, Gy_1, Gxxy_0, Gxxy_1
real(c_double) :: Gyy_0, Gyy_1, Gxxyy_0, Gxxyy_1
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
T = P2(j) - P2(j1)
call ValueSpline1_1 ( Gy_0, Gyy_0, Y, P2(j), P2(j1), F(i,j), F(i,j1), Fyy(i,j), Fyy(i,j1), T )
call ValueSpline1_1 ( Gy_1, Gyy_1, Y, P2(j), P2(j1), F(i1,j), F(i1,j1), Fyy(i1,j), Fyy(i1,j1), T )
call ValueSpline1_1 ( Gxxy_0, Gxxyy_0, Y, P2(j), P2(j1), Fxx(i,j), Fxx(i,j1), Fxxyy(i,j), Fxxyy(i,j1), T )
call ValueSpline1_1 ( Gxxy_1, Gxxyy_1, Y, P2(j), P2(j1), Fxx(i1,j), Fxx(i1,j1), Fxxyy(i1,j), Fxxyy(i1,j1), T )
call ValueSpline1_1 ( S, Sx1, X, P1(i), P1(i1), Gy_0, Gy_1,Gxxy_0, Gxxy_1, P1(i) - P1(i1) )
Sy1 = ValueSpline1_0 ( X, P1(i), P1(i1), Gyy_0, Gyy_1,Gxxyy_0, Gxxyy_1, P1(i) - P1(i1) )
end subroutine CalcSpline2_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module Spline2 !********************************************************************************

View File

@ -0,0 +1,316 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module TPMForceField !******************************************************************************
!
! Calculation of the TMD force field
!
!---------------------------------------------------------------------------------------------------
!
! PGI Fortran, Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, version 09.01, 2020
!
!***************************************************************************************************
use CNTPot
use TPMM0
use TPMM1
use iso_c_binding, only : c_int, c_double, c_char
implicit none
contains !******************************************************************************************
subroutine TubeStretchingForceField ( U1, U2, F1, F2, S1, S2, X1, X2, R12, L12 ) !!!!!!!!!!!
! Interaction energies associated with nodes X1 and X2
real(c_double), intent(inout) :: U1, U2
! Forces exerted on nodes X1 and X2
real(c_double), intent(inout), dimension(0:2) :: F1, F2
! Contributions of nodes X1 and X2 to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2) :: S1, S2
! Coordinates of the segment nodes
real(c_double), intent(in), dimension(0:2) :: X1, X2
! Radius of a nanotube the segment (X1,X2) belongs to
real(c_double), intent(in) :: R12
! Equilibrium length of segment (X1,X2)
real(c_double), intent(in) :: L12
!-------------------------------------------------------------------------------------------
integer(c_int) :: ii, jj, Event
real(c_double) :: U, F, LL, S, Ubcl
real(c_double), dimension(0:2) :: DX, FF
!-------------------------------------------------------------------------------------------
DX = X2 - X1
LL = S_V3norm3 ( DX )
Event = CNTSTRCalc ( U, F, LL, R12, L12, 0, Ubcl )
U = U / 2.0d+00
FF = DX * F / LL
F1 = F1 + FF
U1 = U1 + U
F2 = F2 - FF
U2 = U2 + U
! Stress
do ii = 0, 2
do jj = 0, 2
S = - 0.5d+00 * DX(ii) * FF(jj)
S1(ii,jj) = S1(ii,jj) + S
S2(ii,jj) = S2(ii,jj) + S
end do
end do
end subroutine TubeStretchingForceField !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TubeBendingForceField ( U1, U2, U3, F1, F2, F3, S1, S2, S3, X1, X2, X3, R123, L123, BBF2 )
! Interaction energies associated with nodes X1, X2, and X3
real(c_double), intent(inout) :: U1, U2, U3
! Forces exerted on nodes X1, X2, and X3
real(c_double), intent(inout), dimension(0:2) :: F1, F2, F3
! Contributions of nodes X1, X2, and X3 to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2) :: S1, S2, S3
! Coordinates of nodes
real(c_double), intent(in), dimension(0:2) :: X1, X2, X3
! Radius of nanotube the segment (X1,X2) belongs to
real(c_double), intent(in) :: R123
! Equilibrium length of segment (X1,X2) and (X2,X3) (It is assumed to be the same for both segments)
real(c_double), intent(in) :: L123
integer(c_int), intent(inout) :: BBF2
!-------------------------------------------------------------------------------------------
integer(c_int) :: ii, jj, Event
real(c_double) :: U, F, K, S, Ubcl
real(c_double), dimension(0:2) :: G0, G1, G2
!-------------------------------------------------------------------------------------------
call BendingGradients ( K, G0, G1, G2, X1, X2, X3 )
Event = CNTBNDCalc ( U, F, K, R123, L123, BBF2, Ubcl )
if ( Event == CNTPOT_BBUCKLING ) then
BBF2 = 1
else
BBF2 = 0
end if
U = U / 4.0d+00
F = - F
F1 = F1 + G0 * F
F2 = F2 + G1 * F
F3 = F3 + G2 * F
U1 = U1 + U
U2 = U2 + 2.0d+00 * U
U3 = U3 + U
! Stress
do ii = 0, 2
do jj = 0, 2
S = 0.5d+00 * ( X1(ii) - X2(ii) ) * G0(jj)
S1(ii,jj) = S1(ii,jj) + S
S2(ii,jj) = S2(ii,jj) + S
S = 0.5d+00 * ( X3(ii) - X2(ii) ) * G2(jj)
S3(ii,jj) = S3(ii,jj) + S
S2(ii,jj) = S2(ii,jj) + S
end do
end do
end subroutine TubeBendingForceField !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! The purpose of subroutine SegmentTubeForceField is to calculate interaction forces
! (as well potential energies and components of the virial stress tensor) between a segment
! (X1,X2) and a sequence of segments which belongs to a single CNT.
! It is assumed that X contains ALL nodes of a single CNT that are included into the
! neighbor list of segment (X1,X2).
! The nodes in X are assumed to be ordered according to their physical appearance in the nanotube.
! It means that (X(i),X(i+1)) are either correspond to a real segment or divided by segments
! that do not belong to a nanotube.
! Concept of the extended chain:
! Let's consider a sequence of nodes (X1,X2,...,XN) forming continuous part of a nanotube.
! If node Xe precedes X1 and Xe is the nanotube end, then the extended chain is (Xe,X1,...,XN) and Ee = 1.
! If node Xe follows XN and Xe is the nanotube end, then the extended chain is (X1,...,XN,Xe) and Ee = 2.
! In all other cases, the extended chain coincides with (X1,...,XN) and Ee = 0.
! If the extended chain contains additional node, then non-zero force is exerted on this node.
subroutine SegmentTubeForceField ( U1, U2, U, F1, F2, F, Fe, S1, S2, S, Se, X1, X2, R12, N, X, Xe,&
BBF, R, E1, E2, Ee, TPMType )
! Number of nodes in array X
integer(c_int), intent(in) :: N
! Interaction energies associated with nodes X1 and X2
real(c_double), intent(inout) :: U1, U2
! Interaction energies associated with nodes X
real(c_double), intent(inout), dimension(0:N-1) :: U
! Forces exerted on nodes X1 and X2
real(c_double), intent(inout), dimension(0:2) :: F1, F2
! Forces exerted on nodes X
real(c_double), intent(inout), dimension(0:2,0:N-1) :: F
! Force exerted on node Xe (can be updated only if Ee > 0)
real(c_double), intent(inout), dimension(0:2) :: Fe
! Contributions of nodes X1 and X2 to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2) :: S1, S2
! Contributions of nodes X to the virial stress tensor
real(c_double), intent(inout), dimension(0:2,0:2,0:N-1) :: S
! Contributions of node Xe to the virial stress tensor (can be updated only if Ee > 0)
real(c_double), intent(inout), dimension(0:2,0:2) :: Se
! Coordinates of the segment nodes
real(c_double), intent(in), dimension(0:2) :: X1, X2
! Radius of a nanotube the segment (X1,X2) belongs to
real(c_double), intent(in) :: R12
! Coordinates of the nanotube nodes
real(c_double), intent(in), dimension(0:2,0:N-1) :: X
! Additional node of the extended chain if Ee > 0
real(c_double), intent(in), dimension(0:2) :: Xe
! Bending buckling flags (BBF(i) = 1 in a case of buckling in node i)
integer(c_int), intent(in), dimension(0:N-1) :: BBF
! Radius of nanotube X
real(c_double), intent(in) :: R
! E1 = 1 if the chain node 0 is a CNT end; E1 = 2 if the chain node N-1 is a CNT end
integer(c_int), intent(in) :: E1, E2
! Parameter defining the type of the extended chain (0,1,2)
integer(c_int), intent(in) :: Ee
! Type of the tubular potential (0 or 1)
integer(c_int), intent(in) :: TPMType
!-------------------------------------------------------------------------------------------
integer(c_int) :: k, ii, jj, IntSign
integer(c_int) :: BType, EType, LocalTPMType
real(c_double), dimension(0:2,0:N-1) :: G1, G2
real(c_double), dimension(0:N-1) :: QQ
logical :: EType1, EType2
real(c_double), dimension(0:2) :: G, DG, DQ, XX
real(c_double) :: UT, DR, DS, DS1
! Interaction energies associated with nodes X1 and X2
real(c_double) :: xU1, xU2
! Interaction energies associated with nodes X
real(c_double), dimension(0:N-1) :: xU
! Forces exerted on nodes X1 and X2
real(c_double), dimension(0:2) :: xF1, xF2
! Forces exerted on nodes X
real(c_double), dimension(0:2,0:N-1) :: xF
! Force exerted on node Xe (can be updated only if Ee > 0)
real(c_double), dimension(0:2) :: xFe
!-------------------------------------------------------------------------------------------
! Looking for a buckling point
BType = 0
do k = 0, N - 1
if ( BBF(k) == 1 ) then
BType = 1
exit
end if
end do
! Choosing the LocalTPMType and Etype.
! LocalTPMType is set to 0 if both ends of the chain are nanotube ends or the chain contains a buckling point.
! Overwise, LocalTPMType = TPMType.
if ( BType == 1 ) then
LocalTPMType = 0
EType = 0
else
if ( E1 == 1 ) then ! The first node in the chain is the tube end
EType1 = .true.
else
EType1 = .false.
end if
if ( E2 == 1 ) then ! The last node in the chain is the tube end
EType2 = .true.
else
EType2 = .false.
end if
if ( EType1 .and. EType2 ) then
LocalTPMType = 0
else
LocalTPMType = TPMType
if ( EType1 ) then
EType = 1
else if ( EType2 ) then
EType = 2
else ! No tube ends in the chain
EType = 0
end if
end if
end if
if ( LocalTPMType == 0 ) then
IntSign = TPMInteractionFW0 ( QQ, UT, xU1, xU2, xU, xF1, xF2, xF, G1, G2, X1, X2, N, N, X )
else
if ( EType == 0 ) then
if ( Ee == 1 ) then ! The first node in the extended chain is the tube end
EType = 3
else if ( Ee == 2 ) then ! The last node in the extended chain is the tube end
EType = 4
end if
end if
IntSign = TPMInteractionFW1 ( QQ, UT, xU1, xU2, xU, xF1, xF2, xF, xFe, G1, G2, X1, X2, N, N, X, Xe, EType )
end if
if ( IntSign == 0 ) return ! No interaction
! Final potential energies
U1 = U1 + 0.5d+00 * xU1
U2 = U2 + 0.5d+00 * xU2
U(0:N-1) = U(0:N-1) + 0.5d+00 * xU(0:N-1)
! Contributions to the virial stresses tensor
do ii = 0, 2
DR = 0.125d+00 * ( X2(ii) - X1(ii) )
do jj = 0, 2
DS = DR * ( xF2(jj) - xF1(jj) )
S1(ii,jj) = S1(ii,jj) + DS
S2(ii,jj) = S2(ii,jj) + DS
end do
end do
XX = 0.5d+00 * ( X2 + X1 )
if ( EType > 2 ) then
DQ = Xe - XX
call ApplyPeriodicBC ( DQ )
DQ = DQ / 6.0d+00
do ii = 0, 2
do jj = 0, 2
DS = DQ(ii) * xFe(jj)
S1(ii,jj) = S1(ii,jj) + DS
S2(ii,jj) = S1(ii,jj) + DS
Se(ii,jj) = Se(ii,jj) + DS
end do
end do
end if
do k = 0, N - 2
DQ = 0.5d+00 * ( X(0:2,k+1) + X(0:2,k) ) - XX
call ApplyPeriodicBC ( DQ )
DQ = 0.125d+00 * DQ
G = G1(0:2,k+1) + G2(0:2,k)
DG = G1(0:2,k+1) - G2(0:2,k)
do ii = 0, 2
DR = 0.125d+00 * ( X(ii,k+1) - X(ii,k) )
do jj = 0, 2
DS = DQ(ii) * G(jj)
DS1 = DS + DR * DG(jj)
S1(ii,jj) = S1(ii,jj) + DS
S2(ii,jj) = S2(ii,jj) + DS
S(ii,jj,k) = S(ii,jj,k) + DS1
S(ii,jj,k+1) = S(ii,jj,k+1) + DS1
end do
end do
end do
! Final forces
F1 = F1 + 0.5d+00 * xF1
F2 = F2 + 0.5d+00 * xF2
F(0:2,0:N-1) = F(0:2,0:N-1) + 0.5d+00 * xF(0:2,0:N-1)
if ( EType > 2 ) then
Fe = Fe + 0.5d+00 * xFe
end if
end subroutine SegmentTubeForceField !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMForceField !**************************************************************************

155
lib/mesont/TPMGeom.f90 Normal file
View File

@ -0,0 +1,155 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module TPMGeom !************************************************************************************
!
! Geometry functions.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use TPMLib
use iso_c_binding, only : c_int, c_double, c_char
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
integer(c_int), parameter :: MD_LINES_NONPAR = 0
integer(c_int), parameter :: MD_LINES_PAR = 1
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
! Coordinates of the whole domain
real(c_double) :: DomXmin, DomXmax, DomYmin, DomYmax, DomZmin, DomZmax
real(c_double) :: DomLX, DomLY, DomLZ
real(c_double) :: DomLXhalf, DomLYhalf, DomLZhalf
! Boundary conditions
integer(c_int) :: BC_X = 0
integer(c_int) :: BC_Y = 0
integer(c_int) :: BC_Z = 0
! Skin parameter in NBL and related algorithms
real(c_double) :: Rskin = 1.0d+00
contains !******************************************************************************************
subroutine ApplyPeriodicBC ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This subroutine changes coordinates of the point according to the periodic boundary conditions
! it order to make sure that the point is inside the computational cell,
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2), intent(inout) :: R
!-------------------------------------------------------------------------------------------
if ( BC_X == 1 ) then
if ( R(0) .GT. DomLXHalf ) then
R(0) = R(0) - DomLX
else if ( R(0) .LT. - DomLXHalf ) then
R(0) = R(0) + DomLX
end if
end if
if ( BC_Y == 1 ) then
if ( R(1) .GT. DomLYHalf ) then
R(1) = R(1) - DomLY
else if ( R(1) .LT. - DomLYHalf ) then
R(1) = R(1) + DomLY
end if
end if
if ( BC_Z == 1 ) then
if ( R(2) .GT. DomLZHalf ) then
R(2) = R(2) - DomLZ
else if ( R(2) .LT. - DomLZHalf ) then
R(2) = R(2) + DomLZ
end if
end if
end subroutine ApplyPeriodicBC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine LinePoint ( Displacement, Q, R1, L1, R0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function calculates the point Q of projection of point R0 onto line (R1,L1).
! Q = R1 + Displacement * L1.
!-------------------------------------------------------------------------------------------
real(c_double), intent(inout) :: Displacement
real(c_double), dimension(0:2), intent(inout) :: Q
real(c_double), dimension(0:2), intent(in) :: R1, L1, R0
!--------------------------------------------------------------------------------------------
Q = R0 - R1
! Here we take into account periodic boundaries
call ApplyPeriodicBC ( Q )
Displacement = S_V3xV3 ( Q, L1 )
Q = R1 + Displacement * L1
end subroutine LinePoint !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function LineLine ( H, cosA, D1, D2, L12, R1, L1, R2, L2, Prec ) !!!!!!!!!!!!
! This function determines the smallest distance H between two lines (R1,L1) and (R2,L2).
!-------------------------------------------------------------------------------------------
! Input values:
! R1, L1, point and direction of line 1.
! R2, L2, point and direction of line 2.
! Prec, precision for the case L1 * L2 = 0 (parallel lines).
! Return values:
! H, minimum distance between lines.
! cosA, cosine of the angle between lines.
! D1, D2, displacements.
! L12, unit vector directed along the closest distance.
!-------------------------------------------------------------------------------------------
real(c_double), intent(inout) :: H, cosA, D1, D2
real(c_double), dimension(0:2), intent(out) :: L12
real(c_double), dimension(0:2), intent(in) :: R1, L1, R2, L2
!-------------------------------------------------------------------------------------------
real(c_double), intent(in) :: Prec
real(c_double), dimension(0:2) :: Q1, Q2, R
real(c_double) :: C, DD1, DD2, C1, C2
!-------------------------------------------------------------------------------------------
cosA = S_V3xV3 ( L1, L2 )
C = 1.0 - sqr ( cosA )
if ( C < Prec ) then ! Lines are parallel to each other
LineLine = MD_LINES_PAR
return
end if
LineLine = MD_LINES_NONPAR
R = R2 - R1
! Here we take into account periodic boundary conditions
call ApplyPeriodicBC ( R )
DD1 = S_V3xV3 ( R, L1 )
DD2 = S_V3xV3 ( R, L2 )
D1 = ( cosA * DD2 - DD1 ) / C
D2 = ( DD2 - cosA * DD1 ) / C
Q1 = R1 - D1 * L1
Q2 = R2 - D2 * L2
L12 = Q2 - Q1
! Here we take into account periodic boundary conditions
call ApplyPeriodicBC ( L12 )
H = S_V3norm3 ( L12 )
if ( H < Prec ) then ! Lines intersect each other
C1 = signum ( D1 )
C2 = signum ( D1 ) * signum ( cosA )
Q1 = C1 * L1
Q2 = C2 * L2
call V3_V3xxV3 ( L12, Q1, Q2 )
call V3_ort ( L12 )
else ! No intersection
L12 = L12 / H
end if
end function LineLine !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMGeom !********************************************************************************

215
lib/mesont/TPMLib.f90 Normal file
View File

@ -0,0 +1,215 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module TPMLib !*************************************************************************************
!
! Basic constants, types, and mathematical functions.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use iso_c_binding, only : c_int, c_double, c_char
implicit none
!---------------------------------------------------------------------------------------------------
! Mathematical constants
!---------------------------------------------------------------------------------------------------
real(c_double), parameter :: M_PI_2 = 1.57079632679489661923
real(c_double), parameter :: M_PI = 3.14159265358979323846
real(c_double), parameter :: M_3PI_2 = 4.71238898038468985769
real(c_double), parameter :: M_2PI = 6.28318530717958647692
real(c_double), parameter :: M_PI_180 = 0.017453292519943295769
!---------------------------------------------------------------------------------------------------
! Physical unit constants
!---------------------------------------------------------------------------------------------------
real(c_double), parameter :: K_AMU = 1.66056E-27 ! a.m.u. (atomic mass unit, Dalton)
real(c_double), parameter :: K_EV = 1.60217646e-19 ! eV (electron-volt)
real(c_double), parameter :: K_MDLU = 1.0E-10 ! MD length unit (m)
real(c_double), parameter :: K_MDEU = K_EV ! MD energy unit (J)
real(c_double), parameter :: K_MDMU = K_AMU ! MD mass unit (kg)
real(c_double), parameter :: K_MDFU = K_MDEU / K_MDLU ! MD force unit (N)
real(c_double), parameter :: K_MDCU = K_MDEU / K_MDMU ! MD specific heat unit (J/(kg*K))
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
integer(c_int) :: StdUID = 31
contains !******************************************************************************************
!---------------------------------------------------------------------------------------------------
! Simple mathematical functions
!---------------------------------------------------------------------------------------------------
real(c_double) function rad ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: X
!-------------------------------------------------------------------------------------------
rad = X * M_PI_180
end function rad !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function sqr ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: X
!-------------------------------------------------------------------------------------------
sqr = X * X
end function sqr !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function signum ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: X
!-------------------------------------------------------------------------------------------
if ( X > 0 ) then
signum = 1
else if ( X < 0 ) then
signum = -1
else
signum = 0
end if
end function signum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Vector & matrix functions
!---------------------------------------------------------------------------------------------------
real(c_double) function S_V3xx ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(in) :: V
!-------------------------------------------------------------------------------------------
S_V3xx = V(0) * V(0) + V(1) * V(1) + V(2) * V(2)
end function S_V3xx !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function S_V3xV3 ( V1, V2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(in) :: V1, V2
!-------------------------------------------------------------------------------------------
S_V3xV3 = V1(0) * V2(0) + V1(1) * V2(1) + V1(2) * V2(2)
end function S_V3xV3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function S_V3norm3 ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(in) :: V
!-------------------------------------------------------------------------------------------
S_V3norm3 = dsqrt ( V(0) * V(0) + V(1) * V(1) + V(2) * V(2) )
end function S_V3norm3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine V3_ort ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(inout) :: V
!-------------------------------------------------------------------------------------------
real(c_double) :: Vabs
!-------------------------------------------------------------------------------------------
Vabs = S_V3norm3 ( V )
V(0) = V(0) / Vabs
V(1) = V(1) / Vabs
V(2) = V(2) / Vabs
end subroutine V3_ort !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine V3_V3xxV3 ( V, V1, V2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(out) :: V
real(c_double), dimension(0:2), intent(in) :: V1, V2
!-------------------------------------------------------------------------------------------
V(0) = V1(1) * V2(2) - V1(2) * V2(1)
V(1) = V1(2) * V2(0) - V1(0) * V2(2)
V(2) = V1(0) * V2(1) - V1(1) * V2(0)
end subroutine V3_V3xxV3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Handling of spherical and Euler angles
!---------------------------------------------------------------------------------------------------
subroutine RotationMatrix3 ( M, Psi, Tet, Phi ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Ksi, Tet and Phi are Euler angles
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2,0:2), intent(out) :: M
real(c_double), intent(in) :: Psi, Tet, Phi
!-------------------------------------------------------------------------------------------
real(c_double) :: cK, sK, cT, sT, cP, sP
!-------------------------------------------------------------------------------------------
cK = dcos ( Psi )
sK = dsin ( Psi )
cT = dcos ( Tet )
sT = dsin ( Tet )
cP = dcos ( Phi )
sP = dsin ( Phi )
M(0,0) = cP * cK - sK * sP * cT
M(0,1) = cP * sK + sP * cT * cK
M(0,2) = sP * sT
M(1,0) = - sP * cK - cP * cT * sK
M(1,1) = - sP * sK + cP * cT * cK
M(1,2) = cP * sT
M(2,0) = sT * sK
M(2,1) = - sT * cK
M(2,2) = cT
end subroutine RotationMatrix3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine EulerAngles ( Psi, Tet, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: Tet, Psi
real(c_double), dimension(0:2), intent(in) :: L
!-------------------------------------------------------------------------------------------
Tet = acos ( L(2) )
Psi = atan2 ( L(1), L(0) )
if ( Psi > M_3PI_2 ) then
Psi = Psi - M_3PI_2
else
Psi = Psi + M_PI_2
end if
end subroutine EulerAngles !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! File input and output
!---------------------------------------------------------------------------------------------------
integer(c_int) function OpenFile ( Name, Params, Path ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
character*(*), intent(in) :: Name, Params, Path
!-------------------------------------------------------------------------------------------
integer(c_int) :: Fuid
character*512 :: FullName, Msg, Name1, Action1, Status1, Form1, Position1
!-------------------------------------------------------------------------------------------
OpenFile = StdUID + 1
if ( Params(1:1) == 'r' ) then
Action1 = 'read'
Status1 = 'old'
Position1 = 'rewind'
else if ( Params(1:1) == 'w' ) then
Action1 = 'write'
Status1 = 'replace'
Position1 = 'rewind'
else if ( Params(1:1) == 'a' ) then
Action1 = 'write'
Status1 = 'old'
Position1 = 'append'
endif
if ( Params(2:2) == 'b' ) then
Form1 = 'binary'
else
Form1 = 'formatted'
endif
open ( unit = OpenFile, file = Name, form = Form1, action = Action1, status = Status1, position = Position1 )
StdUID = StdUID + 1
return
end function OpenFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CloseFile ( Fuid ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int), intent(inout) :: Fuid
!-------------------------------------------------------------------------------------------
if ( Fuid < 0 ) return
close ( unit = Fuid )
Fuid = -1
end subroutine CloseFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMLib !*********************************************************************************

194
lib/mesont/TPMM0.f90 Normal file
View File

@ -0,0 +1,194 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module TPMM0 !**************************************************************************************
!
! Combined/Weighted TPM potential of type 0.
!
! Direct application of SST potential to calculation of segment-segment interaction.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use TubePotMono
use iso_c_binding, only : c_int, c_double, c_char
implicit none
contains !******************************************************************************************
integer(c_int) function TPMInteractionFSS ( Q, U, F1_1, F1_2, F2_1, F2_2, R1_1, R1_2, R2_1, R2_2, EType )
real(c_double), intent(inout) :: Q, U
real(c_double), dimension(0:2), intent(inout) :: F1_1, F1_2, F2_1, F2_2
real(c_double), dimension(0:2), intent(in) :: R1_1, R1_2, R2_1, R2_2
integer(c_int), intent(in) :: EType
!-------------------------------------------------------------------------------------------
real(c_double) :: Qa, Ua, Fd, L2
real(c_double), dimension(0:2) :: F1_1a, F1_2a, F2_1a, F2_2a, R2_3, R2, Laxis2, F
integer(c_int) :: IntSign
!-------------------------------------------------------------------------------------------
R2 = 0.5d+00 * ( R2_1 + R2_2 )
Laxis2 = R2_2 - R2_1
L2 = S_V3norm3 ( Laxis2 )
Laxis2 = Laxis2 / L2
if ( EType < 2 ) then
TPMInteractionFSS = TPMInteractionF ( Q, U, F1_1, F1_2, F2_1, F2_2, Fd, R1_1, R1_2, R2_1, R2_2, 1 )
R2_3 = R2_2 + R2_2 - R2_1
IntSign = TPMInteractionF ( Qa, Ua, F1_1a, F1_2a, F2_1a, F2_2a, Fd, R1_1, R1_2, R2_2, R2_3, 1 )
if ( IntSign > 0 ) then
TPMInteractionFSS = 1
call TPMSegmentForces ( F2_1a, F2_2a, F1_1a, F1_2a, R1_1, R1_2, R2, Laxis2, L2 )
F = ( Fd - S_V3xV3 ( F2_2a, Laxis2 ) ) * Laxis2
F2_2a = F2_2a + F
F2_1a = F2_1a - F
end if
else
TPMInteractionFSS = TPMInteractionF ( Q, U, F1_1, F1_2, F2_1, F2_2, Fd, R1_1, R1_2, R2_1, R2_2, 2 )
R2_3 = R2_1 + R2_1 - R2_2
IntSign = TPMInteractionF ( Qa, Ua, F1_1a, F1_2a, F2_1a, F2_2a, Fd, R1_1, R1_2, R2_1, R2_3, 1 )
if ( IntSign > 0 ) then
TPMInteractionFSS = 1
call TPMSegmentForces ( F2_1a, F2_2a, F1_1a, F1_2a, R1_1, R1_2, R2, Laxis2, L2 )
F = ( - Fd - S_V3xV3 ( F2_1a, Laxis2 ) ) * Laxis2
F2_1a = F2_1a + F
F2_2a = F2_2a - F
end if
end if
if ( IntSign > 0 ) then
Q = Q - Qa
if ( Q < 0.0d+00 ) Q = 0.0d+00
U = U - Ua
F2_1 = F2_1 - F2_1a
F2_2 = F2_2 - F2_2a
F1_1 = F1_1 - F1_1a
F1_2 = F1_2 - F1_2a
end if
end function TPMInteractionFSS !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPMInteractionFW0 ( QQ, U, U1, U2, UU, F1, F2, F, G1, G2, R1, R2, N, NMAX, R )
real(c_double), intent(inout) :: U, U1, U2
integer(c_int), intent(in) :: N, NMAX
real(c_double), dimension(0:NMAX-1), intent(out) :: QQ, UU
real(c_double), dimension(0:2), intent(out) :: F1, F2
real(c_double), dimension(0:2,0:NMAX-1), intent(out) :: F, G1, G2
real(c_double), dimension(0:2), intent(in) :: R1, R2
real(c_double), dimension(0:2,0:NMAX-1), intent(in) :: R
!-------------------------------------------------------------------------------------------
integer(c_int) :: i, SType2, GeomID, EType
real(c_double) :: Ua
real(c_double), dimension(0:2) :: F1_1a, F1_2a, F2_1a, F2_2a
real(c_double), dimension(0:2) :: R1a, R2a, Laxis1, Laxis2, L12, DR
real(c_double) :: L1, L2, D1, D2, H, cosA, D, Dmina, Dminb
!-------------------------------------------------------------------------------------------
QQ = 0.0d+00
U = 0.0d+00
U1 = 0.0d+00
U2 = 0.0d+00
UU = 0.0d+00
F1 = 0.0d+00
F2 = 0.0d+00
F = 0.0d+00
G1 = 0.0d+00
G2 = 0.0d+00
TPMInteractionFW0 = 0
do i = 0, N - 2
R1a = 0.5d+00 * ( R1 + R2 )
R2a = 0.5d+00 * ( R(0:2,i+1) + R(0:2,i) )
Laxis1 = R2 - R1
Laxis2 = R(0:2,i+1) - R(0:2,i)
L1 = S_V3norm3 ( Laxis1 )
L2 = S_V3norm3 ( Laxis2 )
Laxis1 = Laxis1 / L1
Laxis2 = Laxis2 / L2
L2 = 0.5d+00 * L2
L1 = 0.5d+00 * L1
GeomID = LineLine ( H, cosA, D1, D2, L12, R1a, Laxis1, R2a, Laxis2, TPGeomPrec )
DR = R1 - R(0:2,i)
call ApplyPeriodicBC ( DR )
Dmina = sqr ( DR(0) ) + sqr ( DR(1) ) + sqr ( DR(2) )
DR = R2 - R(0:2,i)
call ApplyPeriodicBC ( DR )
D = sqr ( DR(0) ) + sqr ( DR(1) ) + sqr ( DR(2) )
if ( D < Dmina ) Dmina = D
if ( GeomID == MD_LINES_NONPAR ) then
D = ( D2 - L2 ) * cosA
if ( D > D1 - L1 .and. D < D1 + L1 ) then
D = sqr ( D2 - L2 ) * ( 1.0d+00 - sqr ( cosA ) ) + sqr ( H )
if ( D < Dmina ) Dmina = D
end if
else
call LinePoint ( D, DR, R1, Laxis1, R(0:2,i) )
if ( D > 0.0d+00 .and. D < 2.0d+00 * L1 ) then
DR = DR - R(0:2,i)
call ApplyPeriodicBC ( DR )
D = sqr ( DR(0) ) + sqr ( DR(1) ) + sqr ( DR(2) )
if ( D < Dmina ) Dmina = D
end if
end if
DR = R1 - R(0:2,i+1)
call ApplyPeriodicBC ( DR )
Dminb = sqr ( DR(0) ) + sqr ( DR(1) ) + sqr ( DR(2) )
DR = R2 - R(0:2,i+1)
call ApplyPeriodicBC ( DR )
D = sqr ( DR(0) ) + sqr ( DR(1) ) + sqr ( DR(2) )
if ( D < Dminb ) Dminb = D
if ( GeomID == MD_LINES_NONPAR ) then
D = ( D2 + L2 ) * cosA
if ( D > D1 - L1 .and. D < D1 + L1 ) then
D = sqr ( D2 + L2 ) * ( 1.0d+00 - sqr ( cosA ) ) + sqr ( H )
if ( D < Dminb ) Dminb = D
end if
else
call LinePoint ( D, DR, R1, Laxis1, R(0:2,i+1) )
if ( D > 0.0d+00 .and. D < 2.0d+00 * L1 ) then
DR = DR - R(0:2,i+1)
call ApplyPeriodicBC ( DR )
D = sqr ( DR(0) ) + sqr ( DR(1) ) + sqr ( DR(2) )
if ( D < Dminb ) Dminb = D
end if
end if
if ( Dmina < Dminb ) then
EType = 1
else
EType = 2
end if
if ( TPMInteractionFSS ( QQ(i), Ua, F1_1a, F1_2a, F2_1a, F2_2a, R1, R2, R(0:2,i), R(0:2,i+1), &
EType ) > 0 ) then
TPMInteractionFW0 = 1
U = U + Ua
Ua = 0.25d+00 * Ua
U1 = U1 + Ua
U2 = U2 + Ua
UU(i) = UU(i) + Ua
UU(i+1) = UU(i+1) + Ua
F1 = F1 + F1_1a
F2 = F2 + F1_2a
F(0:2,i) = F(0:2,i) + F2_1a
F(0:2,i+1) = F(0:2,i+1) + F2_2a
G2(0:2,i) = F2_1a
G1(0:2,i+1) = F2_2a
end if
end do
end function TPMInteractionFW0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMM0 !**********************************************************************************

372
lib/mesont/TPMM1.f90 Normal file
View File

@ -0,0 +1,372 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module TPMM1 !**************************************************************************************
!
! Combined/Weighted potential of type 1.
!
! Calculation of the combined potential is based on the 'extended' chain.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran.
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use TubePotMono
use iso_c_binding, only : c_int, c_double, c_char
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
! Maximum length of a segment chain
integer(c_int), parameter :: TPM_MAX_CHAIN = 100
!---------------------------------------------------------------------------------------------------
! Numerical parameters
!---------------------------------------------------------------------------------------------------
! Switching parameters
real(c_double) :: TPMC123 = 1.0d+00 ! Non-dimensional
real(c_double) :: TPMC3 = 10.0d+00 ! (A)
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
! These global variables are used to speedup calculations
real(c_double), dimension(0:2,0:TPM_MAX_CHAIN-1) :: E1, E2, EE1, EE2
real(c_double), dimension(0:2) :: Q1, Q2, Qe, Qe1, DR, Z1, Z2, S1, S2, Pe, Pe1
real(c_double), dimension(0:TPM_MAX_CHAIN-1) :: W, C
real(c_double), dimension(0:2) :: RR, E10
real(c_double) :: L10, D10
contains !******************************************************************************************
subroutine PairWeight1 ( W, E1_1, E1_2, E2_1, E2_2, R2_1, R2_2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: W
real(c_double), dimension(0:2), intent(out) :: E1_1, E1_2, E2_1, E2_2
real(c_double), dimension(0:2), intent(in) :: R2_1, R2_2
!-------------------------------------------------------------------------------------------
real(c_double) :: D, L20, D20, t, dWdD
real(c_double), dimension(0:2) :: E, E20
!-------------------------------------------------------------------------------------------
E = 0.5d+00 * ( R2_1 + R2_2 ) - RR
call ApplyPeriodicBC ( E )
D = E(0) * E(0) + E(1) * E(1) + E(2) * E(2)
if ( D < D10 * D10 ) then
W = 1.0d+00
E1_1 = 0.0d+00
E1_2 = 0.0d+00
E2_1 = 0.0d+00
E2_2 = 0.0d+00
return
end if
E20 = 0.5d+00 * ( R2_2 - R2_1 )
L20 = sqrt ( S_V3xx ( E20 ) + sqr ( TPMR2 ) )
D20 = L10 + L20 + TPBRcutoff + RSkin
if ( D > D20 * D20 ) then
W = 0.0d+00
E1_1 = 0.0d+00
E1_2 = 0.0d+00
E2_1 = 0.0d+00
E2_2 = 0.0d+00
return
end if
D = sqrt ( D )
E = E / D
E20 = E20 / L20
D20 = D20 - D10
t = ( D - D10 ) / D20
W = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
dWdD = 3.0d+00 * t * ( t - 1.0d+00 ) / D20
E1_1 = dWdD * ( t * E10 - E )
E1_2 = dWdD * ( - t * E10 - E )
E2_1 = dWdD * ( E + t * E20 )
E2_2 = dWdD * ( E - t * E20 )
end subroutine PairWeight1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function EndWeight1 ( W, E1_1, E1_2, E2_1, E2_2, R1_1, R1_2, R2_1, R2_2 ) !!!
real(c_double), intent(out) :: W
real(c_double), dimension(0:2), intent(out) :: E1_1, E1_2, E2_1, E2_2
real(c_double), dimension(0:2), intent(in) :: R1_1, R1_2, R2_1, R2_2
!-------------------------------------------------------------------------------------------
real(c_double) :: D, L20
real(c_double) :: D1, D2, t, dWdD
real(c_double), dimension(0:2) :: RR, E, E20
!-------------------------------------------------------------------------------------------
E = 0.5d+00 * ( R2_1 + R2_2 - ( R1_1 + R1_2 ) )
call ApplyPeriodicBC ( E )
D = S_V3norm3 ( E )
E20 = 0.5d+00 * ( R2_2 - R2_1 )
L20 = sqrt ( S_V3xx ( E20 ) + sqr ( TPMR2 ) )
D1 = L10 + L20 + TPBRcutoff + RSkin
if ( D < D1 ) then
EndWeight1 = 0
W = 1.0d+00
E1_1 = 0.0d+00
E1_2 = 0.0d+00
E2_1 = 0.0d+00
E2_2 = 0.0d+00
return
end if
D2 = D1 + TPMC3
if ( D > D2 ) then
EndWeight1 = 2
W = 0.0d+00
E1_1 = 0.0d+00
E1_2 = 0.0d+00
E2_1 = 0.0d+00
E2_2 = 0.0d+00
return
end if
EndWeight1 = 1
E = E / D
E20 = E20 / L20
t = ( D - D1 ) / TPMC3
W = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
dWdD = 3.0d+00 * t * ( t - 1.0d+00 ) / TPMC3
E1_1 = dWdD * ( E10 - E )
E1_2 = dWdD * ( - E10 - E )
E2_1 = dWdD * ( E + E20 )
E2_2 = dWdD * ( E - E20 )
end function EndWeight1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPMInteractionFC1 ( Q, U, F1, F2, P1, P2, Pe, Pe1, R1, R2, Q1, Q2, Qe, Qe1, EType )
real(c_double), intent(out) :: Q, U
real(c_double), dimension(0:2), intent(out) :: F1, F2, P1, P2, Pe, Pe1
real(c_double), dimension(0:2), intent(in) :: R1, R2, Q1, Q2, Qe, Qe1
integer(c_int), intent(in) :: EType
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2) :: M, QX, Me, F1a, F2a, P1a, P2a, F1b, F2b, P1b, P2b, ER1, ER2, EQe, EQe1
real(c_double) :: W, W1, D, Qa, Qb, Ua, Ub, L, Pee, Peea, Peeb, DU
integer(c_int) :: IntSigna, IntSignb, CaseID
!-------------------------------------------------------------------------------------------
if ( EType == 0 ) then
TPMInteractionFC1 = TPMInteractionF ( Q, U, F1, F2, P1, P2, Pee, R1, R2, Q1, Q2, 0 )
Pe = 0.0d+00
Pe1 = 0.0d+00
else if ( EType < 3 ) then
QX = 0.5d+00 * ( Q1 + Q2 )
M = Q2 - Q1
L = S_V3norm3 ( M )
M = M / L
Me = Qe - QX
D = S_V3norm3 ( Me )
if ( EType == 1 ) then
TPMInteractionFC1 = TPMInteractionF ( Q, U, F1, F2, P1, P2, Pee, R1, R2, QX - D * M, QX, 1 )
else
TPMInteractionFC1 = TPMInteractionF ( Q, U, F1, F2, P1, P2, Pee, R1, R2, QX, QX + D * M, 2 )
end if
call TPMSegmentForces ( P1, P2, F1, F2, R1, R2, QX, M, L )
Pe = ( Pee / D ) * Me
Pe1 = 0.0d+00
QX = 0.5d+00 * Pe
P1 = P1 + QX
P2 = P2 + QX
else
CaseID = EndWeight1 ( W, ER1, ER2, EQe, Eqe1, R1, R2, Qe, Qe1 )
if ( CaseID < 2 ) then
QX = 0.5d+00 * ( Q1 + Q2 )
M = Q2 - Q1
L = S_V3norm3 ( M )
M = M / L
Me = Qe - QX
D = S_V3norm3 ( Me )
if ( EType == 3 ) then
IntSigna = TPMInteractionF ( Qa, Ua, F1a, F2a, P1a, P2a, Peea, R1, R2, QX - D * M, QX, 1 )
else
IntSigna = TPMInteractionF ( Qa, Ua, F1a, F2a, P1a, P2a, Peea, R1, R2, QX, QX + D * M, 2 )
end if
call TPMSegmentForces ( P1a, P2a, F1a, F2a, R1, R2, QX, M, L )
end if
if ( CaseID > 0 ) then
IntSignb = TPMInteractionF ( Qb, Ub, F1b, F2b, P1b, P2b, Peeb, R1, R2, Q1, Q2, 0 )
end if
if ( CaseID == 0 ) then
TPMInteractionFC1 = IntSigna
Q = Qa
U = Ua
F1 = F1a
F2 = F2a
Pe = ( Peea / D ) * Me
Pe1 = 0.0d+00
QX = 0.5d+00 * Pe
P1 = P1a + QX
P2 = P2a + QX
else if ( CaseID == 2 ) then
TPMInteractionFC1 = IntSignb
Q = Qb
U = Ub
F1 = F1b
F2 = F2b
P1 = P1b
P2 = P2b
Pe = 0.0d+00
Pe1 = 0.0d+00
else
TPMInteractionFC1 = 0
if ( IntSigna > 0 .or. IntSignb > 0 ) TPMInteractionFC1 = 1
W1 = 1.0d+00 - W
DU = Ub - Ua
Q = W * Qa + W1 * Qb
U = W * Ua + W1 * Ub
Pe = ( W * Peea / D ) * Me
QX = 0.5d+00 * Pe
F1 = W * F1a + W1 * F1b + DU * ER1
F2 = W * F2a + W1 * F2b + DU * ER2
P1 = W * P1a + W1 * P1b + QX
P2 = W * P2a + W1 * P2b + QX
Pe = Pe - DU * EQe
Pe1 = - DU * EQe1
end if
end if
end function TPMInteractionFC1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPMInteractionFW1 ( QQ, U, U1, U2, UU, F1, F2, F, Fe, G1, G2, R1, R2, N, NMAX, R, Re, EType )
real(c_double), intent(out) :: U, U1, U2
integer(c_int), intent(in) :: N, NMAX, EType
real(c_double), dimension(0:NMAX-1), intent(out) :: QQ, UU
real(c_double), dimension(0:2), intent(out) :: F1, F2, Fe
real(c_double), dimension(0:2,0:NMAX-1), intent(out) :: F, G1, G2
real(c_double), dimension(0:2), intent(in) :: R1, R2, Re
real(c_double), dimension(0:2,0:NMAX-1), intent(in) :: R
!-------------------------------------------------------------------------------------------
integer(c_int) :: i, j
real(c_double) :: Q, WW, DD
!-------------------------------------------------------------------------------------------
Q1 = 0.0d+00
Q2 = 0.0d+00
WW = 0.0d+00
Z1 = 0.0d+00
Z2 = 0.0d+00
TPMInteractionFW1 = 0
E10 = 0.5d+00 * ( R2 - R1 )
L10 = sqrt ( S_V3xx ( E10 ) + sqr ( TPMR1 ) )
D10 = TPMR1 + TPMR2 + TPMC123 * TPBRcutoff + RSkin
E10 = E10 / L10
RR = 0.5d+00 * ( R1 + R2 )
do i = 0, N - 2
call PairWeight1 ( W(i), E1(0:2,i), E2(0:2,i), EE1(0:2,i), EE2(0:2,i), R(0:2,i), R(0:2,i+1) )
Q1 = Q1 + W(i) * R(0:2,i)
Q2 = Q2 + W(i) * R(0:2,i+1)
WW = WW + W(i)
Z1 = Z1 + E1(0:2,i)
Z2 = Z2 + E2(0:2,i)
end do
if ( WW .le. TPGeomPrec ) return
Q1 = Q1 / WW
Q2 = Q2 / WW
Z1 = Z1 / WW
Z2 = Z2 / WW
if ( EType == 1 ) then
Qe = R(0:2,0)
Qe1 = R(0:2,1)
else if ( EType == 2 ) then
Qe = R(0:2,N-1)
Qe1 = R(0:2,N-2)
else if ( EType == 3 ) then
Qe = Re
Qe1 = R(0:2,0)
else if ( EType == 4 ) then
Qe = Re
Qe1 = R(0:2,N-1)
else
Qe = 0.0d+00
Qe1 = 0.0d+00
end if
TPMInteractionFW1 = TPMInteractionFC1 ( Q, U, F1, F2, S1, S2, Pe, Pe1, R1, R2, Q1, Q2, Qe, Qe1, EType )
if ( TPMInteractionFW1 == 0 ) return
W(0:N-2) = W(0:N-2) / WW
E1(0:2,0:N-2) = E1(0:2,0:N-2) / WW
E2(0:2,0:N-2) = E2(0:2,0:N-2) / WW
EE1(0:2,0:N-2) = EE1(0:2,0:N-2) / WW
EE2(0:2,0:N-2) = EE2(0:2,0:N-2) / WW
G1(0:2,0:N-1) = 0.0d+00
G2(0:2,0:N-1) = 0.0d+00
U1 = 0.25d+00 * U
U2 = U1
UU = 0.0d+00
do i = 0, N - 2
QQ(i) = W(i) * Q
DD = W(i) * U1
UU(i) = UU(i) + DD
UU(i+1) = UU(i+1) + DD
end do
do i = 0, N - 2
C(i) = S_V3xV3 ( S1, R(0:2,i) ) + S_V3xV3 ( S2, R(0:2,i+1) )
F1 = F1 + C(i) * ( E1(0:2,i) - W(i) * Z1 )
F2 = F2 + C(i) * ( E2(0:2,i) - W(i) * Z2 )
end do
F(0:2,0) = W(0) * S1
do j = 0, N - 2
if ( j == 0 ) then
DR = EE1(0:2,0) * ( 1.0d+00 - W(0) )
else
DR = - W(j) * EE1(0:2,0)
end if
F(0:2,0) = F(0:2,0) + C(j) * DR
end do
do i = 1, N - 2
G1(0:2,i) = W(i-1) * S2
G2(0:2,i) = W(i) * S1
do j = 0, N - 2
if ( j == i ) then
G1(0:2,i) = G1(0:2,i) - C(j) * W(j) * EE2(0:2,i-1)
G2(0:2,i) = G2(0:2,i) + C(j) * ( EE1(0:2,j) - W(j) * EE1(0:2,i) )
else if ( j == i - 1 ) then
G1(0:2,i) = G1(0:2,i) + C(j) * ( EE2(0:2,j) - W(j) * EE2(0:2,i-1) )
G2(0:2,i) = G2(0:2,i) - C(j) * W(j) * EE1(0:2,i)
else
G1(0:2,i) = G1(0:2,i) - C(j) * W(j) * EE2(0:2,i-1)
G2(0:2,i) = G2(0:2,i) - C(j) * W(j) * EE1(0:2,i)
end if
end do
F(0:2,i) = G1(0:2,i) + G2(0:2,i)
end do
F(0:2,N-1) = W(N-2) * S2
do j = 0, N - 2
if ( j == N - 2 ) then
DR = EE2(0:2,N-2) * ( 1.0d+00 - W(N-2) )
else
DR = - W(j) * EE2(0:2,N-2)
end if
F(0:2,N-1) = F(0:2,N-1) + C(j) * DR
end do
Fe = 0.0d+00
if ( EType == 1 ) then
F(0:2,0) = F(0:2,0) - Pe
else if ( EType == 2 ) then
F(0:2,N-1) = F(0:2,N-1) - Pe
else if ( EType == 3 ) then
F(0:2,0) = F(0:2,0) - Pe1
Fe = - Pe
else if ( EType == 4 ) then
F(0:2,N-1) = F(0:2,N-1) - Pe1
Fe = - Pe
end if
G1(0:2,N-1) = F(0:2,N-1)
G2(0:2,0) = F(0:2,0)
end function TPMInteractionFW1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMM1 !**********************************************************************************

306
lib/mesont/TubePotBase.f90 Normal file
View File

@ -0,0 +1,306 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module TubePotBase !********************************************************************************
!
! Non-bonded pair interaction potential and transfer functions for atoms composing nanotubes.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!---------------------------------------------------------------------------------------------------
!
! This module contains basic parameters for all modules involved into calculations of tubular
! potentials.
!
! It includes definitions of
! -- TPBU, Lennard-Jones (12-6) potential
! -- TPBQ, Transfer function
!
! All default values are adjusted for non-bonded carbon-carbon interaction in carbon nanotubes.
!
!***************************************************************************************************
use TPMLib
use iso_c_binding, only : c_int, c_double, c_char
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
! Types of the potential with respect to the breathing mode
integer(c_int), parameter :: TP_POT_MONO_R = 0
integer(c_int), parameter :: TP_POT_POLY_R = 1
! Maximal number of elements in corresponding tables
integer(c_int), parameter :: TPBNMAX = 2001
! Numerical constants
real(c_double), parameter :: TPbConstD = 5.196152422706632d+00 ! = 3.0**1.5
! Mass of C atom
real(c_double), parameter :: TPBMc = 12.0107d+00 ! (Da)
! Parameters of the Van der Waals interaction between carbon atoms in graphene sheets, see
! Stuart S.J., Tutein A.B., Harrison J.A., J. Chem. Phys. 112(14), 2000
real(c_double), parameter :: TPBEcc = 0.00284d+00 ! (eV)
real(c_double), parameter :: TPBScc = 3.4d+00 ! (A)
! Lattice parameter and surface number density of atoms for a graphene sheet, see
! Dresselhaus et al, Carbon 33(7), 1995
real(c_double), parameter :: TPBAcc = 1.421d+00 ! (A)
real(c_double), parameter :: TPBDcc = 4.0d+00 / ( TPBConstD * TPBAcc * TPBAcc ) ! (1/A^2)
! Specific heat of carbon nanotubes
real(c_double), parameter :: TPBSHcc = 600.0d+00 / K_MDCU ! (eV/(Da*K))
! Cutoff distances for the interactomic potential and transfer function.
! Changes in these parameters can result in necessity to change some numerical parameters too.
real(c_double), parameter :: TPBRmincc = 0.001d+00 * TPBScc ! (A)
real(c_double), parameter :: TPBRcutoffcc = 3.0d+00 * TPBScc ! (A)
real(c_double), parameter :: TPBRcutoff1cc = 2.16d+00 * TPBScc ! (A)
! Parameters of the transfer function for non-bonded interaction between carbon atoms
real(c_double), parameter :: TPBQScc = 7.0d+00 ! (A)
real(c_double), parameter :: TPBQRcutoff1cc = 8.0d+00 ! (A)
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
! Set to .true. to generate diagnostic and warning messages
logical :: TPErrCheck = .true.
character*512 :: TPErrMsg = ''
real(c_double) :: TPGeomPrec = 1.0d-06 ! Geometric precision, see TPInt
integer(c_int) :: TPPotType = TP_POT_MONO_R ! Type of the potential with respect to the breathing mode
! Parameters of the interatomic potential and atoms distribution at the surface
! of the tube
real(c_double) :: TPBM = TPBMc ! Mass of an atom (Da)
real(c_double) :: TPBE = TPBEcc ! Depth of the energy well in (12-6) LJ interatomic potential (eV)
real(c_double) :: TPBS = TPBScc ! Sigma parameter of (12-6) LJ interatomic potential (A)
real(c_double) :: TPBD = TPBDcc ! Numerical density of atoms at the tube surface (1/A^2)
real(c_double) :: TPBSH = TPBSHcc ! Specific heat (eV/(Da*K))
real(c_double) :: TPBRmin = TPBRmincc ! (A)
real(c_double) :: TPBRcutoff = TPBRcutoffcc ! (A)
real(c_double) :: TPBRcutoff1 = TPBRcutoff1cc ! (A)
! Parameters of the transfer function
real(c_double) :: TPBQS = TPBQScc ! Sigma parameter of the transfer function (A)
real(c_double) :: TPBQRcutoff1 = TPBQRcutoff1cc! (A)
! Auxiliary variables
real(c_double) :: TPBE4, TPBE24, TPBDRcutoff, TPBQDRcutoff
real(c_double) :: TPBQR0 ! Constant-value distance for the transfer function (A)
! Table of inter-particle potential, force, and transfer function
integer(c_int) :: TPBN = TPBNMAX
real(c_double) :: TPBDR
real(c_double), dimension(0:TPBNMAX-1) :: TPBQ
real(c_double), dimension(0:TPBNMAX-1) :: TPBU, TPBdUdR
contains !******************************************************************************************
integer(c_int) function TPBsizeof () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
TPBsizeof = 8 * ( size ( TPBQ ) + size ( TPBU ) + size ( TPBdUdR ) )
end function TPBsizeof !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Interpolation
!---------------------------------------------------------------------------------------------------
real(c_double) function TPBQInt0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: R
!-------------------------------------------------------------------------------------------
real(c_double) :: Z, RR
integer(c_int) :: i
!-------------------------------------------------------------------------------------------
if ( R < TPBRmin ) then
!call PrintStdLogMsg ( TPErrMsg )
!write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) ': R < Rmin: R=', R, ', Rmin=', TPBRmin
!call Error ( 'TPBQInt0', TPErrMsg )
elseif ( R > TPBRcutoff ) then
TPBQInt0 = 0.0d+00
return
endif
RR = ( R - TPBRmin ) / TPBDR
i = int ( RR )
RR = RR - i
Z = 1.0d+00 - RR
TPBQInt0 = TPBQ(i) * Z + TPBQ(i+1) * RR
end function TPBQInt0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function TPBUInt0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: R
!-------------------------------------------------------------------------------------------
real(c_double) :: Z, RR
integer(c_int) :: i
!-------------------------------------------------------------------------------------------
if ( R < TPBRmin ) then
!call PrintStdLogMsg ( TPErrMsg )
!write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) ': R < Rmin: R=', R, ', Rmin=', TPBRmin
!call Error ( 'TPBUInt0', TPErrMsg )
elseif ( R > TPBRcutoff ) then
TPBUInt0 = 0.0d+00
return
endif
RR = ( R - TPBRmin ) / TPBDR
i = int ( RR )
RR = RR - i
Z = 1.0d+00 - RR
TPBUInt0 = TPBU(i) * Z + TPBU(i+1) * RR
end function TPBUInt0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPBUInt1 ( U, dUdR, R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdR
real(c_double), intent(in) :: R
!-------------------------------------------------------------------------------------------
real(c_double) :: Z, RR
integer(c_int) :: i
!-------------------------------------------------------------------------------------------
if ( R < TPBRmin ) then
!call PrintStdLogMsg ( TPErrMsg )
!write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) ': R < Rmin: R=', R, ', Rmin=', TPBRmin
!call Error ( 'TPBUInt1', TPErrMsg )
elseif ( R > TPBRcutoff ) then
TPBU = 0.0d+00
TPBdUdR = 0.0d+00
return
endif
RR = ( R - TPBRmin ) / TPBDR
i = int ( RR )
RR = RR - i
Z = 1.0d+00 - RR
U = TPBU(i) * Z + TPBU(i+1) * RR
dUdR = TPBdUdR(i) * Z + TPBdUdR(i+1) * RR
end subroutine TPBUInt1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Calculation
!---------------------------------------------------------------------------------------------------
real(c_double) function TPBQCalc0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: R
!-------------------------------------------------------------------------------------------
real(c_double) :: Z, t, S
!-------------------------------------------------------------------------------------------
if ( R > TPBRcutoff ) then
TPBQCalc0 = 0.0d+00
else if ( R < TPBQR0 ) then
TPBQCalc0 = 1.0d+00
else
Z = TPBQS / R
Z = Z * Z * Z
Z = Z * Z
TPBQCalc0 = 4.0d+00 * ( 1.0d+00 - Z ) * Z
if ( R > TPBQRcutoff1 ) then
t = ( R - TPBQRcutoff1 ) / TPBQDRcutoff
S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
TPBQCalc0 = TPBQCalc0 * S
endif
endif
end function TPBQCalc0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) function TPBUCalc0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: R
!-------------------------------------------------------------------------------------------
real(c_double) :: Z, t, S
!-------------------------------------------------------------------------------------------
if ( R > TPBRcutoff ) then
TPBUCalc0 = 0.0d+00
else
Z = TPBS / R
Z = Z * Z * Z
Z = Z * Z
TPBUCalc0 = TPBE4 * ( Z - 1.0d+00 ) * Z
if ( R > TPBRcutoff1 ) then
t = ( R - TPBRcutoff1 ) / TPBDRcutoff
S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
TPBUCalc0 = TPBUCalc0 * S
endif
endif
end function TPBUCalc0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPBUCalc1 ( U, dUdR, R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(out) :: U, dUdR
real(c_double), intent(in) :: R
real(c_double) :: Z, t, S, dSdR
!-------------------------------------------------------------------------------------------
if ( R > TPBRcutoff ) then
U = 0.0d+00
dUdR = 0.0d+00
else
Z = TPBS / R
Z = Z * Z * Z
Z = Z * Z
U = TPBE4 * ( Z - 1.0d+00 ) * Z
dUdR = TPBE24 * ( 2.0d+00 * Z - 1.0d+00 ) * Z / R
if ( R > TPBRcutoff1 ) then
t = ( R - TPBRcutoff1 ) / TPBDRcutoff
S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
dSdR = 6.0d+00 * t * ( t - 1.0d+00 ) / TPBDRcutoff
dUdR = dUdR * S + U * dSdR
U = U * S
endif
endif
end subroutine TPBUCalc1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPBSegmentForces ( F1, F2, F, M, Laxis, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(out) :: F1, F2
real(c_double), dimension(0:2), intent(in) :: F, M, Laxis
real(c_double), intent(in) :: L
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2) :: FF, MM, FFF
!-------------------------------------------------------------------------------------------
FF = 0.5d+00 * F
MM = M / L
call V3_V3xxV3 ( FFF, MM, Laxis )
F1 = FF - FFF
F2 = FF + FFF
end subroutine TPBSegmentForces !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Initialization
!---------------------------------------------------------------------------------------------------
subroutine TPBInit () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) :: R
integer(c_int) :: i
!-------------------------------------------------------------------------------------------
TPBE4 = 4.0d+00 * TPBE
TPBE24 = - 24.0d+00 * TPBE
TPBDRcutoff = TPBRcutoff - TPBRcutoff1
TPBQDRcutoff = TPBRcutoff - TPBQRcutoff1
TPBQR0 = TPBQS * 2.0d+00 ** ( 1.0d+00 / 6.0d+00 )
TPBDR = ( TPBRcutoff - TPBRmin ) / ( TPBN - 1 )
R = TPBRmin
do i = 0, TPBN - 1
TPBQ(i) = TPBQCalc0 ( R )
call TPBUCalc1 ( TPBU(i), TPBdUdR(i), R )
R = R + TPBDR
enddo
end subroutine TPBInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TubePotBase !****************************************************************************

1698
lib/mesont/TubePotMono.f90 Normal file

File diff suppressed because it is too large Load Diff

443
lib/mesont/TubePotTrue.f90 Normal file
View File

@ -0,0 +1,443 @@
! ------------ ----------------------------------------------------------
! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
! http://lammps.sandia.gov, Sandia National Laboratories
! Steve Plimpton, sjplimp@sandia.gov
!
! 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 author: Alexey N. Volkov, UA, avolkov1@ua.edu
!-------------------------------------------------------------------------
module TubePotTrue !********************************************************************************
!
! TMD Library: True tubular potential and transfer function
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!---------------------------------------------------------------------------------------------------
!
! This module implements calculation of the true potential and transfer functions for interaction
! between two cylinder segments of nanotubes by direct integration over the surfaces of both
! segments.
!
!***************************************************************************************************
use TPMGeom
use TubePotBase
use iso_c_binding, only : c_int, c_double, c_char
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
integer(c_int), parameter :: TPTNXMAX = 257
integer(c_int), parameter :: TPTNEMAX = 128
!---------------------------------------------------------------------------------------------------
! Types
!---------------------------------------------------------------------------------------------------
type TPTSEG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double) :: X, Y, Z
real(c_double) :: Psi, Theta, Phi ! Euler's angles
real(c_double) :: R ! Segment radius
real(c_double) :: L ! Segment length
integer(c_int) :: NX, NE ! Number of nodes for numerical integration
real(c_double) :: DX, DE ! Spacings
real(c_double), dimension(0:2,0:2) :: M ! Transformation matrix
real(c_double), dimension(0:TPTNXMAX-1,0:TPTNXMAX-1,0:2) :: Rtab! Node coordinates
end type TPTSEG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
type(TPTSEG) :: TPTSeg1, TPTSeg2 ! Two segments
contains !******************************************************************************************
subroutine TPTSegAxisVector ( S, Laxis ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real(c_double), dimension(0:2), intent(out) :: Laxis
!-------------------------------------------------------------------------------------------
Laxis(0:2) = S%M(2,0:2)
end subroutine TPTSegAxisVector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTSegRadVector ( S, Lrad, Eps ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real(c_double), dimension(0:2), intent(out) :: Lrad
real(c_double), intent(in) :: Eps
!-------------------------------------------------------------------------------------------
real(c_double) :: Ce, Se
!-------------------------------------------------------------------------------------------
Ce = cos ( Eps )
Se = sin ( Eps )
Lrad(0) = Ce * S%M(0,0) + Se * S%M(1,0)
Lrad(1) = Ce * S%M(0,1) + Se * S%M(1,1)
Lrad(2) = Ce * S%M(0,2) + Se * S%M(1,2)
end subroutine TPTSegRadVector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTRadiusVector ( S, R, X, Eps ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real(c_double), dimension(0:2), intent(out) :: R
real(c_double), intent(in) :: X, Eps
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2) :: Laxis, Lrad
!-------------------------------------------------------------------------------------------
call TPTSegAxisVector ( S, Laxis )
call TPTSegRadVector ( S, Lrad, Eps )
R(0) = S%X + X * Laxis(0) + S%R * Lrad(0)
R(1) = S%Y + X * Laxis(1) + S%R * Lrad(1)
R(2) = S%Z + X * Laxis(2) + S%R * Lrad(2)
end subroutine TPTRadiusVector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTCalcSegNodeTable ( S ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(inout) :: S
!-------------------------------------------------------------------------------------------
real(c_double) :: X, Eps
integer(c_int) :: i, j
!-------------------------------------------------------------------------------------------
X = - S%L / 2.0
call RotationMatrix3 ( S%M, S%Psi, S%Theta, S%Phi )
do i = 0, S%NX - 1
Eps = 0.0d+00
do j = 0, S%NE - 1
call TPTRadiusVector ( S, S%Rtab(i,j,0:2), X, Eps )
Eps = Eps + S%DE
end do
X = X + S%DX
end do
end subroutine TPTCalcSegNodeTable !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTSetSegPosition1 ( S, Rcenter, Laxis, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(inout) :: S
real(c_double), dimension(0:2), intent(in) :: Rcenter, Laxis
real(c_double), intent(in) :: L
!-------------------------------------------------------------------------------------------
S%L = L
S%DX = L / ( S%NX - 1 )
call EulerAngles ( S%Psi, S%Theta, Laxis )
S%Phi= 0.0d+00
S%X = Rcenter(0)
S%Y = Rcenter(1)
S%Z = Rcenter(2)
call TPTCalcSegNodeTable ( S )
end subroutine TPTSetSegPosition1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTSetSegPosition2 ( S, R1, R2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(inout) :: S
real(c_double), dimension(0:2), intent(in) :: R1, R2
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2) :: R, Laxis
real(c_double) :: L
!-------------------------------------------------------------------------------------------
R = 0.5 * ( R1 + R2 )
Laxis = R2 - R1
L = S_V3norm3 ( Laxis )
Laxis = Laxis / L
call TPTSetSegPosition1 ( S, R, Laxis, L )
end subroutine TPTSetSegPosition2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPTCheckIntersection ( S1, S2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S1, S2
!-------------------------------------------------------------------------------------------
integer(c_int) :: i, j
real(c_double) :: L1, L2, Displacement, D
real(c_double), dimension(0:2) :: Laxis, Q, R
!-------------------------------------------------------------------------------------------
L2 = S1%L / 2.0
L1 = - L2
call TPTSegAxisVector ( S1, Laxis )
R(0) = S1%X
R(1) = S1%Y
R(2) = S1%Z
do i = 0, S2%NX - 1
do j = 0, S2%NE - 1
call LinePoint ( Displacement, Q, R, Laxis, S2%Rtab(i,j,0:2) )
D = sqrt ( sqr ( Q(0) - S2%Rtab(i,j,0) ) + sqr ( Q(1) - S2%Rtab(i,j,1) ) &
+ sqr ( Q(2) - S2%Rtab(i,j,2) ) )
if ( Displacement > L1 .and. Displacement < L2 .and. D < S1%R ) then
TPTCheckIntersection = 1
return
end if
end do
end do
TPTCheckIntersection = 0
end function TPTCheckIntersection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPTCalcPointRange ( S, Xmin, Xmax, Re ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real(c_double), intent(out) :: Xmin, Xmax
real(c_double), dimension(0:2), intent(in) :: Re
!-------------------------------------------------------------------------------------------
real(c_double) :: Displacement, Distance
real(c_double), dimension(0:2) :: Laxis, Q, R
!-------------------------------------------------------------------------------------------
call TPTSegAxisVector ( S, Laxis )
R(0) = S%X
R(1) = S%Y
R(2) = S%Z
call LinePoint ( Displacement, Q, R, Laxis, Re )
Distance = sqrt ( sqr ( Q(0) - Re(0) ) + sqr ( Q(1) - Re(1) ) + sqr ( Q(2) - Re(2) ) ) - S%R
if ( TPBRcutoff < Distance ) then
Xmin = 0.0d+00
Xmax = 0.0d+00
TPTCalcPointRange = 0
return
end if
Distance = sqrt ( TPBRcutoff * TPBRcutoff - Distance * Distance )
Xmin = Displacement - Distance
Xmax = Displacement + Distance
TPTCalcPointRange = 1
end function TPTCalcPointRange !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTGetEnds ( R1_1, R1_2, R2_1, R2_2, X1_1, X1_2, X2_1, X2_2, H, A ) !!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(out) :: R1_1, R1_2, R2_1, R2_2
real(c_double), intent(in) :: X1_1, X1_2, X2_1, X2_2, H, A
!-------------------------------------------------------------------------------------------
R1_1(0) = 0.0d+00
R1_1(1) = 0.0d+00
R1_1(2) = X1_1
R1_2(0) = 0.0d+00
R1_2(1) = 0.0d+00
R1_2(2) = X1_2
R2_1(0) = H
R2_1(1) = - X2_1 * sin ( A )
R2_1(2) = X2_1 * cos ( A )
R2_2(0) = H
R2_2(1) = - X2_2 * sin ( A )
R2_2(2) = X2_2 * cos ( A )
end subroutine TPTGetEnds !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Tubular potential
!---------------------------------------------------------------------------------------------------
integer(c_int) function TPTPointPotential ( Q, U, F, R, S ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns the potential U and force F applied to an atom in position R and
! produced by the segment S.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: Q, U
real(c_double), dimension(0:2), intent(out) :: F
real(c_double), dimension(0:2), intent(in) :: R
type(TPTSEG), intent(in) :: S
!-------------------------------------------------------------------------------------------
integer(c_int) :: i, j
real(c_double), dimension(0:2) :: RR, FF
real(c_double) :: QQ, UU, UUU, FFF, Rabs
real(c_double) :: Coeff, Xmin, Xmax, X
!-------------------------------------------------------------------------------------------
TPTPointPotential = 0
Q = 0.0d+00
U = 0.0d+00
F = 0.0d+00
if ( TPTCalcPointRange ( S, Xmin, Xmax, R ) == 0 ) return
X = - S%L / 2.0
do i = 0, S%NX - 1
if ( X > Xmin .and. X < Xmax ) then
QQ = 0.0d+00
UU = 0.0d+00
FF = 0.0d+00
do j = 0, S%NE - 1
RR(0:2) = S%Rtab(i,j,0:2) - R(0:2)
Rabs = S_V3norm3 ( RR )
if ( Rabs < TPBRcutoff ) then
QQ = QQ + TPBQCalc0 ( Rabs )
call TPBUCalc1 ( UUU, FFF, Rabs )
UU = UU + UUU
FFF = FFF / Rabs
FF = FF + FFF * RR
TPTPointPotential = 1
end if
end do
if ( i == 0 .or. i == S%NX - 1 ) then
Q = Q + 0.5d+00 * QQ
U = U + 0.5d+00 * UU
F = F + 0.5d+00 * FF
else
Q = Q + QQ
U = U + UU
F = F + FF
end if
end if
X = X + S%DX
end do
Coeff = TPBD * S%DX * S%R * S%DE
Q = Q * S%DX * S%R * S%DE
U = U * Coeff
F = F * Coeff
end function TPTPointPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPTSectionPotential ( Q, U, F, M, S, i, Ssource ) !!!!!!!!!!!!!!!!!!
! This function returns the potential U, force F and torque M produced by the segment Ssource
! and applied to the i-th circular cross-section of the segment S.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: Q, U
real(c_double), dimension(0:2), intent(out) :: F, M
type(TPTSEG), intent(in) :: S, Ssource
integer(c_int), intent(in) :: i
!-------------------------------------------------------------------------------------------
integer(c_int) :: j
real(c_double), dimension(0:2) :: R, Fp, Mp, Lrad
real(c_double) :: Qp, Up, Eps
real(c_double) :: Coeff
!-------------------------------------------------------------------------------------------
TPTSectionPotential = 0
Q = 0.0d+00
U = 0.0d+00
F = 0.0d+00
M = 0.0d+00
Eps = 0.0d+00
do j = 0, S%NE - 1
call TPTSegRadVector ( S, Lrad, Eps )
if ( TPTPointPotential ( Qp, Up, Fp, S%Rtab(i,j,0:2), Ssource ) == 1 ) then
Q = Q + Qp
U = U + Up
F = F + Fp
R(0) = S%Rtab(i,j,0) - S%X
R(1) = S%Rtab(i,j,1) - S%Y
R(2) = S%Rtab(i,j,2) - S%Z
call V3_V3xxV3 ( Mp, R, Fp )
M = M + Mp
TPTSectionPotential = 1
end if
Eps = Eps + S%DE
end do
Coeff = TPBD * S%R * S%DE
Q = Q * S%R * S%DE
U = U * Coeff
F = F * Coeff
M = M * Coeff
end function TPTSectionPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPTSegmentPotential ( Q, U, F, M, S, Ssource ) !!!!!!!!!!!!!!!!!!!!!!
! This function returns the potential U, force F and torque M produced by the segment
! Ssource and applied to the segment S.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: Q, U
real(c_double), dimension(0:2), intent(out) :: F, M
type(TPTSEG), intent(in) :: S, Ssource
integer(c_int) :: i
real(c_double), dimension(0:2) :: Fc, Mc
real(c_double) :: Qc, Uc
!-------------------------------------------------------------------------------------------
TPTSegmentPotential = 0
Q = 0.0d+00
U = 0.0d+00
F = 0.0d+00
M = 0.0d+00
if ( TPTCheckIntersection ( S, Ssource ) == 1 ) then
TPTSegmentPotential = 2
return
end if
do i = 0, S%NX - 1
if ( TPTSectionPotential ( Qc, Uc, Fc, Mc, S, i, Ssource ) == 1 ) then
if ( i == 0 .or. i == S%NX - 1 ) then
Q = Q + 0.5d+00 * Qc
U = U + 0.5d+00 * Uc
F = F + 0.5d+00 * Fc
M = M + 0.5d+00 * Mc
else
Q = Q + Qc
U = U + Uc
F = F + Fc
M = M + Mc
end if
TPTSegmentPotential = 1
end if
end do
Q = Q * S%DX
U = U * S%DX
F = F * S%DX
M = M * S%DX
end function TPTSegmentPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Forces
!---------------------------------------------------------------------------------------------------
subroutine TPTSegmentForces ( F1, F2, F, M, Laxis, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), dimension(0:2), intent(out) :: F1, F2
real(c_double), dimension(0:2), intent(in) :: F, M, Laxis
real(c_double), intent(in) :: L
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2) :: MM, FF, FFF
!-------------------------------------------------------------------------------------------
FF = 0.5d+00 * F
MM = M / L
call V3_V3xxV3 ( FFF, MM, Laxis )
F1 = FF - FFF
F2 = FF + FFF
end subroutine TPTSegmentForces !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer(c_int) function TPTInteractionF ( Q, U, F1_1, F1_2, F2_1, F2_2, R1_1, R1_2, R2_1, R2_2 )
! This function returns the potential and forces applied to the ends of segments.
!-------------------------------------------------------------------------------------------
real(c_double), intent(out) :: Q, U
real(c_double), dimension(0:2), intent(out) :: F1_1, F1_2, F2_1, F2_2
real(c_double), dimension(0:2), intent(in) :: R1_1, R1_2, R2_1, R2_2
!-------------------------------------------------------------------------------------------
real(c_double), dimension(0:2) :: R1, R2, Laxis1, Laxis2, DR, F1, M1, F2, M2
real(c_double) :: L1, L2
!-------------------------------------------------------------------------------------------
R1 = 0.5 * ( R1_1 + R1_2 )
R2 = 0.5 * ( R2_1 + R2_2 )
Laxis1 = R1_2 - R1_1
Laxis2 = R2_2 - R2_1
L1 = S_V3norm3 ( Laxis1 )
L2 = S_V3norm3 ( Laxis2 )
Laxis1 = Laxis1 / L1
Laxis2 = Laxis2 / L2
DR = R2 - R1
call TPTSetSegPosition1 ( TPTSeg1, R1, Laxis1, L1 )
call TPTSetSegPosition1 ( TPTSeg2, R2, Laxis2, L2 )
TPTInteractionF = TPTSegmentPotential ( Q, U, F1, M1, TPTSeg1, TPTSeg2 )
if ( TPTInteractionF .ne. 1 ) return
call V3_V3xxV3 ( M2, DR, F1 )
F2 = - F1
M2 = - M1 - M2
call TPTSegmentForces ( F1_1, F1_2, F1, M1, Laxis1, L1 )
call TPTSegmentForces ( F2_1, F2_2, F2, M2, Laxis2, L2 )
end function TPTInteractionF !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Initialization
!---------------------------------------------------------------------------------------------------
subroutine TPTInit ( R1, R2, NX, NE ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real(c_double), intent(in) :: R1, R2
integer(c_int), intent(in) :: NX, NE
!-------------------------------------------------------------------------------------------
TPTSeg1%X = 0.0d+00
TPTSeg1%Y = 0.0d+00
TPTSeg1%Z = 0.0d+00
TPTSeg1%Psi = 0.0d+00
TPTSeg1%Theta = 0.0d+00
TPTSeg1%Phi = 0.0d+00
TPTSeg1%R = R1
TPTSeg1%NX = NX
TPTSeg1%NE = NE
TPTSeg1%DE = M_2PI / NE
TPTSeg2%X = 0.0d+00
TPTSeg2%Y = 0.0d+00
TPTSeg2%Z = 0.0d+00
TPTSeg2%Psi = 0.0d+00
TPTSeg2%Theta = 0.0d+00
TPTSeg2%Phi = 0.0d+00
TPTSeg2%R = R2
TPTSeg2%NX = NX
TPTSeg2%NE = NE
TPTSeg2%DE = M_2PI / NE
end subroutine TPTInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TubePotTrue !****************************************************************************

View File

@ -1 +1,2 @@
C_10_10.mesocnt
TABTP_10_10.mesont

696476
potentials/TABTP_10_10.mesont Normal file

File diff suppressed because it is too large Load Diff

8
src/.gitignore vendored
View File

@ -197,6 +197,14 @@
/pair_spin_neel.cpp
/pair_spin_neel.h
/atom_vec_mesont.cpp
/atom_vec_mesont.h
/compute_mesont.cpp
/compute_mesont.h
/export_mesont.h
/pair_mesont_tpm.cpp
/pair_mesont_tpm.h
/angle_cg_cmm.cpp
/angle_cg_cmm.h
/angle_charmm.cpp

View File

@ -14,7 +14,7 @@ SHLIB = liblammps_$@.so
ARLINK = liblammps.a
SHLINK = liblammps.so
TMPNAME= tmp_$@_name
LMPLINK=$(shell echo $(ARLIB) | sed -e 's,lib\([+0-9a-z_-]\+\)\.a$$,-L. -l\1,')
LMPLINK= -L. -llammps_$@
OBJDIR = Obj_$@
OBJSHDIR = Obj_shared_$@
@ -63,11 +63,11 @@ PACKLIB = compress gpu kim kokkos latte message mpiio mscg poems \
python voronoi \
user-adios user-atc user-awpmd user-colvars user-h5md user-lb user-molfile \
user-netcdf user-plumed user-qmmm user-quip user-scafacos \
user-smd user-vtk
user-smd user-vtk user-mesont
PACKSYS = compress mpiio python user-lb
PACKINT = gpu kokkos message poems user-atc user-awpmd user-colvars
PACKINT = gpu kokkos message poems user-atc user-awpmd user-colvars user-mesont
PACKEXT = kim latte mscg voronoi \
user-adios user-h5md user-molfile user-netcdf user-plumed user-qmmm user-quip \
@ -75,13 +75,18 @@ PACKEXT = kim latte mscg voronoi \
PACKALL = $(PACKAGE) $(PACKUSER)
PACKAGEUC = $(shell echo $(PACKAGE) | tr a-z A-Z)
PACKUSERUC = $(shell echo $(PACKUSER) | tr a-z A-Z)
# Helper GNU make function for conversion to upper case without using shell commands
uppercase_TABLE:=a,A b,B c,C d,D e,E f,F g,G h,H i,I j,J k,K l,L m,M n,N o,O p,P q,Q r,R s,S t,T u,U v,V w,W x,X y,Y z,Z
uppercase_internal=$(if $1,$$(subst $(firstword $1),$(call uppercase_internal,$(wordlist 2,$(words $1),$1),$2)),$2)
uppercase=$(eval uppercase_RESULT:=$(call uppercase_internal,$(uppercase_TABLE),$1))$(uppercase_RESULT)
YESDIR = $(shell echo $(@:yes-%=%) | tr a-z A-Z)
NODIR = $(shell echo $(@:no-%=%) | tr a-z A-Z)
LIBDIR = $(shell echo $(@:lib-%=%))
LIBUSERDIR = $(shell echo $(@:lib-user-%=%))
PACKAGEUC = $(call uppercase,$(PACKAGE))
PACKUSERUC = $(call uppercase,$(PACKUSER))
YESDIR = $(call uppercase,$(@:yes-%=%))
NODIR = $(call uppercase,$(@:no-%=%))
LIBDIR = $($(@:lib-%=%))
LIBUSERDIR = $($(@:lib-user-%=%))
# List of all targets

View File

@ -0,0 +1,67 @@
# Install/unInstall package files in LAMMPS
# mode = 0/1/2 for uninstall/install/update
mode=$1
# enforce using portable C locale
LC_ALL=C
export LC_ALL
# arg1 = file, arg2 = file it depends on
action () {
if (test $mode = 0) then
rm -f ../$1
elif (! cmp -s $1 ../$1) then
if (test -z "$2" || test -e ../$2) then
cp $1 ..
if (test $mode = 2) then
echo " updating src/$1"
fi
fi
elif (test -n "$2") then
if (test ! -e ../$2) then
rm -f ../$1
fi
fi
}
# all package files with no dependencies
for file in *.cpp *.h; do
test -f ${file} && action $file
done
# edit 2 Makefile.package files to include/exclude package info
if (test $1 = 1) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*mesont[^ \t]* //' ../Makefile.package
sed -i -e 's|^PKG_INC =[ \t]*|&-I../../lib/mesont |' ../Makefile.package
sed -i -e 's|^PKG_PATH =[ \t]*|&-L../../lib/mesont |' ../Makefile.package
sed -i -e 's|^PKG_LIB =[ \t]*|&-lmesont |' ../Makefile.package
sed -i -e 's|^PKG_SYSINC =[ \t]*|&$(mesont_SYSINC) |' ../Makefile.package
sed -i -e 's|^PKG_SYSLIB =[ \t]*|&$(mesont_SYSLIB) |' ../Makefile.package
sed -i -e 's|^PKG_SYSPATH =[ \t]*|&$(mesont_SYSPATH) |' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^include.*mesont.*$/d' ../Makefile.package.settings
# multiline form needed for BSD sed on Macs
sed -i -e '4 i \
include ..\/..\/lib\/mesont\/Makefile.lammps
' ../Makefile.package.settings
fi
elif (test $1 = 0) then
if (test -e ../Makefile.package) then
sed -i -e 's/[^ \t]*mesont[^ \t]* //' ../Makefile.package
fi
if (test -e ../Makefile.package.settings) then
sed -i -e '/^include.*mesont.*$/d' ../Makefile.package.settings
fi
fi

89
src/USER-MESONT/README Normal file
View File

@ -0,0 +1,89 @@
USER-MESONT is a LAMMPS package for simulation of nanomechanics of carbon
nanotubes (CNTs). The model is based on a coarse-grained representation
of CNTs as "flexible cylinders" consisting of a variable number of
segments. Internal interactions within a CNT and the van der Waals
interaction between the tubes are described by a mesoscopic force
field designed and parameterized based on the results of atomic-level
molecular dynamics simulations. The description of the force field
is provided in the papers listed below.
--
This package was created by Maxim Shugaev (mvs9t@virginia.edu)
at the University of Virginia.
The Fortran library implementing basic level functions describing stretching,
bending, and intertube components of the mesoscopic CNT force field, used
by this package is developed by Alexey N. Volkov (avolkov1@ua.edu)
at the University of Alabama.
--
The following commands are contained in this package:
atom_style mesont
This command enables mesont atom_style containing variables used for
further commands in USER-MESONT.
pair_style mesont/tpm cut table_path BendingMode TPMType
This command activates a pair_style describing CNT mesoscopic tubular
potential model (TPM) force field. "cut" is cutoff distance that should
be set to be at least max(2.0*L, sqrt(L^2/2 + (2.0*R + Tcut)^2)),
where L is the maximum segment length, R is the maximum tube radius,
and Tcut = 10.2 A is the maximum distance between surfaces of interacting
segments. However, the recommended cutoff is 3L.
compute mesont
This command allows evaluation of per atom and total values of stretching,
bending, and intertube interaction components of energies. Use the following
flags: 'estretch', 'ebend', 'etube'.
--
References:
L. V. Zhigilei, C. Wei, and D. Srivastava, Mesoscopic model for dynamic
simulations of carbon nanotubes, Phys. Rev. B 71, 165417, 2005.
A. N. Volkov and L. V. Zhigilei, Structural stability of carbon nanotube
films: The role of bending buckling, ACS Nano 4, 6187-6195, 2010.
A. N. Volkov, K. R. Simov, and L. V. Zhigilei, Mesoscopic model for simulation
of CNT-based materials, Proceedings of the ASME International Mechanical
Engineering Congress and Exposition (IMECE2008), ASME paper IMECE2008-68021,
2008.
A. N. Volkov and L. V. Zhigilei, Mesoscopic interaction potential for carbon
nanotubes of arbitrary length and orientation, J. Phys. Chem. C 114, 5513-5531,
2010.
B. K. Wittmaack, A. H. Banna, A. N. Volkov, L. V. Zhigilei, Mesoscopic
modeling of structural self-organization of carbon nanotubes into vertically
aligned networks of nanotube bundles, Carbon 130, 69-86, 2018.
B. K. Wittmaack, A. N. Volkov, L. V. Zhigilei, Mesoscopic modeling of the
uniaxial compression and recovery of vertically aligned carbon nanotube
forests, Compos. Sci. Technol. 166, 66-85, 2018.
B. K. Wittmaack, A. N. Volkov, L. V. Zhigilei, Phase transformation as the
mechanism of mechanical deformation of vertically aligned carbon nanotube
arrays: Insights from mesoscopic modeling, Carbon 143, 587-597, 2019.
A. N. Volkov and L. V. Zhigilei, Scaling laws and mesoscopic modeling of
thermal conductivity in carbon nanotube materials, Phys. Rev. Lett. 104,
215902, 2010.
A. N. Volkov, T. Shiga, D. Nicholson, J. Shiomi, and L. V. Zhigilei, Effect
of bending buckling of carbon nanotubes on thermal conductivity of carbon
nanotube materials, J. Appl. Phys. 111, 053501, 2012.
A. N. Volkov and L. V. Zhigilei, Heat conduction in carbon nanotube materials:
Strong effect of intrinsic thermal conductivity of carbon nanotubes, Appl.
Phys. Lett. 101, 043113, 2012.
W. M. Jacobs, D. A. Nicholson, H. Zemer, A. N. Volkov, and L. V. Zhigilei,
Acoustic energy dissipation and thermalization in carbon nanotubes: Atomistic
modeling and mesoscopic description, Phys. Rev. B 86, 165414, 2012.
A. N. Volkov and A. H. Banna, Mesoscopic computational model of covalent
cross-links and mechanisms of load transfer in cross-linked carbon nanotube
films with continuous networks of bundles, Comp. Mater. Sci. 176, 109410, 2020.

View File

@ -0,0 +1,49 @@
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#include "atom_vec_mesont.h"
#include "atom.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
AtomVecMesoNT::AtomVecMesoNT(LAMMPS *lmp) : AtomVec(lmp)
{
molecular = 0;
mass_type = 1;
atom->mesont_flag = 1;
// strings with peratom variables to include in each AtomVec method
// strings cannot contain fields in corresponding AtomVec default strings
// order of fields in a string does not matter
// except: fields_data_atom & fields_data_vel must match data file
fields_grow = (char *) "rmass radius length buckling bond_nt molecule";
fields_copy = (char *) "rmass radius length buckling bond_nt molecule";
fields_comm = (char *) "";
fields_comm_vel = (char *) "";
fields_reverse = (char *) "";
fields_border = (char *) "rmass radius length buckling bond_nt molecule";
fields_border_vel = (char *) "rmass radius length buckling bond_nt molecule";
fields_exchange = (char *) "rmass radius length buckling bond_nt molecule";
fields_restart = (char *) "rmass radius length buckling bond_nt molecule";
fields_create = (char *) "rmass radius length buckling bond_nt molecule";
fields_data_atom = (char *) "id molecule type bond_nt rmass radius length buckling x";
fields_data_vel = (char *) "id v";
setup_fields();
}

View File

@ -0,0 +1,41 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#ifdef ATOM_CLASS
AtomStyle(mesont,AtomVecMesoNT)
#else
#ifndef LMP_ATOM_VEC_MESONT_H
#define LMP_ATOM_VEC_MESONT_H
#include "atom_vec.h"
namespace LAMMPS_NS {
class AtomVecMesoNT : public AtomVec {
public:
AtomVecMesoNT(class LAMMPS *);
};
}
#endif
#endif
/* ERROR/WARNING messages:
*/

View File

@ -0,0 +1,156 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#include "compute_mesont.h"
#include <cstring>
#include "atom.h"
#include "update.h"
#include "comm.h"
#include "force.h"
#include "modify.h"
#include "memory.h"
#include "error.h"
#include "pair.h"
#include <string>
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
ComputeMesoNT::ComputeMesoNT(LAMMPS *lmp, int narg, char **arg) :
Compute(lmp, narg, arg), energy(NULL) {
if (narg != 4) error->all(FLERR,"Illegal compute mesont command");
std::string ctype = arg[3];
if (ctype == "estretch") compute_type = ES;
else if (ctype == "ebend") compute_type = EB;
else if (ctype == "etube") compute_type = ET;
else error->all(FLERR,"Illegal compute mesont command");
peratom_flag = 1;
size_peratom_cols = 0;
peatomflag = 1;
timeflag = 1;
comm_reverse = 1;
extscalar = 1;
scalar_flag = 1;
nmax = 0;
}
/* ---------------------------------------------------------------------- */
ComputeMesoNT::~ComputeMesoNT() {
memory->destroy(energy);
}
/* ---------------------------------------------------------------------- */
double ComputeMesoNT::compute_scalar() {
invoked_scalar = update->ntimestep;
if (update->eflag_global != invoked_scalar)
error->all(FLERR,"Energy was not tallied on needed timestep");
int i;
double* ptr = NULL;
if (compute_type == ES)
ptr = static_cast<double*>(force->pair->extract("mesonttpm_Es_tot",i));
else if (compute_type == EB)
ptr = static_cast<double*>(force->pair->extract("mesonttpm_Eb_tot",i));
else if (compute_type == ET)
ptr = static_cast<double*>(force->pair->extract("mesonttpm_Et_tot",i));
else error->all(FLERR,"Illegal compute mesont command");
if (!ptr) error->all(FLERR,
"compute mesont is allowed only with mesont/tpm pair style");
MPI_Allreduce(ptr,&scalar,1,MPI_DOUBLE,MPI_SUM,world);
return scalar;
}
/* ---------------------------------------------------------------------- */
void ComputeMesoNT::compute_peratom() {
invoked_peratom = update->ntimestep;
if (update->eflag_atom != invoked_peratom)
error->all(FLERR,"Per-atom energy was not tallied on needed timestep");
// grow local energy array if necessary
// needs to be atom->nmax in length
if (atom->nmax > nmax) {
memory->destroy(energy);
nmax = atom->nmax;
memory->create(energy,nmax,"mesont_Eb:energy");
vector_atom = energy;
}
// npair includes ghosts if newton_bond is set
// ntotal includes ghosts if either newton flag is set
int nlocal = atom->nlocal;
int npair = nlocal;
if (force->newton) npair += atom->nghost;
int ntotal = nlocal;
if (force->newton) ntotal += atom->nghost;
int i;
// clear local energy array
for (int i = 0; i < ntotal; i++) energy[i] = 0.0;
double* ptr = NULL;
if (compute_type == ES)
ptr = static_cast<double*>(force->pair->extract("mesonttpm_Es",i));
else if (compute_type == EB)
ptr = static_cast<double*>(force->pair->extract("mesonttpm_Eb",i));
else if (compute_type == ET)
ptr = static_cast<double*>(force->pair->extract("mesonttpm_Et",i));
else error->all(FLERR,"Illegal compute mesont command");
if (ptr) for (i = 0; i < npair; i++) energy[i] += ptr[i];
else error->all(FLERR,
"compute mesont is allowed only with mesont/tpm pair style");
// communicate ghost energy between neighbor procs
if (force->newton) comm->reverse_comm_compute(this);
// zero energy of atoms not in group
// only do this after comm since ghost contributions must be included
int *mask = atom->mask;
for (int i = 0; i < nlocal; i++)
if (!(mask[i] & groupbit)) energy[i] = 0.0;
}
/* ---------------------------------------------------------------------- */
int ComputeMesoNT::pack_reverse_comm(int n, int first, double *buf) {
int m = 0;
int last = first + n;
for (int i = first; i < last; i++) buf[m++] = energy[i];
return m;
}
/* ---------------------------------------------------------------------- */
void ComputeMesoNT::unpack_reverse_comm(int n, int *list, double *buf) {
int m = 0;
for (int i = 0; i < n; i++) {
int j = list[i];
energy[j] += buf[m++];
}
}
/* ----------------------------------------------------------------------
memory usage of local atom-based array
------------------------------------------------------------------------- */
double ComputeMesoNT::memory_usage() {
double bytes = nmax * sizeof(double);
return bytes;
}

View File

@ -0,0 +1,67 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
ComputeStyle(mesont,ComputeMesoNT)
#else
#ifndef LMP_COMPUTE_MESONT_ATOM_H
#define LMP_COMPUTE_MESONT_ATOM_H
#include "compute.h"
namespace LAMMPS_NS {
class ComputeMesoNT : public Compute {
public:
ComputeMesoNT(class LAMMPS *, int, char **);
~ComputeMesoNT();
void init() {}
void compute_peratom();
double compute_scalar();
int pack_reverse_comm(int, int, double *);
void unpack_reverse_comm(int, int *, double *);
double memory_usage();
private:
int nmax;
double *energy;
enum ComputeType {ES, EB, ET};
ComputeType compute_type;
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Illegal compute mesont command
Incorrect argument list in the compute init.
E: Per-atom energy was not tallied on needed timestep
UNSPECIFIED.
E: compute mesont is allowed only with mesont/tpm pair style
Use mesont pair style.
*/

View File

@ -0,0 +1,47 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
// see ExportCNT.f90 in lib/mesont for function details
void mesont_lib_TPBInit();
void mesont_lib_TPMInit(const int& M, const int& N);
void mesont_lib_SetTablePath(const char* TPMFile, const int& N);
void mesont_lib_InitCNTPotModule(const int& STRModel, const int& STRParams,
const int& YMType, const int& BNDModel, const double& Rref);
double mesont_lib_get_R();
void mesont_lib_TubeStretchingForceField(double& U1, double& U2, double* F1,
double* F2, double* S1, double* S2, const double* X1, const double* X2,
const double& R12, const double& L12);
void mesont_lib_TubeBendingForceField(double& U1, double& U2, double& U3,
double* F1, double* F2, double* F3, double* S1, double* S2, double* S3,
const double* X1, const double* X2, const double* X3, const double& R123,
const double& L123, int& BBF2 );
void mesont_lib_SegmentTubeForceField(double& U1, double& U2, double *U,
double* F1, double* F2, double* F, double* Fe, double* S1, double* S2,
double* S, double* Se, const double* X1, const double* X2,
const double& R12, const int& N, const double* X, const double* Xe,
const int* BBF, const double& R, const int& E1, const int& E2,
const int& Ee, const int& TPMType);
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,797 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#include "pair_mesont_tpm.h"
#include "export_mesont.h"
#include <mpi.h>
#include "atom.h"
#include "comm.h"
#include "force.h"
#include "memory.h"
#include "error.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include <cstring>
#include <vector>
#include <cmath>
#include <string>
#include <fstream>
#include <sstream>
#include <algorithm>
using namespace LAMMPS_NS;
//since LAMMPS is compiled with C++ 2003, define a substitution for std::array
template<typename T, int N>
class array2003{
public:
T& operator[] (int idx){ return data[idx];};
const T& operator[] (int idx) const{ return data[idx];};
private:
T data[N];
};
class MESONTList {
public:
MESONTList(const Atom* atom, const NeighList* nblist, double rc2);
~MESONTList() {};
//list of segments
const std::vector<array2003<int,2> >& get_segments() const;
//list of triplets
const std::vector<array2003<int,3> >& get_triplets() const;
//list of neighbor chains [start,end] for segments
//(use idx() to get real indexes)
const std::vector<std::vector<array2003<int,2> > >& get_nbs() const;
//convert idx from sorted representation to real idx
int get_idx(int idx) const;
//return list of indexes for conversion from sorted representation
const std::vector<int>& get_idx_list() const;
//convert idx from real idx to sorted representation
int get_idxb(int idx) const;
//return list of indexes for conversion to sorted representation
const std::vector<int>& get_idxb_list() const;
//check if the node is the end of the tube
bool is_end(int idx) const;
array2003<int, 2> get_segment(int idx) const;
array2003<int, 3> get_triplet(int idx) const;
static const int cnt_end = -1;
static const int domain_end = -2;
static const int not_cnt = -3;
private:
std::vector<array2003<int, 2> > chain_list, segments;
std::vector<array2003<int, 3> > triplets;
std::vector<std::vector<array2003<int, 2> > > nb_chains;
std::vector<int> index_list, index_list_b;
};
//=============================================================================
inline const std::vector<std::vector<array2003<int, 2> > > &
MESONTList::get_nbs() const {
return nb_chains;
}
inline int MESONTList::get_idx(int idx) const {
return index_list[idx];
}
inline const std::vector<int>& MESONTList::get_idx_list() const {
return index_list;
};
inline int MESONTList::get_idxb(int idx) const {
return index_list_b[idx];
}
inline const std::vector<int>& MESONTList::get_idxb_list() const {
return index_list_b;
};
inline const std::vector<array2003<int, 2> > & MESONTList::get_segments()
const {
return segments;
}
inline const std::vector<array2003<int, 3> > & MESONTList::get_triplets()
const {
return triplets;
}
inline array2003<int, 2> MESONTList::get_segment(int idx) const {
array2003<int, 2> result;
result[0] = chain_list[idx][0];
result[1] = idx;
return result;
}
inline array2003<int, 3> MESONTList::get_triplet(int idx) const {
array2003<int, 3> result;
result[0] = chain_list[idx][0];
result[1] = idx;
result[2] = chain_list[idx][1];
return result;
}
inline bool MESONTList::is_end(int idx) const {
return chain_list[idx][0] == cnt_end || chain_list[idx][1] == cnt_end;
};
template<typename T>
void vector_union(std::vector<T>& v1, std::vector<T>& v2,
std::vector<T>& merged) {
std::sort(v1.begin(), v1.end());
std::sort(v2.begin(), v2.end());
merged.reserve(v1.size() + v2.size());
typename std::vector<T>::iterator it1 = v1.begin();
typename std::vector<T>::iterator it2 = v2.begin();
while (it1 != v1.end() && it2 != v2.end()) {
if (*it1 < *it2) {
if (merged.empty() || merged.back() < *it1) merged.push_back(*it1);
++it1;
}
else {
if (merged.empty() || merged.back() < *it2) merged.push_back(*it2);
++it2;
}
}
while (it1 != v1.end()) {
if (merged.empty() || merged.back() < *it1) merged.push_back(*it1);
++it1;
}
while (it2 != v2.end()) {
if (merged.empty() || merged.back() < *it2) merged.push_back(*it2);
++it2;
}
}
MESONTList::MESONTList(const Atom* atom, const NeighList* nblist, double /* rc2 */){
if (atom == NULL || nblist == NULL) return;
//number of local atoms at the node
int nlocal = atom->nlocal;
//total number of atoms in the node and ghost shell
int nall = nblist->inum + nblist->gnum;
int ntot = atom->nlocal + atom->nghost;
tagint* const g_id = atom->tag;
tagint** const bonds = atom->bond_nt;
tagint* const chain_id = atom->molecule;
int* ilist = nblist->ilist;
//convert bonds to local id representation
array2003<int, 2> tmp_arr;
tmp_arr[0] = not_cnt; tmp_arr[1] = not_cnt;
chain_list.resize(ntot, tmp_arr);
for (int ii = 0; ii < nall; ii++) {
int i = ilist[ii];
chain_list[i][0] = domain_end;
chain_list[i][1] = domain_end;
}
for (int ii = 0; ii < nall; ii++) {
int i = ilist[ii];
int nnb = nblist->numneigh[i];
for (int m = 0; m < 2; m++)
if (bonds[i][m] == cnt_end) chain_list[i][m] = cnt_end;
for (int j = 0; j < nnb; j++) {
int nb = nblist->firstneigh[i][j];
if (bonds[i][0] == g_id[nb]){
chain_list[i][0] = nb;
chain_list[nb][1] = i;
break;
}
}
}
//reorder chains: index list
//list of indexes for conversion FROM reordered representation
index_list.reserve(nall);
index_list_b.resize(ntot, -1); // convert index TO reordered representation
for (int i = 0; i < ntot; i++) {
if (chain_list[i][0] == cnt_end || chain_list[i][0] == domain_end) {
index_list.push_back(i);
index_list_b[i] = index_list.size() - 1;
int idx = i;
while (1) {
idx = chain_list[idx][1];
if (idx == cnt_end || idx == domain_end) break;
else index_list.push_back(idx);
index_list_b[idx] = index_list.size() - 1;
}
}
}
//segment list
for (int i = 0; i < nlocal; i++) {
if (chain_list[i][0] == not_cnt) continue;
if (chain_list[i][0] != cnt_end && chain_list[i][0] != domain_end &&
g_id[i] < g_id[chain_list[i][0]]){
array2003<int, 2> tmp_c;
tmp_c[0] = i; tmp_c[1] = chain_list[i][0];
segments.push_back(tmp_c);
}
if (chain_list[i][1] != cnt_end && chain_list[i][1] != domain_end &&
g_id[i] < g_id[chain_list[i][1]]){
array2003<int, 2> tmp_c;
tmp_c[0] = i; tmp_c[1] = chain_list[i][1];
segments.push_back(tmp_c);
}
}
int nbonds = segments.size();
//triplets
for (int i = 0; i < nlocal; i++){
if (chain_list[i][0] == not_cnt) continue;
if (chain_list[i][0] != cnt_end && chain_list[i][0] != domain_end &&
chain_list[i][1] != cnt_end && chain_list[i][1] != domain_end)
triplets.push_back(get_triplet(i));
}
//segment neighbor list
nb_chains.resize(nbonds);
std::vector<int> nb_list_i[2], nb_list;
for (int i = 0; i < nbonds; i++) {
//union of nb lists
for (int m = 0; m < 2; m++) {
nb_list_i[m].resize(0);
int idx = segments[i][m];
if (idx >= nlocal) continue;
int nnb = nblist->numneigh[idx];
for (int j = 0; j < nnb; j++) {
int jdx = nblist->firstneigh[idx][j];
//no self interactions for nbs within the same tube
if (chain_id[jdx] == chain_id[idx] &&
std::abs(index_list_b[idx] - index_list_b[jdx]) <= 5) continue;
nb_list_i[m].push_back(index_list_b[jdx]);
}
}
vector_union(nb_list_i[0], nb_list_i[1], nb_list);
int nnb = nb_list.size();
if (nnb > 0) {
int idx_s = nb_list[0];
for (int j = 0; j < nnb; j++) {
//if nodes are not continuous in the sorted representation
//or represent chain ends, create a new neighbor chain
int idx_next = chain_list[index_list[nb_list[j]]][1];
if ((j == nnb - 1) || (nb_list[j] + 1 != nb_list[j+1]) ||
(idx_next == cnt_end) || (idx_next == domain_end)) {
array2003<int, 2> chain;
chain[0] = idx_s;
chain[1] = nb_list[j];
//make sure that segments having at least one node
//in the neighbor list are included
int idx0 = index_list[chain[0]]; // real id of the ends
int idx1 = index_list[chain[1]];
if (chain_list[idx0][0] != cnt_end &&
chain_list[idx0][0] != domain_end) chain[0] -= 1;
if (chain_list[idx1][1] != cnt_end &&
chain_list[idx1][1] != domain_end) chain[1] += 1;
if(chain[0] != chain[1]) nb_chains[i].push_back(chain);
idx_s = (j == nnb - 1) ? -1 : nb_list[j + 1];
}
}
}
nb_list.resize(0);
}
}
/* ---------------------------------------------------------------------- */
// the cutoff distance between walls of tubes
static const double TPBRcutoff = 3.0*3.4;
int PairMESONTTPM::instance_count = 0;
/* ---------------------------------------------------------------------- */
PairMESONTTPM::PairMESONTTPM(LAMMPS *lmp) : Pair(lmp) {
writedata=1;
BendingMode = 0; // Harmonic bending model
TPMType = 0; // Inter-tube segment-segment interaction
tab_path = NULL;
tab_path_length = 0;
eatom_s = NULL;
eatom_b = NULL;
eatom_t = NULL;
instance_count++;
if(instance_count > 1) error->all(FLERR,
"only a single instance of mesont/tpm pair style can be created");
}
/* ---------------------------------------------------------------------- */
PairMESONTTPM::~PairMESONTTPM()
{
if (allocated) {
memory->destroy(setflag);
memory->destroy(cutsq);
memory->destroy(cut);
memory->destroy(eatom_s);
memory->destroy(eatom_b);
memory->destroy(eatom_t);
}
instance_count--;
if (tab_path != NULL) memory->destroy(tab_path);
}
/* ---------------------------------------------------------------------- */
void PairMESONTTPM::compute(int eflag, int vflag){
ev_init(eflag,vflag);
//total number of atoms in the node and ghost shell
int nall = list->inum + list->gnum;
int ntot = atom->nlocal + atom->nghost;
int newton_pair = force->newton_pair;
if(!newton_pair)
error->all(FLERR,"Pair style mesont/tpm requires newton pair on");
double **x = atom->x;
double **f = atom->f;
double *r = atom->radius;
double *l = atom->length;
int *buckling = atom->buckling;
tagint *g_id = atom->tag;
//check if cutoff is chosen correctly
double RT = mesont_lib_get_R();
double Lmax = 0.0;
for (int ii = 0; ii < list->inum; ii++) {
int i = list->ilist[ii];
if (Lmax < l[i]) Lmax = l[i];
}
double Rcut_min = std::max(2.0*Lmax, std::sqrt(0.5*Lmax*Lmax +
std::pow((2.0*RT + TPBRcutoff),2)));
if (cut_global < Rcut_min){
std::stringstream err;
err << "The selected cutoff is too small for the current system : " <<
"L_max = " << Lmax << ", R_max = " << RT << ", Rc = " << cut_global <<
", Rcut_min = " << Rcut_min;
error->all(FLERR, err.str().c_str());
}
//generate bonds and chain nblist
MESONTList ntlist(atom, list, cut_global*cut_global);
//reorder data to make it contiguous within tubes
//and compatible with Fortran functions
std::vector<double> x_sort(3*nall), f_sort(3*nall), s_sort(9*nall);
std::vector<double> u_ts_sort(nall), u_tb_sort(nall), u_tt_sort(nall);
std::vector<int> b_sort(nall);
for (int i = 0; i < nall; i++){
int idx = ntlist.get_idx(i);
for (int j = 0; j < 3; j++) x_sort[3*i+j] = x[idx][j];
b_sort[i] = buckling[idx];
}
//bending potential
int n_triplets = ntlist.get_triplets().size();
for (int i = 0; i < n_triplets; i++) {
const array2003<int,3>& t = ntlist.get_triplets()[i];
//idx of nodes of a triplet in sorted representation
int idx_s0 = ntlist.get_idxb(t[0]);
int idx_s1 = ntlist.get_idxb(t[1]);
int idx_s2 = ntlist.get_idxb(t[2]);
double* X1 = &(x_sort[3*idx_s0]);
double* X2 = &(x_sort[3*idx_s1]);
double* X3 = &(x_sort[3*idx_s2]);
double& U1b = u_tb_sort[idx_s0];
double& U2b = u_tb_sort[idx_s1];
double& U3b = u_tb_sort[idx_s2];
double* F1 = &(f_sort[3*idx_s0]);
double* F2 = &(f_sort[3*idx_s1]);
double* F3 = &(f_sort[3*idx_s2]);
double* S1 = &(s_sort[9*idx_s0]);
double* S2 = &(s_sort[9*idx_s1]);
double* S3 = &(s_sort[9*idx_s2]);
double& R123 = r[t[1]];
double& L123 = l[t[1]];
int& BBF2 = b_sort[idx_s1];
mesont_lib_TubeBendingForceField(U1b, U2b, U3b, F1, F2, F3, S1, S2, S3,
X1, X2, X3, R123, L123, BBF2);
}
//share new values of buckling
if (BendingMode == 1){
for (int i = 0; i < nall; i++){
int idx = ntlist.get_idx(i);
buckling[idx] = b_sort[i];
}
comm->forward_comm_pair(this);
for (int i = 0; i < nall; i++){
int idx = ntlist.get_idx(i);
b_sort[i] = buckling[idx];
}
}
//segment-segment and segment-tube interactions
int n_segments = ntlist.get_segments().size();
double Rmax = 0.0;
Lmax = 0.0;
for (int i = 0; i < n_segments; i++) {
const array2003<int,2>& s = ntlist.get_segments()[i];
//idx of a segment end 1 in sorted representation
int idx_s0 = ntlist.get_idxb(s[0]);
//idx of a segment end 2 in sorted representation
int idx_s1 = ntlist.get_idxb(s[1]);
double* X1 = &(x_sort[3*idx_s0]);
double* X2 = &(x_sort[3*idx_s1]);
double length = std::sqrt(std::pow(X1[0]-X2[0],2) +
std::pow(X1[1]-X2[1],2) + std::pow(X1[2]-X2[2],2));
if (length > Lmax) Lmax = length;
double& U1t = u_tt_sort[idx_s0];
double& U2t = u_tt_sort[idx_s1];
double& U1s = u_ts_sort[idx_s0];
double& U2s = u_ts_sort[idx_s1];
double* F1 = &(f_sort[3*idx_s0]);
double* F2 = &(f_sort[3*idx_s1]);
double* S1 = &(s_sort[9*idx_s0]);
double* S2 = &(s_sort[9*idx_s1]);
double R12 = r[s[0]]; if (R12 > Rmax) Rmax = R12;
if (std::abs(R12 - RT) > 1e-3)
error->all(FLERR,"Inconsistent input and potential table");
//assume that the length of the segment is defined by the node with
//smallest global id
double L12 = (g_id[s[0]] > g_id[s[1]]) ? l[s[1]] : l[s[0]];
mesont_lib_TubeStretchingForceField(U1s, U2s, F1, F2, S1, S2, X1, X2,
R12, L12);
for (int nc = 0; nc < (int)ntlist.get_nbs()[i].size(); nc++){
//id of the beginning and end of the chain in the sorted representation
const array2003<int,2>& chain = ntlist.get_nbs()[i][nc];
int N = chain[1] - chain[0] + 1; //number of elements in the chain
int end1 = ntlist.get_idx(chain[0]); //chain ends (real representation)
int end2 = ntlist.get_idx(chain[1]);
double* X = &(x_sort[3*chain[0]]);
double* Ut = &(u_tt_sort[chain[0]]);
double* F = &(f_sort[3*chain[0]]);
double* S = &(s_sort[9*chain[0]]);
double R = r[end1];
int* BBF = &(b_sort[chain[0]]);
int E1 = ntlist.is_end(end1);
int E2 = ntlist.is_end(end2);
int Ee = 0;
double* Xe = X; double* Fe = F; double* Se = S;
if (!E1 && ntlist.get_triplet(end1)[0] != MESONTList::domain_end &&
ntlist.get_triplet(ntlist.get_triplet(end1)[0])[0] ==
MESONTList::cnt_end){
Ee = 1;
int idx = ntlist.get_idxb(ntlist.get_triplet(end1)[0]);
Xe = &(x_sort[3*idx]);
Fe = &(f_sort[3*idx]);
Se = &(s_sort[9*idx]);
}
else if (!E2 && ntlist.get_triplet(end2)[2] != MESONTList::domain_end &&
ntlist.get_triplet(ntlist.get_triplet(end2)[2])[2] ==
MESONTList::cnt_end){
Ee = 2;
int idx = ntlist.get_idxb(ntlist.get_triplet(end2)[2]);
Xe = &(x_sort[3*idx]);
Fe = &(f_sort[3*idx]);
Se = &(s_sort[9*idx]);
}
mesont_lib_SegmentTubeForceField(U1t, U2t, Ut, F1, F2, F, Fe, S1, S2, S,
Se, X1, X2, R12, N, X, Xe, BBF, R, E1, E2, Ee, TPMType);
}
}
//check if cutoff is chosen correctly
Rcut_min = std::max(2.0*Lmax, std::sqrt(0.5*Lmax*Lmax +
std::pow((2.0*Rmax + TPBRcutoff),2)));
if (cut_global < Rcut_min){
std::stringstream err;
err << "The selected cutoff is too small for the current system : " <<
"L_max = " << Lmax << ", R_max = " << RT << ", Rc = " << cut_global <<
", Rcut_min = " << Rcut_min;
error->all(FLERR, err.str().c_str());
}
// set per atom values and accumulators
// reallocate per-atom arrays if necessary
if (atom->nmax > maxeatom) {
maxeatom = atom->nmax;
memory->destroy(eatom);
memory->create(eatom,comm->nthreads*maxeatom,"pair:eatom");
memory->destroy(eatom_s);
memory->create(eatom_s,comm->nthreads*maxeatom,"pair:eatom_s");
memory->destroy(eatom_b);
memory->create(eatom_b,comm->nthreads*maxeatom,"pair:eatom_b");
memory->destroy(eatom_t);
memory->create(eatom_t,comm->nthreads*maxeatom,"pair:eatom_t");
}
if (atom->nmax > maxvatom) {
maxvatom = atom->nmax;
memory->destroy(vatom);
memory->create(vatom,comm->nthreads*maxvatom,6,"pair:vatom");
}
// zero accumulators
eng_vdwl = 0.0; energy_s = 0.0;
energy_b = 0.0; energy_t = 0.0;
for (int i = 0; i < 6; i++) virial[i] = 0.0;
for (int i = 0; i < ntot; i++){
eatom[i] = 0.0; eatom_s[i] = 0.0;
eatom_b[i] = 0.0; eatom_t[i] = 0.0;
}
for (int i = 0; i < ntot; i++)
for (int j = 0; j < 6; j++) vatom[i][j] = 0.0;
//convert from sorted representation
for (int i = 0; i < nall; i++){
int idx = ntlist.get_idx(i);
for (int j = 0; j < 3; j++) f[idx][j] += f_sort[3*i+j];
eatom_s[idx] = u_ts_sort[i];
eatom_b[idx] = u_tb_sort[i];
eatom_t[idx] = u_tt_sort[i];
eatom[idx] = u_ts_sort[i] + u_tb_sort[i] + u_tt_sort[i];
energy_s += u_ts_sort[i];
energy_b += u_tb_sort[i];
energy_t += u_tt_sort[i];
vatom[idx][0] = s_sort[9*i+0]; //xx
vatom[idx][1] = s_sort[9*i+4]; //yy
vatom[idx][2] = s_sort[9*i+8]; //zz
vatom[idx][3] = s_sort[9*i+1]; //xy
vatom[idx][4] = s_sort[9*i+2]; //xz
vatom[idx][5] = s_sort[9*i+5]; //yz
for (int j = 0; j < 6; j++) virial[j] += vatom[idx][j];
buckling[idx] = b_sort[i];
}
eng_vdwl = energy_s + energy_b + energy_t;
}
/* ----------------------------------------------------------------------
allocate all arrays
------------------------------------------------------------------------- */
void PairMESONTTPM::allocate(){
allocated = 1;
int n = atom->ntypes;
memory->create(setflag,n+1,n+1,"pair:setflag");
for (int i = 1; i <= n; i++)
for (int j = i; j <= n; j++)
setflag[i][j] = 0;
memory->create(cutsq,n+1,n+1,"pair:cutsq");
memory->create(cut,n+1,n+1,"pair:cut");
}
/* ----------------------------------------------------------------------
global settings
------------------------------------------------------------------------- */
void PairMESONTTPM::settings(int narg, char **arg){
if ((narg == 0) || (narg > 4))
error->all(FLERR,"Illegal pair_style command");
cut_global = force->numeric(FLERR,arg[0]);
// reset cutoffs that have been explicitly set
if (allocated) {
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i+1; j <= atom->ntypes; j++)
cut[i][j] = cut_global;
}
std::string TPMAFile = (narg > 1) ? arg[1] : "MESONT-TABTP.xrs";
tab_path_length = TPMAFile.length();
if (tab_path != NULL) memory->destroy(tab_path);
//c_str returns '\0' terminated string
memory->create(tab_path,tab_path_length+1,"pair:path");
std::memcpy(tab_path, TPMAFile.c_str(), tab_path_length+1);
mesont_lib_SetTablePath(tab_path, tab_path_length);
if (narg > 2) {
BendingMode = force->numeric(FLERR,arg[2]);
if ((BendingMode < 0) || (BendingMode > 1))
error->all(FLERR,"Incorrect BendingMode");
}
if (narg > 3) {
TPMType = force->numeric(FLERR,arg[3]);
if ((TPMType < 0) || (TPMType > 1))
error->all(FLERR,"Incorrect TPMType");
}
mesont_lib_TPBInit();
int M, N;
std::ifstream in(TPMAFile);
if (!in.is_open()) error->all(FLERR,"Incorrect table path");
std::string tmp;
std::getline(in,tmp);
std::getline(in,tmp);
std::getline(in,tmp);
in >> M >> N;
in.close();
mesont_lib_TPMInit(M, N);
mesont_lib_InitCNTPotModule(1, 3, 0, BendingMode, mesont_lib_get_R());
}
/* ----------------------------------------------------------------------
set coeffs for one or more type pairs
------------------------------------------------------------------------- */
void PairMESONTTPM::coeff(int narg, char **arg){
if ((narg < 2) || (narg > 3))
error->all(FLERR,"Incorrect args for pair coefficients");
if (!allocated) allocate();
int ilo,ihi,jlo,jhi;
force->bounds(FLERR,arg[0],atom->ntypes,ilo,ihi);
force->bounds(FLERR,arg[1],atom->ntypes,jlo,jhi);
double cut_one = cut_global;
if (narg == 3) cut_one = force->numeric(FLERR,arg[2]);
int count = 0;
for (int i = ilo; i <= ihi; i++) {
for (int j = MAX(jlo,i); j <= jhi; j++) {
cut[i][j] = cut_one;
setflag[i][j] = 1;
count++;
}
}
if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients");
}
/* ----------------------------------------------------------------------
init for one type pair i,j and corresponding j,i
------------------------------------------------------------------------- */
double PairMESONTTPM::init_one(int i, int j){
if (setflag[i][j] == 0) {
cut[i][j] = mix_distance(cut[i][i],cut[j][j]);
}
return cut[i][j];
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairMESONTTPM::write_restart(FILE *fp){
write_restart_settings(fp);
int i,j;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
fwrite(&setflag[i][j],sizeof(int),1,fp);
if (setflag[i][j]) {
fwrite(&cut[i][j],sizeof(double),1,fp);
}
}
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairMESONTTPM::read_restart(FILE *fp){
read_restart_settings(fp);
allocate();
int i,j;
int me = comm->me;
for (i = 1; i <= atom->ntypes; i++)
for (j = i; j <= atom->ntypes; j++) {
if (me == 0) fread(&setflag[i][j],sizeof(int),1,fp);
MPI_Bcast(&setflag[i][j],1,MPI_INT,0,world);
if (setflag[i][j]) {
if (me == 0) {
fread(&cut[i][j],sizeof(double),1,fp);
}
MPI_Bcast(&cut[i][j],1,MPI_DOUBLE,0,world);
}
}
}
/* ----------------------------------------------------------------------
proc 0 writes to restart file
------------------------------------------------------------------------- */
void PairMESONTTPM::write_restart_settings(FILE *fp){
fwrite(&BendingMode,sizeof(int),1,fp);
fwrite(&TPMType,sizeof(int),1,fp);
fwrite(&cut_global,sizeof(double),1,fp);
fwrite(&tab_path_length,sizeof(int),1,fp);
fwrite(tab_path,tab_path_length+1,1,fp);
}
/* ----------------------------------------------------------------------
proc 0 reads from restart file, bcasts
------------------------------------------------------------------------- */
void PairMESONTTPM::read_restart_settings(FILE *fp){
int me = comm->me;
if (me == 0) {
fread(&BendingMode,sizeof(int),1,fp);
fread(&TPMType,sizeof(int),1,fp);
fread(&cut_global,sizeof(double),1,fp);
fread(&tab_path_length,sizeof(int),1,fp);
}
MPI_Bcast(&BendingMode,1,MPI_INT,0,world);
MPI_Bcast(&TPMType,1,MPI_INT,0,world);
MPI_Bcast(&cut_global,1,MPI_DOUBLE,0,world);
MPI_Bcast(&tab_path_length,1,MPI_INT,0,world);
if (tab_path != NULL) memory->destroy(tab_path);
memory->create(tab_path,tab_path_length+1,"pair:path");
if (me == 0) fread(tab_path,tab_path_length+1,1,fp);
MPI_Bcast(tab_path,tab_path_length+1,MPI_CHAR,0,world);
mesont_lib_SetTablePath(tab_path,tab_path_length);
mesont_lib_TPBInit();
int M, N;
std::ifstream in(tab_path);
if (!in.is_open()) error->all(FLERR,"Incorrect table path");
std::string tmp;
std::getline(in,tmp);
std::getline(in,tmp);
std::getline(in,tmp);
in >> M >> N;
in.close();
mesont_lib_TPMInit(M, N);
mesont_lib_InitCNTPotModule(1, 3, 0, BendingMode, mesont_lib_get_R());
}
/* ----------------------------------------------------------------------
proc 0 writes to data file
------------------------------------------------------------------------- */
void PairMESONTTPM::write_data(FILE *fp){
for (int i = 1; i <= atom->ntypes; i++)
fprintf(fp,"%d\n",i);
}
/* ----------------------------------------------------------------------
proc 0 writes all pairs to data file
------------------------------------------------------------------------- */
void PairMESONTTPM::write_data_all(FILE *fp){
for (int i = 1; i <= atom->ntypes; i++)
for (int j = i; j <= atom->ntypes; j++)
fprintf(fp,"%d %d %g\n",i,j,cut[i][j]);
}
/* ---------------------------------------------------------------------- */
void PairMESONTTPM::init_style(){
//make sure that a full list is created (including ghost nodes)
int r = neighbor->request(this,instance_me);
neighbor->requests[r]->half = false;
neighbor->requests[r]->full = true;
neighbor->requests[r]->ghost = true;
}
void* PairMESONTTPM::extract(const char *str, int &){
if (strcmp(str,"mesonttpm_Es_tot") == 0) return &energy_s;
else if (strcmp(str,"mesonttpm_Eb_tot") == 0) return &energy_b;
else if (strcmp(str,"mesonttpm_Et_tot") == 0) return &energy_t;
else if (strcmp(str,"mesonttpm_Es") == 0) return eatom_s;
else if (strcmp(str,"mesonttpm_Eb") == 0) return eatom_b;
else if (strcmp(str,"mesonttpm_Et") == 0) return eatom_t;
else return NULL;
};

View File

@ -0,0 +1,98 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#ifdef PAIR_CLASS
PairStyle(mesont/tpm,PairMESONTTPM)
#else
#ifndef LMP_PAIR_MESONT_TPM_H
#define LMP_PAIR_MESONT_TPM_H
#include "pair.h"
namespace LAMMPS_NS {
class PairMESONTTPM : public Pair {
public:
PairMESONTTPM(class LAMMPS *);
virtual ~PairMESONTTPM();
virtual void compute(int, int);
void settings(int, char **);
void coeff(int, char **);
double init_one(int, int);
void write_restart(FILE *);
void read_restart(FILE *);
void write_restart_settings(FILE *);
void read_restart_settings(FILE *);
void write_data(FILE *);
void write_data_all(FILE *);
virtual void init_style();
double energy_s; // accumulated energies for stretching
double energy_b; // accumulated energies for bending
double energy_t; // accumulated energies for tube-tube interaction
double *eatom_s, *eatom_b, *eatom_t; // accumulated per-atom values
protected:
int BendingMode, TPMType;
char* tab_path;
int tab_path_length;
double cut_global;
double **cut;
static int instance_count;
virtual void allocate();
virtual void *extract(const char *, int &);
};
}
#endif
#endif
/* ERROR/WARNING messages:
E: Pair style mesont/tpm requires newton pair on
newton_pair must be set to on
E: The selected cutoff is too small for the current system
cutoff must be increased.
E: Illegal pair_style command
Incorrect argument list in the style init.
E: Incorrect table path
Incorrect path to the table files.
E: Incorrect BendingMode
Self-explanatory.
E: Incorrect TPMType
Self-explanatory.
E: Inconsistent input and potential table
The tube diameter is inconsistent with the chirality specified
during generation of the potential table.
*/

View File

@ -1,3 +1,4 @@
# list of potential files to be fetched when this package is installed
# potential file md5sum
C_10_10.mesocnt 028de73ec828b7830d762702eda571c1
TABTP_10_10.mesont 744a739da49ad5e78492c1fc9fd9f8c1

View File

@ -97,7 +97,6 @@ pair_style kolmogorov/crespi/full, Wengen Ouyang (Tel Aviv University), w.g.ouya
pair_style kolmogorov/crespi/z, Jaap Kroes (Radboud U), jaapkroes at gmail dot com, 28 Feb 17
pair_style meam/spline, Alexander Stukowski (LLNL), alex at stukowski.com, 1 Feb 12
pair_style meam/sw/spline, Robert Rudd (LLNL), robert.rudd at llnl.gov, 1 Oct 12
pair_style mesocnt, Philipp Kloza (U Cambridge), pak37 at cam.ac.uk, 15 Jan 20
pair_style morse/smooth/linear, Stefan Paquay (TU Eindhoven), stefanpaquay at gmail.com, 29 Feb 16
pair_style srp, Tim Sirk, tim.sirk at us.army.mil, 21 Nov 14
pair_style tersoff/table, Luca Ferraro, luca.ferraro@caspur.it, 1 Dec 11

View File

@ -148,6 +148,12 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
cc = cc_flux = NULL;
edpd_temp = edpd_flux = edpd_cv = NULL;
// USER-MESONT package
length = NULL;
buckling = NULL;
bond_nt = NULL;
// USER-SMD package
contact_radius = NULL;
@ -296,6 +302,11 @@ Atom::~Atom()
memory->destroy(cv);
memory->destroy(vest);
// USER-MESONT package
memory->destroy(length);
memory->destroy(buckling);
memory->destroy(bond_nt);
memory->destroy(contact_radius);
memory->destroy(smd_data_9);
memory->destroy(smd_stress);
@ -545,6 +556,12 @@ void Atom::peratom_create()
add_peratom("cc",&cc,DOUBLE,1);
add_peratom("cc_flux",&cc_flux,DOUBLE,1,1); // set per-thread flag
// USER-MESONT package
add_peratom("length",&length,DOUBLE,0);
add_peratom("buckling",&buckling,INT,0);
add_peratom("bond_nt",&bond_nt,tagintsize,2);
// USER-SPH package
add_peratom("rho",&rho,DOUBLE,0);
@ -670,6 +687,7 @@ void Atom::set_atomflag_defaults()
sp_flag = 0;
x0_flag = 0;
smd_flag = damage_flag = 0;
mesont_flag = 0;
contact_radius_flag = smd_data_9_flag = smd_stress_flag = 0;
eff_plastic_strain_flag = eff_plastic_strain_rate_flag = 0;
@ -2488,6 +2506,11 @@ void *Atom::extract(char *name)
if (strcmp(name,"cv") == 0) return (void *) cv;
if (strcmp(name,"vest") == 0) return (void *) vest;
// USER-MESONT package
if (strcmp(name,"length") == 0) return (void *) length;
if (strcmp(name,"buckling") == 0) return (void *) buckling;
if (strcmp(name,"bond_nt") == 0) return (void *) bond_nt;
if (strcmp(name, "contact_radius") == 0) return (void *) contact_radius;
if (strcmp(name, "smd_data_9") == 0) return (void *) smd_data_9;
if (strcmp(name, "smd_stress") == 0) return (void *) smd_stress;

View File

@ -129,6 +129,12 @@ class Atom : protected Pointers {
double *edpd_cv; // heat capacity
int cc_species;
// USER-MESONT package
double *length;
int *buckling;
tagint **bond_nt;
// USER-SMD package
double *contact_radius;
@ -163,6 +169,7 @@ class Atom : protected Pointers {
int cs_flag,csforce_flag,vforce_flag,ervelforce_flag,etag_flag;
int rho_flag,esph_flag,cv_flag,vest_flag;
int dpd_flag,edpd_flag,tdpd_flag;
int mesont_flag;
// SPIN package

View File

@ -585,7 +585,7 @@ void AtomVec::unpack_comm(int n, int first, double *buf)
if (cols == 0) {
int *vec = *((int **) pdata);
for (i = first; i < last; i++)
vec[i] = ubuf(buf[m++]).i;
vec[i] = (int) ubuf(buf[m++]).i;
} else {
int **array = *((int ***) pdata);
for (i = first; i < last; i++)
@ -1085,7 +1085,7 @@ void AtomVec::unpack_border(int n, int first, double *buf)
if (cols == 0) {
int *vec = *((int **) pdata);
for (i = first; i < last; i++)
vec[i] = ubuf(buf[m++]).i;
vec[i] = (int) ubuf(buf[m++]).i;
} else {
int **array = *((int ***) pdata);
for (i = first; i < last; i++)

View File

@ -375,7 +375,13 @@ ComputePropertyAtom::ComputePropertyAtom(LAMMPS *lmp, int narg, char **arg) :
error->all(FLERR,"Compute property/atom floating point "
"vector does not exist");
pack_choice[i] = &ComputePropertyAtom::pack_dname;
}
else if (strcmp(arg[iarg],"buckling") == 0) {
if (!atom->mesont_flag)
error->all(FLERR,"Compute property/atom for "
"atom property that isn't allocated");
pack_choice[i] = &ComputePropertyAtom::pack_buckling;
// check if atom style recognizes keyword
} else {
@ -1774,6 +1780,21 @@ void ComputePropertyAtom::pack_corner3z(int n)
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_buckling(int n)
{
int *buckling = atom->buckling;
int *mask = atom->mask;
int nlocal = atom->nlocal;
for (int i = 0; i < nlocal; i++) {
if (mask[i] & groupbit) buf[n] = static_cast<double>(buckling[i]);
else buf[n] = 0.0;
n += nvalues;
}
}
/* ---------------------------------------------------------------------- */
void ComputePropertyAtom::pack_nbonds(int n)
{
int *num_bond = atom->num_bond;

View File

@ -125,6 +125,7 @@ class ComputePropertyAtom : public Compute {
void pack_corner3x(int);
void pack_corner3y(int);
void pack_corner3z(int);
void pack_buckling(int);
void pack_nbonds(int);

58
tools/mesont/README Normal file
View File

@ -0,0 +1,58 @@
=== USER-MESONT tools ===
===============================
The programs in this folder can be used to analyze the
output of simulations using the CNT mesoscopic force
field (USER-MESONT).
dump2vtk.cpp converts output written in *.dump format (the
sequence of columns must be "ATOMS id type x y z Es Eb Et
Ek ix iy iz", the same as in the examples at examples\USER\mesont)
into VTK format that can be visualized as a set of tubes in
Paraview (or other packages). The executable takes 3 parameters:
system.init - an input file with information about connections
between cnt nodes, config.dump - LAMMPS output with snapshots,
out - output folder for writing VTK files (must exist).
Code TMDPotGen is designed to generate ASCII text files TPMSSTP.xrs
and TPMA.xrs containing tabulated tubular potentials for
single-walled CNTs with a given chirality (m,n). The input
parameters for the code must be provided in the form of an ASCII
text file TMDPotGen.xdt. The output of the code are files TPMSSTP.xrs
and TPMA.xrs. All parameters in the tables are given in metal units.
The generation of the tables takes approximately 4 hours.
Code TMDGen is designed to generate initial samples composed of
straight and dispersed nanotubes of given chirality and length at
a given material density. In the generated samples, nanotubes are
distributed with random positions and orientations. Both periodic
and free boundary conditions are available along each axis of the
system. The input parameters for the code must be provided in form
of an ASCII text file TMDGen.xdt and include the following:
LS0: sample size along z- and y-directions (A)
HS0: sample size along z-direction (A)
DS0: material density (g/cm^3)
BC_X0: Type of boundary conditions along x-direction (0, Free; 1, Periodic)
BC_Y0: Type of boundary conditions along y-direction (0, Free; 1, Periodic)
BC_Z0: Type of boundary conditions along z-direction (0, Free; 1, Periodic)
ChiIndM: First chirality index of nanotubes
ChiIndN: Second chirality index of nanotubes
LT0: Nanotube length (A)
SegType: Parameter that defines how a nanotubes will be divided into
segments(0, NSeg0 will be used; 1, LSeg0 will be used)
NSeg0: Number of segments in every nanotube. Used if SegType = 0. Then
LSeg0 = LT0 / NSeg0
LSeg0: Length of segments in every nanotube. Used if SegType = 1. Then
NSeg0 = [ LT0 / LSeg0 ]
DeltaT: Minimum gap between nanotube walls in the generated sample (A)
NAmax: Maximum number of attempts to add new nanotube to the sample
GeomPrec: Precision of calculations (dimensionless).
The output of the code is an ASCII text file TMDSample.init written in the
LAMMPS format compatible with cnt atomic style. All parameters in the sample
files generated with TMDGen are given in metal units.
This packages were created by Maxim Shugaev (mvs9t@virginia.edu)
at the University of Virginia and by Alexey N. Volkov (avolkov1@ua.edu)
at the University of Alabama.

View File

@ -0,0 +1,33 @@
#---------------------------------------------------------------------------------------------------
#
# This is Makefile for builing the executable TMDGen
#
# Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, 2020, Version 13.00
#
#---------------------------------------------------------------------------------------------------
EXEPATH = .
F90 = ifort
F90FLAGS = -O3 -ipo
LDFLAGS =
OBJS = TPMLib.o TPMGeom.o TMDGenData.o TMDGen3D.o TMDGen.o
EXE = $(EXEPATH)/TMDGen
# compile and load
default:
@echo " "
@echo "Compiling Code of Program TMDGen"
@echo "FORTRAN 90"
$(MAKE) $(EXE)
$(EXE): $(OBJS)
$(F90) $(F90FLAGS) $(LDFLAGS) -o $(EXE) $(OBJS)
.SUFFIXES: .f90 .o
.f90.o:
$(F90) $(F90FLAGS) -c $*.f90
clean:
rm -f *.o

View File

@ -0,0 +1,267 @@
program TMDGen !************************************************************************************
!
! Stand-alone generator of 3D CNT samples.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, 2020, Version 13.00
!
!***************************************************************************************************
use TMDGen3D
implicit none
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
integer*4 :: Nseg, Nnode
real*8 :: DS00
!---------------------------------------------------------------------------------------------------
! Body
!---------------------------------------------------------------------------------------------------
print *, 'TMD generator of 3D CNT samples, v. 13.00'
print '(a34,a,i10)', 'Maximum number of nanotubes', ' : ', MAX_TUBE
call SetRandomSeed ()
! Reading and printing of governing parameters
call LoadGoverningParameters ()
call PrintGoverningParameters ()
! Here we calculate the radius of nanotubes
RT0 = TPBA * sqrt ( 3.0d+00 * ( ChiIndM * ChiIndM + ChiIndN * ChiIndN + ChiIndM * ChiIndN ) ) / M_2PI;
! Here we calculate parameters of the desired sample
call InitSample ()
DS0 = DS0 * ( K_MDDU / 1.0d+03 )
call PrintSampleParameters ( 'Desired' )
DS00 = DS0
DS0 = DS0 / ( K_MDDU / 1.0d+03 )
call Generator3D ()
! Here we write the major output file with the sample
!call WriteOutputFile_old_format ()
!call WriteOutputFile ()
! Here we write an auxiliary Tecplot file to visualize the initial sample
!PrintTecplotFile ()
call WriteLAMMPSFile()
! Here we print parameters of the final sample
call PrintSampleParameters ( 'Final' )
print '(a34,a,f15.4,a)', 'Nanotube radius ', ' : ', RT0, ' a'
print '(a34,a,f15.4,a)', 'Nanotube length ', ' : ', LT0, ' a'
print '(a34,a,f15.4,a)', 'Nanotube mass ', ' : ', M_2PI * RT0 * LT0 * TPBM * TPBD, ' Da'
if ( SegType == 0 ) then
LSeg0 = LT0 / NSeg0
else
NSeg0 = int ( LT0 / LSeg0 ) + 1
LSeg0 = LT0 / NSeg0
end if
print '(a34,a,f15.4,a)', 'Nanotube segment length ', ' : ', LSeg0, ' a'
print '(a34,a,f15.4,a)', 'Nanotube segment mass ', ' : ', M_2PI * RT0 * LSeg0 * TPBM * TPBD, ' Da'
print '(a34,a,f15.4)', 'Desired / Real densities ', ' : ', DS00 / DS0
print '(a34,a,i10)', 'Real number of tubes', ' : ', NT
print '(a34,a,i10)', 'Real number of segments', ' : ', Nseg
print '(a34,a,i10)', 'Real number of nodes', ' : ', Nnode
contains !******************************************************************************************
subroutine DiscretizeTube ( X0, DL, NS, i ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function calculaats geometrical parameters that are necessary to represent straight
! tube i as a sequence of segments.
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(out) :: X0
real*8, intent(out) :: DL
integer*4, intent(out) :: NS
integer*4, intent(in) :: i
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2) :: X1
!-------------------------------------------------------------------------------------------
call GetTubeEnds ( X0, X1, i )
if ( SegType == 0 ) then
NS = NSeg0
else
NS = int ( LT(i) / LSeg0 ) + 1
end if
DL = LT(i) / NS
end subroutine DiscretizeTube !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine WriteOutputFile_old_format () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function writes a dat file (version 2) with the initial nanotube sample.
! This file is used by TMD/TMDMPI to start a new simulation.
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid, i, j, NTS, Prop
real*8 :: DL, L, L00, M00, I00, J00, C00, LL00, MM00, II00, JJ00, CC00
real*8, dimension(0:2) :: X, X0
logical*4 :: PrintNode
!-------------------------------------------------------------------------------------------
Fuid = OpenFile ( 'TMDGen_old.dat', "wt", "" )
write ( unit = Fuid, fmt = '(i12)' ) 3
write ( unit = Fuid, fmt = '(2i4,4e20.12)' ) ChiIndM, ChiIndN, RT0, TPBA, TPBD, TPBM
write ( unit = Fuid, fmt = '(3e20.12)' ) DomXmin, DomYmin, DomZmin
write ( unit = Fuid, fmt = '(3e20.12)' ) DomXmax, DomYmax, DomZmax
write ( unit = Fuid, fmt = '(3i12)' ) BC_X, BC_Y, BC_Z
write ( unit = Fuid, fmt = '(i12)' ) NT
Nseg = 0
Nnode = 0
do i = 0, NT - 1
call DiscretizeTube ( X0, DL, NTS, i )
L00 = LT(i) / NTS
M00 = TubeMass ( i ) / NTS
I00 = 0.0d+00
J00 = M00 * sqr ( RT(i) )
C00 = M00 * TubeSpecificHeat ( i )
Nseg = Nseg + NTS
write ( unit = Fuid, fmt = '(i12)' ) NTS + 1
Nnode = Nnode + NTS + 1
L = 0.0d+00
do j = 0, NTS
X = X0 + L * DT(i,0:2)
MM00 = M00
II00 = I00
JJ00 = J00
CC00 = C00
LL00 = L00
if ( j == 0 .or. j == NTS ) then
MM00 = 0.5d+00 * M00
II00 = 0.5d+00 * I00
JJ00 = 0.5d+00 * J00
CC00 = 0.5d+00 * C00
end if
if ( j == NTS ) LL00 = 0.0d+00
Prop = 0
write ( unit = Fuid, fmt = '(i2,6e20.12)' ) Prop, RT(0), LL00, MM00, II00, JJ00, CC00
write ( unit = Fuid, fmt = '(6e20.12)' ) X, RT(i), 0.0d+00, 300.0d+00
L = L + DL
end do
end do
write ( unit = Fuid, fmt = '(i12)' ) 0
write ( unit = Fuid, fmt = '(i12)' ) 0
call CloseFile ( Fuid )
end subroutine WriteOutputFile_old_format !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine WriteOutputFile () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function writes a dat file (version 2) with the initial nanotube sample.
! This file is used by TMD/TMDMPI to start a new simulation.
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid, i, j, NTS
real*8 :: DL, L, L00, M00, LL00, MM00
real*8, dimension(0:2) :: X, X0
logical*4 :: PrintNode
!-------------------------------------------------------------------------------------------
Fuid = OpenFile ( 'TMDGen.dat', "wt", "" )
write ( unit = Fuid, fmt = '(2i4,4e20.12)' ) ChiIndM, ChiIndN, RT0, TPBA, TPBD, TPBM
write ( unit = Fuid, fmt = '(3e20.12)' ) DomXmin, DomYmin, DomZmin
write ( unit = Fuid, fmt = '(3e20.12)' ) DomXmax, DomYmax, DomZmax
write ( unit = Fuid, fmt = '(3i12)' ) BC_X, BC_Y, BC_Z
write ( unit = Fuid, fmt = '(i12)' ) NT
Nseg = 0
Nnode = 0
do i = 0, NT - 1
call DiscretizeTube ( X0, DL, NTS, i )
L00 = LT(i) / NTS
M00 = TubeMass ( i ) / NTS
Nseg = Nseg + NTS
write ( unit = Fuid, fmt = '(i12)' ) NTS + 1
Nnode = Nnode + NTS + 1
L = 0.0d+00
do j = 0, NTS
X = X0 + L * DT(i,0:2)
MM00 = M00
LL00 = L00
if ( j == 0 .or. j == NTS ) MM00 = 0.5d+00 * M00
if ( j == NTS ) LL00 = 0.0d+00
write ( unit = Fuid, fmt = '(5e20.12)' ) X, LL00, MM00
L = L + DL
end do
end do
call CloseFile ( Fuid )
end subroutine WriteOutputFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine PrintTecplotFile () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function prints Tecplot file to visualize the generated sample
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid, i
real*8 :: LT2
!-------------------------------------------------------------------------------------------
Fuid = OpenFile ( 'TMDGen.plt', "wt", "" )
write ( unit = Fuid, fmt = '(a)' ) 'VARIABLES="X" "Y" "Z"'
do i = 0, NT - 1
write ( unit = Fuid, fmt = '(a,i,a)' ) 'ZONE T="T', i, '"'
LT2 = 0.5d+00 * LT(i)
write ( unit = Fuid, fmt = '(3e20.12)' ) CT(i,0:2) - LT2 * DT(i,0:2)
write ( unit = Fuid, fmt = '(3e20.12)' ) CT(i,0:2) + LT2 * DT(i,0:2)
end do
call CloseFile ( Fuid )
end subroutine PrintTecplotFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine WriteLAMMPSFile () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function writes a dat file (version 2) with the initial nanotube sample.
! This file is used by TMD/TMDMPI to start a new simulation.
!-------------------------------------------------------------------------------------------
integer*4 :: file_id, i, j, NTS, node_id, b1, b2
real*8 :: DL, L, L00, M00, LL00, MM00
real*8, dimension(0:2) :: X, X0
logical*4 :: PrintNode
!-------------------------------------------------------------------------------------------
open(newunit = file_id, file = 'TMDSample.init')
write(file_id,*)
write(file_id,*)
!count the number of nodes and segments
Nseg = 0
Nnode = 0
do i = 0, NT - 1
call DiscretizeTube (X0, DL, NTS, i)
Nseg = Nseg + NTS
Nnode = Nnode + NTS + 1
enddo
write(file_id,'(i9,a)') Nnode, " atoms"
write(file_id,*)
write(file_id,*) "1 atom types"
write(file_id,*)
write(file_id,'(2e20.12,2a)') DomXmin, DomXmax, " xlo xhi"
write(file_id,'(2e20.12,2a)') DomYmin, DomYmax, " ylo yhi"
write(file_id,'(2e20.12,2a)') DomZmin, DomZmax, " zlo zhi"
write(file_id,*)
write(file_id,*) "Masses"
write(file_id,*)
write(file_id,*) "1 1.0"
write(file_id,*)
write(file_id,*) "Atoms"
write(file_id,*)
node_id = 1
do i = 0, NT - 1
call DiscretizeTube(X0, DL, NTS, i)
L00 = LT(i) / NTS
M00 = TubeMass (i) / NTS
b1 = -1
L = 0.0d+00
do j = 0, NTS
b2 = node_id + 1
if (j == NTS) b2 = -1
MM00 = M00
LL00 = L00
if (j == 0 .or. j == NTS) MM00 = 0.5d+00 * M00
if (j == NTS) LL00 = 0.0d+00
X = X0 + L * DT(i,0:2)
write(file_id,'(2i9,a,2i9,3e14.7,a,3e20.12,a)') node_id, i, " 1 ", b1, b2, MM00, RT(i), LL00, " 0 ", X, " 0 0 0"
b1 = node_id
node_id = node_id + 1
L = L + DL
enddo
enddo
close(file_id)
end subroutine !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end program TMDGen !********************************************************************************

View File

@ -0,0 +1,15 @@
0.400000000000E+04 : LS0, A
0.400000000000E+04 : HS0, A
0.010000000000E+00 : DS0, Density g/cm^3
1 : BC_X0, periodic along X
1 : BC_Y0, periodic along Y
0 : BC_Z0, periodic along Z
10 : ChiIndM, tube chirality M
10 : ChiIndN, tube chirality N
0.200000000000E+04 : LT0, A
0 : SegType
100 : NSeg0
0.200000000000E+02 : LSeg0
0.500000000000E+01 : DeltaT, A
1000000 : NAmax
0.100000000000E-06 : GeomPrec

View File

@ -0,0 +1,231 @@
module TMDGen3D !***********************************************************************************
!
! Generator of 3D CNT samples for TPM force field
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!---------------------------------------------------------------------------------------------------
use TMDGenData
implicit none
contains !******************************************************************************************
real*8 function MinimalDistance3D ( S1, S2, H, cosA, P, Q ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns the minimum distance between two line segments in 3D
!-------------------------------------------------------------------------------------------
real*8, intent(out) :: S1, S2
real*8, intent(in) :: H, cosA
real*8, dimension(0:1), intent(in) :: P, Q
!-------------------------------------------------------------------------------------------
real*8 :: H2, cosA2, D
real*8, dimension(0:1) :: P1, Q1
integer*4, dimension(0:1,0:1) :: KA
integer*4 :: i, j, K
!-------------------------------------------------------------------------------------------
if ( ( P(0) * P(1) .le. 0.0d+00 ) .and. ( Q(0) * Q(1) .le. 0.0d+00 ) ) then
MinimalDistance3D = H
S1 = 0.5d+00 * ( P(0) + P(1) )
S2 = 0.5d+00 * ( Q(0) + Q(1) )
return
end if
do i = 0, 1
P1(i) = P(i) * cosA
Q1(i) = Q(i) * cosA
end do
KA = 1
K = 0
do i = 0, 1
if ( ( Q1(i) .ge. P(0) ) .and. ( Q1(i) .le. P(1) ) ) then
D = sqr ( Q(i) )
if ( K == 0 ) then
MinimalDistance3D = D
S1 = Q1(i)
S2 = Q(i)
K = 1
else if ( D < MinimalDistance3D ) then
MinimalDistance3D = D
S1 = Q1(i)
S2 = Q(i)
end if
KA(0,i) = 0
KA(1,i) = 0
end if
if ( ( P1(i) .ge. Q(0) ) .and. ( P1(i) .le. Q(1) ) ) then
D = sqr ( P(i) )
if ( K == 0 ) then
MinimalDistance3D = D
S1 = P(i)
S2 = P1(i)
K = 1
else if ( D < MinimalDistance3D ) then
MinimalDistance3D = D
S1 = P(i)
S2 = P1(i)
end if
KA(i,0) = 0
KA(i,1) = 0
end if
end do
H2 = sqr ( H )
cosA2 = 2.0d+00 * cosA
if ( K == 1 ) MinimalDistance3D = H2 + MinimalDistance3D * ( 1.0d+00 - sqr ( cosA ) )
do i = 0, 1
do j = 0, 1
if ( KA(i,j) == 1 ) then
D = H2 + sqr ( P(i) ) + sqr ( Q(j) ) - P(i) * Q(j) * cosA2
if ( K == 0 ) then
MinimalDistance3D = D
S1 = P(i)
S2 = Q(j)
K = 1
else if ( D < MinimalDistance3D ) then
MinimalDistance3D = D
S1 = P(i)
S2 = Q(j)
end if
end if
end do
end do
MinimalDistance3D = dsqrt ( MinimalDistance3D )
end function MinimalDistance3D !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine RandTube3D ( X, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This subroutine generates a random tube in an isotropic 3D sample
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(out) :: X, L
!-------------------------------------------------------------------------------------------
real*8 :: CT, ST, E
!-------------------------------------------------------------------------------------------
if ( BC_X0 == 0 ) then
X(0)= LS0 * randnumber ()
else
X(0)= LS0 * ( 0.5d+00 - 1.0d+00 * randnumber () )
end if
if ( BC_Y0 == 0 ) then
X(1)= LS0 * randnumber ()
else
X(1)= LS0 * ( 0.5d+00 - 1.0d+00 * randnumber () )
end if
if ( BC_Z0 == 0 ) then
X(2)= HS0 *randnumber ()
else
X(2)= HS0 * ( 0.5d+00 - 1.0d+00 * randnumber () )
end if
CT = 1.0d+00 - 2.0d+00 * randnumber ()
ST = sqrt ( 1.0d+00 - sqr ( CT ) )
E = M_2PI * randnumber ()
L(0)= CT
L(1)= ST * cos ( E )
L(2)= ST * sin ( E )
end subroutine RandTube3D !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
logical function AddTubeToSample3D ( MS ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function adds the last generated tube to the existing sample, if possible.
! In a case of periodic boundaries, this version is valid only f the tube length is smaller
! than the half of the sample.
!-------------------------------------------------------------------------------------------
real*8, intent(inout) :: MS
!-------------------------------------------------------------------------------------------
integer*4 :: i, m
real*8 :: Dmin, LT2, H, cosA, D1, D2, S1, S2
real*8, dimension(0:2) :: X, L12
real*8, dimension(0:1) :: P, Q
!-------------------------------------------------------------------------------------------
AddTubeToSample3D = .false.
if ( .not. IsTubeInside ( NT ) ) return
LT2 = 0.5d+00 * LT(NT)
do m = 0, NT - 1
X = CT(NT,0:2)
if ( LineLine ( H, cosA, D1, D2, L12, X, DT(NT,0:2), CT(m,0:2), DT(m,0:2), GeomPrec ) == MD_LINES_NONPAR ) then
P(0) = D1 - LT2
P(1) = D1 + LT2
Q(0) = D2 - 0.5d+00 * LT(m)
Q(1) = D2 + 0.5d+00 * LT(m)
Dmin = MinimalDistance3D ( S1, S2, H, cosA, P, Q )
else
call LinePoint ( H, L12, CT(m,0:2), DT(m,0:2), X )
L12 = L12 - X
call ApplyPeriodicBC ( L12 )
Dmin = S_V3norm3 ( L12 )
end if
if ( Dmin < RT(NT) + RT(m) + DeltaT ) return
end do
MS = MS + TubeMass ( NT )
NT = NT + 1
AddTubeToSample3D = .true.
end function AddTubeToSample3D !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine Generator3D () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This subroutine implements the whole fgenerator of 3D samples
!-------------------------------------------------------------------------------------------
integer*4 :: NA, NT0
real*8 :: MS
real*8 :: X1, X2, Y1, Y2, Z1, Z2
!-------------------------------------------------------------------------------------------
NT = 0
MS = 0.0d+00
NT0 = int ( MS0 / ( M_2PI * RT0 * LT0 * TPBM * TPBD ) )
do
if ( NT == MAX_TUBE ) then
print *, 'Error in [Generator3D]: MAX_TUBE is too small'
stop
end if
if ( MS .ge. MS0 ) exit
NA = 0
! Trying to add the tube to the sample
! The maximal number of attempts is equal to NAmax
RT(NT) = RT0
LT(NT) = LT0
do
if ( NA == NAmax ) exit
call RandTube3D ( CT(NT,0:2), DT(NT,0:2) )
if ( AddTubeToSample3D ( MS ) ) then
print '(a,i10,a,i10,a,i10)', 'Tube ', NT, '(Appr.', NT0, ' total): Attempt ', NA
if ( BC_X0 == 0 ) then
X1 = CT(NT,0) - 0.5d+00 * LT(NT) * DT(NT,0)
X2 = CT(NT,0) + 0.5d+00 * LT(NT) * DT(NT,0)
if ( DomXmin > X1 ) DomXmin = X1
if ( DomXmin > X2 ) DomXmin = X2
if ( DomXmax < X1 ) DomXmax = X1
if ( DomXmax < X2 ) DomXmax = X2
end if
if ( BC_Y0 == 0 ) then
Y1 = CT(NT,1) - 0.5d+00 * LT(NT) * DT(NT,1)
Y2 = CT(NT,1) + 0.5d+00 * LT(NT) * DT(NT,1)
if ( DomYmin > Y1 ) DomYmin = Y1
if ( DomYmin > Y2 ) DomYmin = Y2
if ( DomYmax < Y1 ) DomYmax = Y1
if ( DomYmax < Y2 ) DomYmax = Y2
end if
if ( BC_Z0 == 0 ) then
Z1 = CT(NT,2) - 0.5d+00 * LT(NT) * DT(NT,2)
Z2 = CT(NT,2) + 0.5d+00 * LT(NT) * DT(NT,2)
if ( DomZmin > Z1 ) DomZmin = Z1
if ( DomZmin > Z2 ) DomZmin = Z2
if ( DomZmax < Z1 ) DomZmax = Z1
if ( DomZmax < Z2 ) DomZmax = Z2
end if
exit
end if
NA = NA + 1
end do
end do
MS0 = MS
if ( BC_X0 == 0 ) DomLX = DomXmax - DomXmin
if ( BC_Y0 == 0 ) DomLY = DomYmax - DomYmin
if ( BC_Z0 == 0 ) DomLZ = DomZmax - DomZmin
VS0 = ( DomXmax - DomXmin ) * ( DomYmax - DomYmin ) * ( DomZmax - DomZmin )
DS0 = MS0 / VS0 * ( K_MDDU / 1.0d+03 )
end subroutine Generator3D !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TMDGen3D !*******************************************************************************

View File

@ -0,0 +1,289 @@
module TMDGenData !*********************************************************************************
!
! Common data for TMDGen
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!---------------------------------------------------------------------------------------------------
use TPMGeom
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
integer*4, parameter :: MAX_TUBE = 1000000 ! Maximum number of tubes in 3D
real*8, parameter :: K_MDDU = K_MDMU / K_MDLU / K_MDLU / K_MDLU ! MD density unit (kg/m**3)
!
! These parameters are specific for carbon nanotubes and taken from module TubePotBase
!
real*8, parameter :: TPbConstD = 5.196152422706632d+00 ! = 3.0**1.5
! Mass of C atom
real*8, parameter :: TPBM = 12.0107d+00 ! (a.m.u.)
! Lattice parameter and numerical density of atoms for a graphene sheet, see Dresselhaus et al, Carbon 33(7), 1995
real*8, parameter :: TPBA = 1.421d+00 ! (Angstrom)
real*8, parameter :: TPBD = 4.0d+00 / ( TPBConstD * TPBA * TPBA ) ! (1/Angstrom^2)
! Specific heat of carbon nanotubes
real*8, parameter :: TPBSH = 600.0d+00 / K_MDCU ! (eV/(Da*K))
!---------------------------------------------------------------------------------------------------
! Governing parameters
!---------------------------------------------------------------------------------------------------
! Parameters of the sample
real*8 :: LS0 = 4000.0 ! Sample size in x, y-directions (Angstrom)
real*8 :: HS0 = 4000.0 ! Sample size in z-direction (Angstrom)
real*8 :: DS0 = 0.01 ! Density (g/cm**3)
integer*4 :: BC_X0 = 1 ! Boundary conditions in x-direction: 0, free; 1, periodic
integer*4 :: BC_Y0 = 1 ! Boundary conditions in y-direction: 0, free; 1, periodic
integer*4 :: BC_Z0 = 1 ! Boundary conditions in z-direction: 0, free; 1, periodic
! Parameters of tubes
integer*4 :: ChiIndM = 10 ! Chirality index m of nanotubes
integer*4 :: ChiIndN = 10 ! Chirality index n of nanotubes
real*8 :: LT0 = 2000.0 ! Characterstic length of tubes (Angstrom)
integer*4 :: SegType = 0 ! 0, number of segments per tube is fixed
! 1, rounded length of segments is fixed
integer*4 :: NSeg0 = 100 ! Number of segments per tube
real*8 :: LSeg0 = 20.0d+00 ! Length of the segment (Angstrom)
! Parameters controlling the sample structure
real*8 :: DeltaT = 3.0 ! Minimal distance between tubes (Angstrom)
integer*4 :: NAmax = 50000 ! Maximal number of attempts (for SampleType = 4 it is used as an input paramtere for number of tubes)
real*8 :: GeomPrec = 1.0d-06 ! Geometrical precision
!---------------------------------------------------------------------------------------------------
! Computed data
!---------------------------------------------------------------------------------------------------
real*8 :: RT0 = 6.785 ! Radius of tubes (Angstrom)
real*8 :: VS0 ! Desired volume of the sample, Angstrom**3
real*8 :: MS0 ! Desired mass of the sample, Da (For SampleType = 4 it is the defined fixed mass- definition is given in TMDGen7T)
real*8 :: CTCD ! Center to center distance between any surrounding tube and center tube (used for SampleType == 4 only)
integer*4 :: NT ! Real number of tubes
real*8, dimension(0:MAX_TUBE-1) :: RT ! Radii of tubes, Angstrom
real*8, dimension(0:MAX_TUBE-1) :: LT ! Lengths of tubes, Angstrom
real*8, dimension(0:MAX_TUBE-1,0:2) :: CT ! Coordinates of tubes' centers, Angstrom
real*8, dimension(0:MAX_TUBE-1,0:2) :: DT ! Directions of tubes
integer*4, dimension(0:MAX_TUBE-1) :: AT ! Parent axes of tubes. It is used only in GeneratorBundle ()
contains !******************************************************************************************
!---------------------------------------------------------------------------------------------------
! Pseudo-random number generator
!---------------------------------------------------------------------------------------------------
real*8 function randnumber () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns a pseudo-random number with uniform distribution in [0,1]
!-------------------------------------------------------------------------------------------
call random_number ( randnumber )
end function randnumber !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine SetRandomSeed () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This subroutine sets random seed for the pseudo-random number generator
!-------------------------------------------------------------------------------------------
integer :: i, n, clock
integer, dimension(:), allocatable :: seed
!-------------------------------------------------------------------------------------------
call RANDOM_SEED ( size = n )
allocate ( seed(n) )
call SYSTEM_CLOCK ( COUNT = clock )
seed = clock + 37 * (/ (i - 1, i = 1, n) /)
call RANDOM_SEED ( PUT = seed )
deallocate ( seed )
end subroutine SetRandomSeed !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Generators for (random) properties of nanotubes
!---------------------------------------------------------------------------------------------------
real*8 function TubeMass ( i ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns the mass of the tube in Da
!-------------------------------------------------------------------------------------------
integer*4, intent(in) :: i
!-------------------------------------------------------------------------------------------
TubeMass = M_2PI * RT(i) * LT(i) * TPBM * TPBD
end function TubeMass !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function TubeSpecificHeat ( i ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns the specific heat of the tube
!-------------------------------------------------------------------------------------------
integer*4, intent(in) :: i
!-------------------------------------------------------------------------------------------
TubeSpecificHeat = TPBSH
end function TubeSpecificHeat !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Reading and printing of input parameters
!---------------------------------------------------------------------------------------------------
subroutine LoadGoverningParameters () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function reads governing parameters from xdt file
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid, i
character*512 :: Msg
!-------------------------------------------------------------------------------------------
Fuid = OpenFile ( 'TMDGen.xdt', 'rt', '' )
read ( unit = Fuid, fmt = '(e22.12)' ) LS0
read ( unit = Fuid, fmt = '(e22.12)' ) HS0
read ( unit = Fuid, fmt = '(e22.12)' ) DS0
read ( unit = Fuid, fmt = '(i22)' ) BC_X0
read ( unit = Fuid, fmt = '(i22)' ) BC_Y0
read ( unit = Fuid, fmt = '(i22)' ) BC_Z0
read ( unit = Fuid, fmt = '(i22)' ) ChiIndM
read ( unit = Fuid, fmt = '(i22)' ) ChiIndN
read ( unit = Fuid, fmt = '(e22.12)' ) LT0
read ( unit = Fuid, fmt = '(i22)' ) SegType
read ( unit = Fuid, fmt = '(i22)' ) NSeg0
read ( unit = Fuid, fmt = '(e22.12)' ) LSeg0
read ( unit = Fuid, fmt = '(e22.12)' ) DeltaT
read ( unit = Fuid, fmt = '(i22)' ) NAmax
read ( unit = Fuid, fmt = '(e22.12)' ) GeomPrec
call CloseFile ( Fuid )
end subroutine LoadGoverningParameters !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine PrintGoverningParameters () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function prints governing parameters to xlg file
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid, i
!-------------------------------------------------------------------------------------------
Fuid = OpenFile ( 'TMDGen.xlg', 'wt', '' )
write ( unit = Fuid, fmt = '(e22.12,a)' ) LS0, ' : LS0, Angstrom'
write ( unit = Fuid, fmt = '(e22.12,a)' ) HS0, ' : HS0, Angstrom'
write ( unit = Fuid, fmt = '(e22.12,a)' ) DS0, ' : DS0, g/cm**3'
write ( unit = Fuid, fmt = '(e22.12,a)' ) DS0, ' : SC0, 1/A**2'
write ( unit = Fuid, fmt = '(i22,a)' ) BC_X0, ' : BC_X0'
write ( unit = Fuid, fmt = '(i22,a)' ) BC_Y0, ' : BC_Y0'
write ( unit = Fuid, fmt = '(i22,a)' ) BC_Z0, ' : BC_Z0'
write ( unit = Fuid, fmt = '(i22,a)' ) ChiIndM, ' : ChiIndM'
write ( unit = Fuid, fmt = '(i22,a)' ) ChiIndN, ' : ChiIndN'
write ( unit = Fuid, fmt = '(e22.12,a)' ) LT0, ' : LT0, Angstrom'
write ( unit = Fuid, fmt = '(i22,a)' ) SegType, ' : SegType'
write ( unit = Fuid, fmt = '(i22,a)' ) NSeg0, ' : NSeg0'
write ( unit = Fuid, fmt = '(e22.12,a)' ) LSeg0, ' : LSeg0, Angstrom'
write ( unit = Fuid, fmt = '(e22.12,a)' ) DeltaT, ' : DeltaT'
write ( unit = Fuid, fmt = '(i22,a)' ) NAmax, ' : NAmax'
write ( unit = Fuid, fmt = '(e22.12,a)' ) GeomPrec, ' : GeomPrec'
call CloseFile ( Fuid )
end subroutine PrintGoverningParameters !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Printing of sample parameters
!---------------------------------------------------------------------------------------------------
subroutine PrintSampleParameters ( ParType ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function prints the most imprtant parameters of the sample.
! In the code, it used twice to print parameters of the desired and really generated samples.
!-------------------------------------------------------------------------------------------
character*(*), intent(in) :: ParType
real*8 :: MP, M, V
!-------------------------------------------------------------------------------------------
print '(a,a,a)', '*** ', trim(ParType), ' properties of the sample'
print '(a34,a,f15.4,a)', 'L', ' : ', LS0, ' A'
print '(a34,a,f15.4,a)', 'H', ' : ', HS0, ' A'
print '(a34,a,f15.4,a)', 'Density', ' : ', DS0, ' g/cm**3'
print '(a34,a,e15.8,a)', 'Volume', ' : ', VS0, ' A*3'
print '(a34,a,e15.8,a)', 'Mass', ' : ', MS0, ' Da'
print '(a34,a,i10)', 'BC_X', ' : ', BC_X0
print '(a34,a,i10)', 'BC_Y', ' : ', BC_Y0
print '(a34,a,i10)', 'BC_Z', ' : ', BC_Z0
end subroutine PrintSampleParameters !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Initializing of basic geometrical parameters of the generated sample
!---------------------------------------------------------------------------------------------------
subroutine InitSample () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function initializes the geometrical parameters of the sample (sizes, etc.)
!-------------------------------------------------------------------------------------------
BC_X = BC_X0
BC_Y = BC_Y0
BC_Z = BC_Z0
DomXmin = - LS0 / 2.0d+00
DomXmax = LS0 / 2.0d+00
DomYmin = - LS0 / 2.0d+00
DomYmax = LS0 / 2.0d+00
DomZmin = - HS0 / 2.0d+00
DomZmax = HS0 / 2.0d+00
if ( BC_X0 == 0 ) then
DomXmin = 0.0d+00
DomXmax = LS0
end if
if ( BC_Y0 == 0 ) then
DomYmin = 0.0d+00
DomYmax = LS0
end if
if ( BC_Z0 == 0 ) then
DomZmin = 0.0d+00
DomZmax = HS0
end if
DomLX = DomXmax - DomXmin
DomLY = DomYmax - DomYmin
DomLZ = DomZmax - DomZmin
DomLXHalf = 0.5d+00 * DomLX
DomLYHalf = 0.5d+00 * DomLY
DomLZHalf = 0.5d+00 * DomLZ
DS0 = DS0 / ( K_MDDU / 1.0d+03 )
VS0 = LS0 * LS0 * HS0
MS0 = DS0 * VS0
end subroutine InitSample !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! A few auxiliary functions
!---------------------------------------------------------------------------------------------------
subroutine GetTubeEnds ( X0, X1, i ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function calculates coordinates of two ends of nanotube i
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(out) :: X0, X1
integer*4, intent(in) :: i
!-------------------------------------------------------------------------------------------
real*8 :: LT2
!-------------------------------------------------------------------------------------------
LT2 = 0.5d+00 * LT(i)
X0 = CT(i,0:2) - LT2 * DT(i,0:2)
X1 = CT(i,0:2) + LT2 * DT(i,0:2)
end subroutine GetTubeEnds !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
logical function IsTubeInside ( i ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns true if nanotube i lies inside the sample. Otherwise it returns false.
!-------------------------------------------------------------------------------------------
integer*4, intent(in) :: i
!-------------------------------------------------------------------------------------------
integer*4 :: n
real*8, dimension(0:2) :: X0, X1, Xmin, Xmax
!-------------------------------------------------------------------------------------------
IsTubeInside = .true.
if ( BC_X == 1 .and. BC_Y == 1 .and. BC_Z == 1 ) return
call GetTubeEnds ( X0, X1, i )
do n = 0, 2
Xmin(n) = min ( X0(n), X1(n) )
Xmax(n) = max ( X0(n), X1(n) )
end do
IsTubeInside = .false.
if ( BC_X == 0 .and. ( Xmin(0) < DomXmin .or. Xmax(0) > DomXmax ) ) return
if ( BC_Y == 0 .and. ( Xmin(1) < DomYmin .or. Xmax(1) > DomYmax ) ) return
if ( BC_Z == 0 .and. ( Xmin(2) < DomZmin .or. Xmax(2) > DomZmax ) ) return
IsTubeInside = .true.
end function IsTubeInside !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TMDGenData !*****************************************************************************

View File

@ -0,0 +1,45 @@
newton on
log cnt.log
echo both
units metal
lattice sc 1.0
boundary p p fs
neighbor 1.0 bin
neigh_modify every 5 delay 0 check yes
atom_style cnt
#cut, RT, STRMode, BendingMode, STRParams, YMType, TPMType, TPMSSTP.xrs, TPMA.xrs
pair_style cnt/cnt 45.0 6.785 1 0 3 0 0 ../../../potentials/TPMSSTP.xrs ../../../potentials/TPMA.xrs
read_data TMDSample.init
pair_coeff * *
velocity all create 600.0 2019
timestep 0.010
fix 1 all nve
#fix 1 all nvt temp 300.0 300.0 1.0
thermo_modify flush yes
thermo 1
reset_timestep 0
compute Es all cnt/Es
compute Eb all cnt/Eb
compute Et all cnt/Et
compute Ek all ke/atom
compute Es_tot all cnt/Es_tot
compute Eb_tot all cnt/Eb_tot
compute Et_tot all cnt/Et_tot
compute Ep_tot all pe
compute Ek_tot all ke
variable time_ equal time
variable Ep_ equal c_Ep_tot
variable Ek_ equal c_Ek_tot
variable Etot_ equal v_Ek_+v_Ep_
variable Es_ equal c_Es_tot
variable Eb_ equal c_Eb_tot
variable Et_ equal c_Et_tot
dump out_dump all custom 50 config_E.dump id type x y z c_Es c_Eb c_Et c_Ek ix iy iz
fix out_info all print 10 "${time_} ${Etot_} ${Ek_} ${Ep_} ${Es_} ${Eb_} ${Et_}" file "E.txt" screen no
run 50
write_data system_E.data

View File

@ -0,0 +1,144 @@
module TPMGeom !************************************************************************************
!
! Geometry functions for TPM force field
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, 2020, Version 13.00
!
!***************************************************************************************************
use TPMLib
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
integer*4, parameter :: MD_LINES_NONPAR = 0
integer*4, parameter :: MD_LINES_PAR = 1
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
! Coordinates of the whole domain
real*8 :: DomXmin, DomXmax, DomYmin, DomYmax, DomZmin, DomZmax
real*8 :: DomLX, DomLY, DomLZ
real*8 :: DomLXhalf, DomLYhalf, DomLZhalf
! Boundary conditions
integer*4 :: BC_X = 0
integer*4 :: BC_Y = 0
integer*4 :: BC_Z = 0
! Skin parameter in NBL and related algorithms
real*8 :: Rskin = 1.0d+00
contains !******************************************************************************************
subroutine ApplyPeriodicBC ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This subroutine changes coortinates of the point accorning to periodic boundary conditions
! it order to makesure that the point is inside the computational cell
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(inout) :: R
!-------------------------------------------------------------------------------------------
! These commented lines implemment the more general, but less efficient algorithm
!if ( BC_X == 1 ) R(0) = R(0) - DomLX * roundint ( R(0) / DomLX )
!if ( BC_Y == 1 ) R(1) = R(1) - DomLY * roundint ( R(1) / DomLY )
!if ( BC_Z == 1 ) R(2) = R(2) - DomLZ * roundint ( R(2) / DomLZ )
if ( BC_X == 1 ) then
if ( R(0) .GT. DomLXHalf ) then
R(0) = R(0) - DomLX
else if ( R(0) .LT. - DomLXHalf ) then
R(0) = R(0) + DomLX
end if
end if
if ( BC_Y == 1 ) then
if ( R(1) .GT. DomLYHalf ) then
R(1) = R(1) - DomLY
else if ( R(1) .LT. - DomLYHalf ) then
R(1) = R(1) + DomLY
end if
end if
if ( BC_Z == 1 ) then
if ( R(2) .GT. DomLZHalf ) then
R(2) = R(2) - DomLZ
else if ( R(2) .LT. - DomLZHalf ) then
R(2) = R(2) + DomLZ
end if
end if
end subroutine ApplyPeriodicBC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine LinePoint ( Displacement, Q, R1, L1, R0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function calculates the point Q of projection of point R0 on line (R1,L1)
! Q = R1 + Disaplacement * L1
!-------------------------------------------------------------------------------------------
real*8, intent(inout) :: Displacement
real*8, dimension(0:2), intent(inout) :: Q
real*8, dimension(0:2), intent(in) :: R1, L1, R0
!--------------------------------------------------------------------------------------------
Q = R0 - R1
! Here we take into account periodic boundaries
call ApplyPeriodicBC ( Q )
Displacement = S_V3xV3 ( Q, L1 )
Q = R1 + Displacement * L1
end subroutine LinePoint !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function LineLine ( H, cosA, D1, D2, L12, R1, L1, R2, L2, Prec ) !!!!!!!!!!!!!!!!!
! This function determines the neares distance H between two lines (R1,L1) and (R2,L2)
!-------------------------------------------------------------------------------------------
! Input values:
! R1, L1, point and direction of line 1
! R2, L2, point and direction of line 2
! Prec, precision for the case L1 * L2 = 0 (parallel lines)
! Return values:
! H, minimal distance between lines
! cosA, cosine of angle between lines
! D1, D2, displacemets
! L12, unit vector directed along the closes distance
!-------------------------------------------------------------------------------------------
real*8, intent(inout) :: H, cosA, D1, D2
real*8, dimension(0:2), intent(out) :: L12
real*8, dimension(0:2), intent(in) :: R1, L1, R2, L2
!-------------------------------------------------------------------------------------------
real*8, intent(in) :: Prec
real*8, dimension(0:2) :: Q1, Q2, R
real*8 :: C, DD1, DD2, C1, C2
!-------------------------------------------------------------------------------------------
cosA = S_V3xV3 ( L1, L2 )
C = 1.0 - sqr ( cosA )
if ( C < Prec ) then ! Lines are parallel to each other
LineLine = MD_LINES_PAR
return
end if
LineLine = MD_LINES_NONPAR
R = R2 - R1
! Here we take into account periodic boundaries
call ApplyPeriodicBC ( R )
DD1 = S_V3xV3 ( R, L1 )
DD2 = S_V3xV3 ( R, L2 )
D1 = ( cosA * DD2 - DD1 ) / C
D2 = ( DD2 - cosA * DD1 ) / C
Q1 = R1 - D1 * L1
Q2 = R2 - D2 * L2
L12 = Q2 - Q1
! Here we take into account periodic boundaries
call ApplyPeriodicBC ( L12 )
H = S_V3norm3 ( L12 )
if ( H < Prec ) then ! Lines intersect each other
C1 = signum ( D1 )
C2 = signum ( D1 ) * signum ( cosA )
Q1 = C1 * L1
Q2 = C2 * L2
call V3_V3xxV3 ( L12, Q1, Q2 )
call V3_ort ( L12 )
else ! No intersection
L12 = L12 / H
end if
end function LineLine !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMGeom !********************************************************************************

View File

@ -0,0 +1,205 @@
module TPMLib !*************************************************************************************
!
! Common constants, types, and functions for TPM force field
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, 2020, Version 13.00
!
!***************************************************************************************************
implicit none
!---------------------------------------------------------------------------------------------------
! Mathematical constants
!---------------------------------------------------------------------------------------------------
real*8, parameter :: M_PI_2 = 1.57079632679489661923
real*8, parameter :: M_PI = 3.14159265358979323846
real*8, parameter :: M_3PI_2 = 4.71238898038468985769
real*8, parameter :: M_2PI = 6.28318530717958647692
real*8, parameter :: M_PI_180 = 0.017453292519943295769
!---------------------------------------------------------------------------------------------------
! Physical unit constants
!---------------------------------------------------------------------------------------------------
real*8, parameter :: K_AMU = 1.66056E-27 ! a.m.u. (atomic mass unit, Dalton)
real*8, parameter :: K_EV = 1.60217646e-19 ! eV (electron-volt)
real*8, parameter :: K_MDLU = 1.0E-10 ! MD length unit (m)
real*8, parameter :: K_MDEU = K_EV ! MD energy unit (J)
real*8, parameter :: K_MDMU = K_AMU ! MD mass unit (kg)
real*8, parameter :: K_MDFU = K_MDEU / K_MDLU ! MD force unit (N)
real*8, parameter :: K_MDCU = K_MDEU / K_MDMU ! MD specific heat unit (J/(kg*K))
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
integer*4 :: StdUID = 31
contains !******************************************************************************************
!---------------------------------------------------------------------------------------------------
! Simple mathematical functions
!---------------------------------------------------------------------------------------------------
real*8 function rad ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: X
!-------------------------------------------------------------------------------------------
rad = X * M_PI_180
end function rad !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function sqr ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: X
!-------------------------------------------------------------------------------------------
sqr = X * X
end function sqr !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function signum ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: X
!-------------------------------------------------------------------------------------------
if ( X > 0 ) then
signum = 1
else if ( X < 0 ) then
signum = -1
else
signum = 0
end if
end function signum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Vector & matrix functions
!---------------------------------------------------------------------------------------------------
real*8 function S_V3xx ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(in) :: V
!-------------------------------------------------------------------------------------------
S_V3xx = V(0) * V(0) + V(1) * V(1) + V(2) * V(2)
end function S_V3xx !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function S_V3xV3 ( V1, V2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(in) :: V1, V2
!-------------------------------------------------------------------------------------------
S_V3xV3 = V1(0) * V2(0) + V1(1) * V2(1) + V1(2) * V2(2)
end function S_V3xV3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function S_V3norm3 ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(in) :: V
!-------------------------------------------------------------------------------------------
S_V3norm3 = dsqrt ( V(0) * V(0) + V(1) * V(1) + V(2) * V(2) )
end function S_V3norm3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine V3_ort ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Vector production
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(inout) :: V
!-------------------------------------------------------------------------------------------
real*8 :: Vabs
!-------------------------------------------------------------------------------------------
Vabs = S_V3norm3 ( V )
V(0) = V(0) / Vabs
V(1) = V(1) / Vabs
V(2) = V(2) / Vabs
end subroutine V3_ort !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine V3_V3xxV3 ( V, V1, V2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Vector production
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(out) :: V
real*8, dimension(0:2), intent(in) :: V1, V2
!-------------------------------------------------------------------------------------------
V(0) = V1(1) * V2(2) - V1(2) * V2(1)
V(1) = V1(2) * V2(0) - V1(0) * V2(2)
V(2) = V1(0) * V2(1) - V1(1) * V2(0)
end subroutine V3_V3xxV3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Handling of spherical and Euler angles
!---------------------------------------------------------------------------------------------------
subroutine RotationMatrix3 ( M, Psi, Tet, Phi ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Ksi, Tet and Phi are Euler angles
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2,0:2), intent(out) :: M
real*8, intent(in) :: Psi, Tet, Phi
!-------------------------------------------------------------------------------------------
real*8 :: cK, sK, cT, sT, cP, sP
!-------------------------------------------------------------------------------------------
cK = dcos ( Psi )
sK = dsin ( Psi )
cT = dcos ( Tet )
sT = dsin ( Tet )
cP = dcos ( Phi )
sP = dsin ( Phi )
M(0,0) = cP * cK - sK * sP * cT
M(0,1) = cP * sK + sP * cT * cK
M(0,2) = sP * sT
M(1,0) = - sP * cK - cP * cT * sK
M(1,1) = - sP * sK + cP * cT * cK
M(1,2) = cP * sT
M(2,0) = sT * sK
M(2,1) = - sT * cK
M(2,2) = cT
end subroutine RotationMatrix3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine EulerAngles ( Psi, Tet, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(out) :: Tet, Psi
real*8, dimension(0:2), intent(in) :: L
!-------------------------------------------------------------------------------------------
Tet = acos ( L(2) )
Psi = atan2 ( L(1), L(0) )
if ( Psi > M_3PI_2 ) then
Psi = Psi - M_3PI_2
else
Psi = Psi + M_PI_2
end if
end subroutine EulerAngles !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! File inout and output
!---------------------------------------------------------------------------------------------------
integer*4 function OpenFile ( Name, Params, Path ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
character*(*), intent(in) :: Name, Params, Path
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid
character*512 :: FullName, Msg, Name1, Action1, Status1, Form1, Position1
!-------------------------------------------------------------------------------------------
OpenFile = StdUID + 1
if ( Params(1:1) == 'r' ) then
Action1 = 'read'
Status1 = 'old'
Position1 = 'rewind'
else if ( Params(1:1) == 'w' ) then
Action1 = 'write'
Status1 = 'replace'
Position1 = 'rewind'
else if ( Params(1:1) == 'a' ) then
Action1 = 'write'
Status1 = 'old'
Position1 = 'append'
endif
if ( Params(2:2) == 'b' ) then
Form1 = 'binary'
else
Form1 = 'formatted'
endif
open ( unit = OpenFile, file = Name, form = Form1, action = Action1, status = Status1, position = Position1 )
StdUID = StdUID + 1
return
end function OpenFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CloseFile ( Fuid ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4, intent(inout) :: Fuid
!-------------------------------------------------------------------------------------------
if ( Fuid < 0 ) return
close ( unit = Fuid )
Fuid = -1
end subroutine CloseFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMLib !*********************************************************************************

View File

@ -0,0 +1,98 @@
module LinFun2 !************************************************************************************
!
! Bi-linear functions and their derivatives.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
implicit none
contains !******************************************************************************************
real*8 function CalcLinFun1_0 ( i, X, N, P, F ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4, intent(in) :: i, N
real*8, intent(in) :: X
real*8, dimension(0:N-1), intent(in) :: P
real*8, dimension(0:N-1), intent(inout) :: F
integer*4 :: i1
real*8 :: A, A0
!-------------------------------------------------------------------------------------------
i1 = i - 1
A0 = ( P(i) - X ) / ( P(i) - P(i1) )
A = 1.0d+00 - A0
CalcLinFun1_0 = A0 * F(i1) + A * F(i)
end function CalcLinFun1_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcLinFun1_1 ( S, Sx1, i, X, N, P, F, Fx ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(out) :: S, Sx1
integer*4, intent(in) :: i, N
real*8, intent(in) :: X
real*8, dimension(0:N-1), intent(in) :: P
real*8, dimension(0:N-1), intent(inout) :: F, Fx
integer*4 :: i1
real*8 :: A, A0
!-------------------------------------------------------------------------------------------
i1 = i - 1
A0 = ( P(i) - X ) / ( P(i) - P(i1) )
A = 1.0d+00 - A0
S = A0 * F(i1) + A * F(i)
Sx1 = A0 * Fx(i1) + A * Fx(i)
end subroutine CalcLinFun1_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function CalcLinFun2_0 ( i, j, X, Y, N1, N2, P1, P2, F ) !!
integer*4, intent(in) :: i, j, N1, N2
real*8, intent(in) :: X, Y
real*8, dimension(0:N1-1), intent(in) :: P1
real*8, dimension(0:N2-1), intent(in) :: P2
real*8, dimension(0:N1-1,0:N2-1), intent(inout) :: F
integer*4 :: i1, j1
real*8 :: A, A0, B, B0, G, G0
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
A0 = ( P1(i) - X ) / ( P1(i) - P1(i1) )
A = 1.0d+00 - A0
B0 = ( P2(j) - Y ) / ( P2(j) - P2(j1) )
B = 1.0d+00 - B0
G = B0 * F(i,j1) + B * F(i,j)
G0 = B0 * F(i1,j1) + B * F(i1,j)
CalcLinFun2_0 = A0 * G0 + A * G
end function CalcLinFun2_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcLinFun2_1 ( S, Sx1, Sy1, i, j, X, Y, N1, N2, P1, P2, F, Fx, Fy ) !!!!!!!!!!!!
real*8, intent(out) :: S, Sx1, Sy1
integer*4, intent(in) :: i, j, N1, N2
real*8, intent(in) :: X, Y
real*8, dimension(0:N1-1), intent(in) :: P1
real*8, dimension(0:N2-1), intent(in) :: P2
real*8, dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fx, Fy
integer*4 :: i1, j1
real*8 :: A, A0, B, B0, G, G0
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
A0 = ( P1(i) - X ) / ( P1(i) - P1(i1) )
A = 1.0d+00 - A0
B0 = ( P2(j) - Y ) / ( P2(j) - P2(j1) )
B = 1.0d+00 - B0
G = B0 * F(i,j1) + B * F(i,j)
G0 = B0 * F(i1,j1) + B * F(i1,j)
S = A0 * G0 + A * G
G = B0 * Fx(i,j1) + B * Fx(i,j)
G0 = B0 * Fx(i1,j1) + B * Fx(i1,j)
Sx1 = A0 * G0 + A * G
G = B0 * Fy(i,j1) + B * Fy(i,j)
G0 = B0 * Fy(i1,j1) + B * Fy(i1,j)
Sy1 = A0 * G0 + A * G
end subroutine CalcLinFun2_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module LinFun2 !********************************************************************************

View File

@ -0,0 +1,35 @@
#---------------------------------------------------------------------------------------------------
#
# This is Makefile for builing the executable TMDPotGen
#
# Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, 2020, Version 13.00
#
#---------------------------------------------------------------------------------------------------
EXEPATH = .
F90 = ifort
F90FLAGS = -Ofast -mcmodel=medium
#F90 = pgf90
#F90FLAGS = -fast -mcmodel=medium
LDFLAGS =
OBJS = TPMLib.o LinFun2.o Spline1.o Spline2.o TPMGeom.o TubePotBase.o TubePotTrue.o TubePotMono.o TMDPotGen.o
EXE = $(EXEPATH)/TMDPotGen
# compile and load
default:
@echo " "
@echo "Compiling Code of Program TMDPotGen"
@echo "FORTRAN 90"
$(MAKE) $(EXE)
$(EXE): $(OBJS)
$(F90) $(F90FLAGS) $(LDFLAGS) -o $(EXE) $(OBJS)
.SUFFIXES: .f90 .o
.f90.o:
$(F90) $(F90FLAGS) -c $*.f90
clean:
rm -f *.o

View File

@ -0,0 +1,177 @@
module Spline1 !************************************************************************************
!
! One-dimensional cubic spline function.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
implicit none
contains !******************************************************************************************
real*8 function ValueSpline1_0 ( X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1 ) !!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1
real*8 :: H26, HL, HR
!-------------------------------------------------------------------------------------------
H26 = Hi_1 * Hi_1 / 6.0
Hl = X - Xi_1
Hr = Xi - X
ValueSpline1_0 = ( ( Mi_1 * Hr * Hr * Hr + Mi * Hl * Hl * Hl ) / 6.0 + ( Yi_1 - Mi_1 * H26 ) * Hr &
+ ( Yi - Mi * H26 ) * Hl ) / Hi_1
end function ValueSpline1_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine ValueSpline1_1 ( S, S1, X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1 ) !!!!!!!!!!!!!!!!!
real*8, intent(out) :: S, S1
real*8, intent(in) :: X, Xi, Xi_1, Yi, Yi_1, Mi, Mi_1, Hi_1
real*8 :: H6, H26, HL, HR, HL2, HR2
!-------------------------------------------------------------------------------------------
H6 = Hi_1 / 6.0d+00
H26 = Hi_1 * H6
HL = X - Xi_1
HR = Xi - X
HL2 = HL * HL
HR2 = HR * HR
S = ( ( Mi_1 * HR2 * Hr + Mi * HL2 * Hl ) / 6.0 + ( Yi_1 - Mi_1 * H26 ) * HR + ( Yi - Mi * H26 ) * HL ) / Hi_1
S1 = ( ( Mi * HL2 - Mi_1 * HR2 ) / 2.0d+00 + Yi - Yi_1 ) / Hi_1 - H6 * ( Mi - Mi_1 )
end subroutine ValueSpline1_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine sprogonka3 ( N, K0, K1, K2, F, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4, intent(in) :: N
real*8, dimension(0:N-1), intent(in) :: K0, K1, K2
real*8, dimension(0:N-1), intent(inout) :: F, X
real*8 :: D
integer*4 :: i
!-------------------------------------------------------------------------------------------
X(0) = F(0) / K1(0)
F(0) = - K2(0) / K1(0)
do i = 1, N - 1
D = - ( K1(i) + F(i-1) * K0(i) )
X(i) = ( K0(i) * X(i-1) - F(i) ) / D
F(i) = K2(i) / D
end do
do i = N - 2, 0, -1
X(i) = X(i) + F(i) * X(i+1)
end do
end subroutine sprogonka3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CreateSpline1 ( CL, CR, N, P, F, M, D, K0, K1, K2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4, intent(in) :: CL, CR, N
real*8, dimension (0:N-1), intent(in) :: P, F
real*8, dimension (0:N-1), intent(inout):: M, D, K0, K1, K2
integer*4 :: i
real*8 :: Z
!-------------------------------------------------------------------------------------------
do i = 1, N - 1
K0(i) = P(i) - P(i-1)
K1(i) = ( F(i) - F(i-1) ) / K0(i)
end do
select case ( CL )
case (1)
K1(0) = 2.0d+00 / 3.0d+00
K2(0) = 1.0d+00 / 3.0d+00
D (0) = 2 * ( K1(1) - M(0) ) / K0(1)
case (2)
K1(0) = 1.0d+00
K2(0) = 0.0d+00
D(0) = M(0)
case (3)
K1(0) = 1.0d+00
K2(0) = 0.0d+00
D(0) = 0.0d+00
end select
Z = K1(N-1)
do i = 1, N - 2
D(i) = 6.0d+00 * ( K1(i+1) - K1(i) )
K2(i) = K0(i+1)
K1(i) = 2.0d+00 * ( K2(i) + K0(i) )
end do
select case ( CR )
case (1)
D(N-1) = 2.0d+00 * ( M(N-1) - Z ) / K0(N-1)
K1(N-1) = 2.0d+00 / 3.0d+00
K0(N-1) = 1.0d+00 / 3.0d+00
case (2)
K1(N-1) = 1.0d+00
K0(N-1) = 0.0d+00
D(N-1) = M(N-1)
case (3)
K1(N-1) = 1.0d+00
K0(N-1) = 0.0d+00
D(N-1) = 0.0d+00
end select
call sprogonka3 ( N, K0, K1, K2, D, M )
end subroutine CreateSpline1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function CalcSpline1_0 ( i, X, N, P, F, M ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4, intent(in) :: i, N
real*8, intent(in) :: X
real*8, dimension(0:N-1), intent(in) :: P, F, M
integer*4 :: j
real*8 :: HL, HR, H, H6, H26, HR2, HL2, HRH, HLH
!-------------------------------------------------------------------------------------------
j = i - 1
HL = X - P(j)
HR = P(i) - X
H = P(i) - P(j)
H6 = H / 6.0d+00
H26 = H * H6
HL2 = HL * HL
HR2 = HR * HR
HLH = HL / H
HRH = HR / H
CalcSpline1_0 = ( M(j) * HR2 * HRH + M(i) * HL2 * HLH ) / 6.0d+00 + ( F(j) - M(j) * H26 ) * HRH &
+ ( F(i) - M(i) * H26 ) * HLH
end function CalcSpline1_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcSpline1_1 ( S, S1, i, X, N, P, F, M ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(out) :: S, S1
integer*4, intent(in) :: i, N
real*8, intent(in) :: X
real*8, dimension(0:N-1), intent(in) :: P, F, M
integer*4 :: j
real*8 :: HL, HR, H, H6, H26, HR2, HL2, HRH, HLH
!-------------------------------------------------------------------------------------------
j = i - 1
HL = X - P(j)
HR = P(i) - X
H = P(i) - P(j)
H6 = H / 6.0d+00
H26 = H * H6
HL2 = HL * HL
HR2 = HR * HR
HLH = HL / H
HRH = HR / H
S = ( M(j) * HR2 * HRH + M(i) * HL2 * HLH ) / 6.0d+00 + ( F(j) - M(j) * H26 ) * HRH + ( F(i) - M(i) * H26 ) * HLH
S1 = ( ( M(i) * HL2 - M(j) * HR2 ) / 2.0d+00 + F(i) - F(j) ) / H - H6 * ( M(i) - M(j) )
end subroutine CalcSpline1_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcSpline1_2 ( S, S1, S2, i, X, N, P, F, M ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(out) :: S, S1, S2
integer*4, intent(in) :: i, N
real*8, intent(in) :: X
real*8, dimension(0:N-1), intent(in) :: P, F, M
integer*4 :: j
real*8 :: HL, HR, H, H6, H26, HR2, HL2, HRH, HLH
!-------------------------------------------------------------------------------------------
j = i - 1
HL = X - P(j)
HR = P(i) - X
H = P(i) - P(j)
H6 = H / 6.0d+00
H26 = H * H6
HL2 = HL * HL
HR2 = HR * HR
HLH = HL / H
HRH = HR / H
S = ( M(j) * HR2 * HRH + M(i) * HL2 * HLH ) / 6.0d+00 + ( F(j) - M(j) * H26 ) * HRH + ( F(i) - M(i) * H26 ) * HLH
S1 = ( ( M(i) * HL2 - M(j) * HR2 ) / 2.0d+00 + F(i) - F(j) ) / H - H6 * ( M(i) - M(j) )
S2 = M(j) * HRH + M(i) * HLH
end subroutine CalcSpline1_2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module Spline1 !********************************************************************************

View File

@ -0,0 +1,171 @@
module Spline2 !************************************************************************************
!
! Two-dimensional cubic spline function.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 09.01, 2017
!
!***************************************************************************************************
use Spline1
implicit none
contains !******************************************************************************************
subroutine CreateSpline2 ( CL, CD, CR, CU, N1, N2, N, P1, P2, F, Fxx, Fyy, Fxxyy, FF, MM, DD, K0, K1, K2 )
integer*4, intent(in) :: CL, CD, CR, CU, N1, N2, N
real*8, dimension(0:N1-1), intent(in) :: P1
real*8, dimension(0:N2-1), intent(in) :: P2
real*8, dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
real*8, dimension(0:N-1), intent(inout) :: FF, MM, DD, K0, K1, K2
integer*4 :: II
!-------------------------------------------------------------------------------------------
do II = 0, N2 - 1
FF(0:N1-1) = F(0:N1-1,II)
MM(0) = Fxx(0,II)
MM(N1-1) = Fxx(N1-1,II)
call CreateSpline1 ( CL, CR, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxx(0:N1-1,II) = MM(0:N1-1)
end do
do II = 0, N1 - 1
MM(0) = Fyy(II,0)
MM(N-1) = Fyy(II,N2-1)
FF(0:N2-1) = F(II,0:N2-1)
call CreateSpline1 ( CD, CU, N2, P2, FF, MM, DD, K0, K1, K2 )
Fyy(II,0:N2-1) = MM(0:N2-1)
end do
FF(0:N1-1) = Fyy(0:N1-1,0 )
call CreateSpline1 ( 3, 3, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(0:N1-1,0) = MM(0:N1-1)
FF(0:N1-1) = Fyy(0:N1-1,N2-1 )
call CreateSpline1 ( 3, 3, N1, P1, FF, MM, DD, K0, K1, k2 )
Fxxyy(0:N1-1,N2-1) = MM(0:N1-1)
do II = 1, N1 - 2
MM(0) = Fxxyy(II,0)
MM(N-1) = Fxxyy(II,N2-1)
FF(0:N2-1) = Fxx(II,0:N2-1)
call CreateSpline1 ( 2 , 2, N2, P2, FF, MM, DD, K0, K1, K2 )
Fxxyy(II,0:N2-1) = MM(0:N2-1)
end do
end subroutine CreateSpline2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CreateSpline2Ext ( CL, CD, CR, CU, N1, N1A, N2, N2A, N, P1, P2, F, Fxx, Fyy, Fxxyy, FF, MM, DD, K0, K1, K2 )
integer*4, intent(in) :: CL, CD, CR, CU, N1, N1A, N2, N2A, N
real*8, dimension(0:N1-1), intent(in) :: P1
real*8, dimension(0:N2-1), intent(in) :: P2
real*8, dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
real*8, dimension(0:N-1), intent(inout) :: FF, MM, DD, K0, K1, K2
integer*4 :: II
!-------------------------------------------------------------------------------------------
Fxx = 0.0d+00
Fyy = 0.0d+00
Fxxyy = 0.0d+00
do II = 0, N2A
FF(0:N1-1) = F(0:N1-1,II)
MM(0) = Fxx(0,II)
MM(N1-1) = Fxx(N1-1,II)
call CreateSpline1 ( CL, CR, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxx(0:N1-1,II) = MM(0:N1-1)
end do
do II = N2A + 1, N2 - 1
FF(0:N1-N1A-1) = F(N1A:N1-1,II)
MM(0) = Fxx(N1A,II)
MM(N1-N1A-1) = Fxx(N1-1,II)
call CreateSpline1 ( CL, CR, N1 - N1A, P1, FF, MM, DD, K0, K1, K2 )
Fxx(N1A:N1-1,II) = MM(0:N1-N1A-1)
end do
do II = 0, N1A - 1
MM(0) = Fyy(II,0)
MM(N2A) = Fyy(II,N2A)
FF(0:N2A) = F(II,0:N2A)
call CreateSpline1 ( CD, CU, N2A + 1, P2, FF, MM, DD, K0, K1, K2 )
Fyy(II,0:N2A) = MM(0:N2A)
end do
do II = N1A, N1 - 1
MM(0) = Fyy(II,0)
MM(N-1) = Fyy(II,N2-1)
FF(0:N2-1) = F(II,0:N2-1)
call CreateSpline1 ( CD, CU, N2, P2, FF, MM, DD, K0, K1, K2 )
Fyy(II,0:N2-1) = MM(0:N2-1)
end do
FF(0:N1-1) = Fyy(0:N1-1,0)
call CreateSpline1 ( 3, 3, N1, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(0:N1-1,0) = MM(0:N1-1)
FF(0:N1A) = Fyy(0:N1A,N2A)
call CreateSpline1 ( 3, 3, N1A + 1, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(0:N1A,N2A) = MM(0:N1A)
FF(0:N1-N1A-1) = Fyy(N1A:N1-1,N2-1 )
call CreateSpline1 ( 3, 3, N1-N1A, P1, FF, MM, DD, K0, K1, K2 )
Fxxyy(N1A:N1-1,N2-1) = MM(0:N1-N1A-1)
do II = 1, N1A
MM(0) = Fxxyy(II,0)
MM(N2A) = Fxxyy(II,N2A)
FF(0:N2A) = Fxx(II,0:N2A)
call CreateSpline1 ( 2 , 2, N2A + 1, P2, FF, MM, DD, K0, K1, K2 )
Fxxyy(II,0:N2A) = MM(0:N2A)
end do
do II = N1A + 1, N1 - 2
MM(0) = Fxxyy(II,0)
MM(N-1) = Fxxyy(II,N2-1)
FF(0:N2-1) = Fxx(II,0:N2-1)
call CreateSpline1 ( 2 , 2, N2, P2, FF, MM, DD, K0, K1, K2 )
Fxxyy(II,0:N2-1) = MM(0:N2-1)
end do
end subroutine CreateSpline2Ext !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function CalcSpline2_0 ( i, j, X, Y, N1, N2, P1, P2, F, Fxx, Fyy, Fxxyy ) !!!!!!!!!!!
integer*4, intent(in) :: i, j, N1, N2
real*8, intent(in) :: X, Y
real*8, dimension(0:N1-1), intent(in) :: P1
real*8, dimension(0:N2-1), intent(in) :: P2
real*8, dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
integer*4 :: i1, j1
real*8 :: T, Gy_0, Gy_1, Gxxy_0, Gxxy_1
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
T = P2(j) - P2(j1)
Gy_0 = ValueSpline1_0 ( Y, P2(j), P2(j1), F(i,j), F(i,j1), Fyy(i,j), Fyy(i,j1), T )
Gy_1 = ValueSpline1_0 ( Y, P2(j), P2(j1), F(i1,j), F(i1,j1), Fyy(i1,j), Fyy(i1,j1), T )
Gxxy_0 = ValueSpline1_0 ( Y, P2(j), P2(j1), Fxx(i,j), Fxx(i,j1), Fxxyy(i,j), Fxxyy(i,j1), T )
Gxxy_1 = ValueSpline1_0 ( Y, P2(j), P2(j1), Fxx(i1,j), Fxx(i1,j1), Fxxyy(i1,j), Fxxyy(i1,j1), T )
CalcSpline2_0 = ValueSpline1_0 ( X, P1(i), P1(i1), Gy_0, Gy_1,Gxxy_0, Gxxy_1, P1(i) - P1(i1) )
end function CalcSpline2_0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CalcSpline2_1 ( S, Sx1, Sy1, i, j, X, Y, N1, N2, P1, P2, F, Fxx, Fyy, Fxxyy ) !!!
real*8, intent(out) :: S, Sx1, Sy1
integer*4, intent(in) :: i, j, N1, N2
real*8, intent(in) :: X, Y
real*8, dimension(0:N1-1), intent(in) :: P1
real*8, dimension(0:N2-1), intent(in) :: P2
real*8, dimension(0:N1-1,0:N2-1), intent(inout) :: F, Fxx, Fyy, Fxxyy
integer*4 :: i1, j1
real*8 :: T, Gy_0, Gy_1, Gxxy_0, Gxxy_1
real*8 :: Gyy_0, Gyy_1, Gxxyy_0, Gxxyy_1
!-------------------------------------------------------------------------------------------
i1 = i - 1
j1 = j - 1
T = P2(j) - P2(j1)
call ValueSpline1_1 ( Gy_0, Gyy_0, Y, P2(j), P2(j1), F(i,j), F(i,j1), Fyy(i,j), Fyy(i,j1), T )
call ValueSpline1_1 ( Gy_1, Gyy_1, Y, P2(j), P2(j1), F(i1,j), F(i1,j1), Fyy(i1,j), Fyy(i1,j1), T )
call ValueSpline1_1 ( Gxxy_0, Gxxyy_0, Y, P2(j), P2(j1), Fxx(i,j), Fxx(i,j1), Fxxyy(i,j), Fxxyy(i,j1), T )
call ValueSpline1_1 ( Gxxy_1, Gxxyy_1, Y, P2(j), P2(j1), Fxx(i1,j), Fxx(i1,j1), Fxxyy(i1,j), Fxxyy(i1,j1), T )
call ValueSpline1_1 ( S, Sx1, X, P1(i), P1(i1), Gy_0, Gy_1,Gxxy_0, Gxxy_1, P1(i) - P1(i1) )
Sy1 = ValueSpline1_0 ( X, P1(i), P1(i1), Gyy_0, Gyy_1,Gxxyy_0, Gxxyy_1, P1(i) - P1(i1) )
end subroutine CalcSpline2_1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module Spline2 !********************************************************************************

View File

@ -0,0 +1,62 @@
program TMDPotGen !*********************************************************************************
!
! Stand-alone generator of files containing tubular potential data for single-walled CNTs.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!***************************************************************************************************
use TubePotMono
implicit none
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
integer*4 :: ChiIndM = 10 ! Chirality index m of nanotubes
integer*4 :: ChiIndN = 10 ! Chirality index n of nanotubes
!---------------------------------------------------------------------------------------------------
! Body
!---------------------------------------------------------------------------------------------------
TPMStartMode = 0
! Reading and printing of governing parameters
call LoadGoverningParameters ()
call PrintGoverningParameters ()
call TPBInit ()
call TPMInit ( ChiIndM, ChiIndN )
contains !------------------------------------------------------------------------------------------
subroutine LoadGoverningParameters () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function reads governing parameters from xdt file
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid, i
character*512 :: Msg
!-------------------------------------------------------------------------------------------
Fuid = OpenFile ( 'TMDPotGen.xdt', 'rt', '' )
read ( unit = Fuid, fmt = '(i22)' ) ChiIndM
read ( unit = Fuid, fmt = '(i22)' ) ChiIndN
call CloseFile ( Fuid )
end subroutine LoadGoverningParameters !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine PrintGoverningParameters () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function prints governing parameters to xlg file
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid, i
!-------------------------------------------------------------------------------------------
Fuid = OpenFile ( 'TMDPotGen.xlg', 'wt', '' )
write ( unit = Fuid, fmt = '(i22,a)' ) ChiIndM, ' : ChiIndM'
write ( unit = Fuid, fmt = '(i22,a)' ) ChiIndN, ' : ChiIndN'
call CloseFile ( Fuid )
end subroutine PrintGoverningParameters !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end program TMDPotGen !*****************************************************************************

View File

@ -0,0 +1,2 @@
10 : ChiIndM
10 : ChiIndN

View File

@ -0,0 +1,144 @@
module TPMGeom !************************************************************************************
!
! Geometry functions for TPM force field.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!***************************************************************************************************
use TPMLib
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
integer*4, parameter :: MD_LINES_NONPAR = 0
integer*4, parameter :: MD_LINES_PAR = 1
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
! Coordinates of the whole domain
real*8 :: DomXmin, DomXmax, DomYmin, DomYmax, DomZmin, DomZmax
real*8 :: DomLX, DomLY, DomLZ
real*8 :: DomLXhalf, DomLYhalf, DomLZhalf
! Boundary conditions
integer*4 :: BC_X = 0
integer*4 :: BC_Y = 0
integer*4 :: BC_Z = 0
! Skin parameter in NBL and related algorithms
real*8 :: Rskin = 1.0d+00
contains !******************************************************************************************
subroutine ApplyPeriodicBC ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This subroutine changes coordinates of the point according to periodic boundary conditions
! it order to make sure that the point is inside the computational cell
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(inout) :: R
!-------------------------------------------------------------------------------------------
! These commented lines implement the more general, but less efficient algorithm
!if ( BC_X == 1 ) R(0) = R(0) - DomLX * roundint ( R(0) / DomLX )
!if ( BC_Y == 1 ) R(1) = R(1) - DomLY * roundint ( R(1) / DomLY )
!if ( BC_Z == 1 ) R(2) = R(2) - DomLZ * roundint ( R(2) / DomLZ )
if ( BC_X == 1 ) then
if ( R(0) .GT. DomLXHalf ) then
R(0) = R(0) - DomLX
else if ( R(0) .LT. - DomLXHalf ) then
R(0) = R(0) + DomLX
end if
end if
if ( BC_Y == 1 ) then
if ( R(1) .GT. DomLYHalf ) then
R(1) = R(1) - DomLY
else if ( R(1) .LT. - DomLYHalf ) then
R(1) = R(1) + DomLY
end if
end if
if ( BC_Z == 1 ) then
if ( R(2) .GT. DomLZHalf ) then
R(2) = R(2) - DomLZ
else if ( R(2) .LT. - DomLZHalf ) then
R(2) = R(2) + DomLZ
end if
end if
end subroutine ApplyPeriodicBC !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine LinePoint ( Displacement, Q, R1, L1, R0 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function calculates the point Q of projection of point R0 on line (R1,L1)
! Q = R1 + Disaplacement * L1
!-------------------------------------------------------------------------------------------
real*8, intent(inout) :: Displacement
real*8, dimension(0:2), intent(inout) :: Q
real*8, dimension(0:2), intent(in) :: R1, L1, R0
!--------------------------------------------------------------------------------------------
Q = R0 - R1
! Here we take into account periodic boundaries
call ApplyPeriodicBC ( Q )
Displacement = S_V3xV3 ( Q, L1 )
Q = R1 + Displacement * L1
end subroutine LinePoint !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function LineLine ( H, cosA, D1, D2, L12, R1, L1, R2, L2, Prec ) !!!!!!!!!!!!!!!!!
! This function determines the nearest distance H between two lines (R1,L1) and (R2,L2)
!-------------------------------------------------------------------------------------------
! Input values:
! R1, L1, point and direction of line 1
! R2, L2, point and direction of line 2
! Prec, precision for the case L1 * L2 = 0 (parallel lines)
! Return values:
! H, minimal distance between lines
! cosA, cosine of angle between lines
! D1, D2, displacements
! L12, unit vector directed along the closes distance
!-------------------------------------------------------------------------------------------
real*8, intent(inout) :: H, cosA, D1, D2
real*8, dimension(0:2), intent(out) :: L12
real*8, dimension(0:2), intent(in) :: R1, L1, R2, L2
!-------------------------------------------------------------------------------------------
real*8, intent(in) :: Prec
real*8, dimension(0:2) :: Q1, Q2, R
real*8 :: C, DD1, DD2, C1, C2
!-------------------------------------------------------------------------------------------
cosA = S_V3xV3 ( L1, L2 )
C = 1.0 - sqr ( cosA )
if ( C < Prec ) then ! Lines are parallel to each other
LineLine = MD_LINES_PAR
return
end if
LineLine = MD_LINES_NONPAR
R = R2 - R1
! Here we take into account periodic boundaries
call ApplyPeriodicBC ( R )
DD1 = S_V3xV3 ( R, L1 )
DD2 = S_V3xV3 ( R, L2 )
D1 = ( cosA * DD2 - DD1 ) / C
D2 = ( DD2 - cosA * DD1 ) / C
Q1 = R1 - D1 * L1
Q2 = R2 - D2 * L2
L12 = Q2 - Q1
! Here we take into account periodic boundaries
call ApplyPeriodicBC ( L12 )
H = S_V3norm3 ( L12 )
if ( H < Prec ) then ! Lines intersect each other
C1 = signum ( D1 )
C2 = signum ( D1 ) * signum ( cosA )
Q1 = C1 * L1
Q2 = C2 * L2
call V3_V3xxV3 ( L12, Q1, Q2 )
call V3_ort ( L12 )
else ! No intersection
L12 = L12 / H
end if
end function LineLine !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMGeom !********************************************************************************

View File

@ -0,0 +1,205 @@
module TPMLib !*************************************************************************************
!
! Common constants, types, and functions for TPM force field.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!***************************************************************************************************
implicit none
!---------------------------------------------------------------------------------------------------
! Mathematical constants
!---------------------------------------------------------------------------------------------------
real*8, parameter :: M_PI_2 = 1.57079632679489661923
real*8, parameter :: M_PI = 3.14159265358979323846
real*8, parameter :: M_3PI_2 = 4.71238898038468985769
real*8, parameter :: M_2PI = 6.28318530717958647692
real*8, parameter :: M_PI_180 = 0.017453292519943295769
!---------------------------------------------------------------------------------------------------
! Physical unit constants
!---------------------------------------------------------------------------------------------------
real*8, parameter :: K_AMU = 1.66056E-27 ! a.m.u. (atomic mass unit, Dalton)
real*8, parameter :: K_EV = 1.60217646e-19 ! eV (electron-volt)
real*8, parameter :: K_MDLU = 1.0E-10 ! MD length unit (m)
real*8, parameter :: K_MDEU = K_EV ! MD energy unit (J)
real*8, parameter :: K_MDMU = K_AMU ! MD mass unit (kg)
real*8, parameter :: K_MDFU = K_MDEU / K_MDLU ! MD force unit (N)
real*8, parameter :: K_MDCU = K_MDEU / K_MDMU ! MD specific heat unit (J/(kg*K))
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
integer*4 :: StdUID = 31
contains !******************************************************************************************
!---------------------------------------------------------------------------------------------------
! Simple mathematical functions
!---------------------------------------------------------------------------------------------------
real*8 function rad ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: X
!-------------------------------------------------------------------------------------------
rad = X * M_PI_180
end function rad !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function sqr ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: X
!-------------------------------------------------------------------------------------------
sqr = X * X
end function sqr !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function signum ( X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: X
!-------------------------------------------------------------------------------------------
if ( X > 0 ) then
signum = 1
else if ( X < 0 ) then
signum = -1
else
signum = 0
end if
end function signum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Vector & matrix functions
!---------------------------------------------------------------------------------------------------
real*8 function S_V3xx ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(in) :: V
!-------------------------------------------------------------------------------------------
S_V3xx = V(0) * V(0) + V(1) * V(1) + V(2) * V(2)
end function S_V3xx !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function S_V3xV3 ( V1, V2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(in) :: V1, V2
!-------------------------------------------------------------------------------------------
S_V3xV3 = V1(0) * V2(0) + V1(1) * V2(1) + V1(2) * V2(2)
end function S_V3xV3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function S_V3norm3 ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(in) :: V
!-------------------------------------------------------------------------------------------
S_V3norm3 = dsqrt ( V(0) * V(0) + V(1) * V(1) + V(2) * V(2) )
end function S_V3norm3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine V3_ort ( V ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Vector production
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(inout) :: V
!-------------------------------------------------------------------------------------------
real*8 :: Vabs
!-------------------------------------------------------------------------------------------
Vabs = S_V3norm3 ( V )
V(0) = V(0) / Vabs
V(1) = V(1) / Vabs
V(2) = V(2) / Vabs
end subroutine V3_ort !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine V3_V3xxV3 ( V, V1, V2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Vector production
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2), intent(out) :: V
real*8, dimension(0:2), intent(in) :: V1, V2
!-------------------------------------------------------------------------------------------
V(0) = V1(1) * V2(2) - V1(2) * V2(1)
V(1) = V1(2) * V2(0) - V1(0) * V2(2)
V(2) = V1(0) * V2(1) - V1(1) * V2(0)
end subroutine V3_V3xxV3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Handling of spherical and Euler angles
!---------------------------------------------------------------------------------------------------
subroutine RotationMatrix3 ( M, Psi, Tet, Phi ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! Ksi, Tet and Phi are Euler angles
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2,0:2), intent(out) :: M
real*8, intent(in) :: Psi, Tet, Phi
!-------------------------------------------------------------------------------------------
real*8 :: cK, sK, cT, sT, cP, sP
!-------------------------------------------------------------------------------------------
cK = dcos ( Psi )
sK = dsin ( Psi )
cT = dcos ( Tet )
sT = dsin ( Tet )
cP = dcos ( Phi )
sP = dsin ( Phi )
M(0,0) = cP * cK - sK * sP * cT
M(0,1) = cP * sK + sP * cT * cK
M(0,2) = sP * sT
M(1,0) = - sP * cK - cP * cT * sK
M(1,1) = - sP * sK + cP * cT * cK
M(1,2) = cP * sT
M(2,0) = sT * sK
M(2,1) = - sT * cK
M(2,2) = cT
end subroutine RotationMatrix3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine EulerAngles ( Psi, Tet, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(out) :: Tet, Psi
real*8, dimension(0:2), intent(in) :: L
!-------------------------------------------------------------------------------------------
Tet = acos ( L(2) )
Psi = atan2 ( L(1), L(0) )
if ( Psi > M_3PI_2 ) then
Psi = Psi - M_3PI_2
else
Psi = Psi + M_PI_2
end if
end subroutine EulerAngles !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! File input and output
!---------------------------------------------------------------------------------------------------
integer*4 function OpenFile ( Name, Params, Path ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
character*(*), intent(in) :: Name, Params, Path
!-------------------------------------------------------------------------------------------
integer*4 :: Fuid
character*512 :: FullName, Msg, Name1, Action1, Status1, Form1, Position1
!-------------------------------------------------------------------------------------------
OpenFile = StdUID + 1
if ( Params(1:1) == 'r' ) then
Action1 = 'read'
Status1 = 'old'
Position1 = 'rewind'
else if ( Params(1:1) == 'w' ) then
Action1 = 'write'
Status1 = 'replace'
Position1 = 'rewind'
else if ( Params(1:1) == 'a' ) then
Action1 = 'write'
Status1 = 'old'
Position1 = 'append'
endif
if ( Params(2:2) == 'b' ) then
Form1 = 'binary'
else
Form1 = 'formatted'
endif
open ( unit = OpenFile, file = Name, form = Form1, action = Action1, status = Status1, position = Position1 )
StdUID = StdUID + 1
return
end function OpenFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine CloseFile ( Fuid ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4, intent(inout) :: Fuid
!-------------------------------------------------------------------------------------------
if ( Fuid < 0 ) return
close ( unit = Fuid )
Fuid = -1
end subroutine CloseFile !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TPMLib !*********************************************************************************

View File

@ -0,0 +1,289 @@
module TubePotBase !********************************************************************************
!
! Non-Bonded pair interaction potential and transfer functions for atoms composing nanotubes.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!---------------------------------------------------------------------------------------------------
!
! This module contains basic parameters for all modules involved into calculations of tubular
! potentials.
!
! It includes definitions of
! -- TPBU, Lennard-Jones (12-6) potential;
! -- TPBQ, Transfer function,
!
! All default values are adjusted for non-bonded carbon-carbon interaction in carbon nanotubes.
!
!***************************************************************************************************
use TPMLib
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
! Types of the potential with respect to the breathing mode
integer*4, parameter :: TP_POT_MONO_R = 0
integer*4, parameter :: TP_POT_POLY_R = 1
! Maximum number of elements in corresponding tables
integer*4, parameter :: TPBNMAX = 2001
! Numerical constants
real*8, parameter :: TPbConstD = 5.196152422706632d+00 ! = 3.0**1.5
! Mass of C atom
real*8, parameter :: TPBMc = 12.0107d+00 ! (Da)
! Parameters of the Van der Waals interaction between carbon atoms in graphene sheets, see
! Stuart S.J., Tutein A.B., Harrison J.A., J. Chem. Phys. 112(14), 2000
real*8, parameter :: TPBEcc = 0.00284d+00 ! (eV)
real*8, parameter :: TPBScc = 3.4d+00 ! (A)
! Lattice parameter and surface number density of atoms for a graphene sheet, see
! Dresselhaus et al, Carbon 33(7), 1995
real*8, parameter :: TPBAcc = 1.421d+00 ! (A)
real*8, parameter :: TPBDcc = 4.0d+00 / ( TPBConstD * TPBAcc * TPBAcc ) ! (1/A^2)
! Specific heat of carbon nanotubes
real*8, parameter :: TPBSHcc = 600.0d+00 / K_MDCU ! (eV/(Da*K))
! Cutoff distances for interactomic potential and transfer function.
! Changes in these parameters can result in necessity to change some numerical parameters too.
real*8, parameter :: TPBRmincc = 0.001d+00 * TPBScc ! (A)
real*8, parameter :: TPBRcutoffcc = 3.0d+00 * TPBScc ! (A)
real*8, parameter :: TPBRcutoff1cc = 2.16d+00 * TPBScc ! (A)
! Parameters of the transfer function for non-bonded interaction between carbon atoms
real*8, parameter :: TPBQScc = 7.0d+00 ! (A)
real*8, parameter :: TPBQRcutoff1cc = 8.0d+00 ! (A)
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
logical :: TPErrCheck = .true. ! Set to .true. to generate diagnostic and warning messages
character*512 :: TPErrMsg = ''
real*8 :: TPGeomPrec = 1.0d-06 ! Geometric precision, see TPInt
integer*4 :: TPPotType = TP_POT_MONO_R ! Type of the potential with respect to the breathing mode
! Parameters of the interatomic potential and atoms distribution at the nanotube surface
real*8 :: TPBM = TPBMc ! Mass of an atom (Da)
real*8 :: TPBE = TPBEcc ! Depth of the energy well in (12-6) LJ interatomic potential (eV)
real*8 :: TPBS = TPBScc ! Sigma parameter of (12-6) LJ interatomic potential (A)
real*8 :: TPBD = TPBDcc ! Numerical density of atoms at the tube surface (1/A^2)
real*8 :: TPBSH = TPBSHcc ! Specific heat (eV/(Da*K))
real*8 :: TPBRmin = TPBRmincc ! (A)
real*8 :: TPBRcutoff = TPBRcutoffcc ! (A)
real*8 :: TPBRcutoff1 = TPBRcutoff1cc ! (A)
! Physical parameters of the transfer function
real*8 :: TPBQS = TPBQScc ! Sigma parameter of the transfer function (A)
real*8 :: TPBQRcutoff1 = TPBQRcutoff1cc ! (A)
! Auxiliary variables
real*8 :: TPBE4, TPBE24, TPBDRcutoff, TPBQDRcutoff
real*8 :: TPBQR0 ! Constant-value distance for the transfer function (A)
! Table of inter-particle potential, force, and transfer function
integer*4 :: TPBN = TPBNMAX
real*8 :: TPBDR
real*8, dimension(0:TPBNMAX-1) :: TPBQ
real*8, dimension(0:TPBNMAX-1) :: TPBU, TPBdUdR
contains !******************************************************************************************
integer*4 function TPBsizeof () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
TPBsizeof = 8 * ( size ( TPBQ ) + size ( TPBU ) + size ( TPBdUdR ) )
end function TPBsizeof !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Interpolation
!---------------------------------------------------------------------------------------------------
real*8 function TPBQInt0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: R
!-------------------------------------------------------------------------------------------
real*8 :: Z, RR
integer*4 :: i
!-------------------------------------------------------------------------------------------
if ( R < TPBRmin ) then
!call PrintStdLogMsg ( TPErrMsg )
!write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) ': R < Rmin: R=', R, ', Rmin=', TPBRmin
!call Error ( 'TPBQInt0', TPErrMsg )
elseif ( R > TPBRcutoff ) then
TPBQInt0 = 0.0d+00
return
endif
RR = ( R - TPBRmin ) / TPBDR
i = int ( RR )
RR = RR - i
Z = 1.0d+00 - RR
TPBQInt0 = TPBQ(i) * Z + TPBQ(i+1) * RR
end function TPBQInt0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function TPBUInt0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: R
!-------------------------------------------------------------------------------------------
real*8 :: Z, RR
integer*4 :: i
!-------------------------------------------------------------------------------------------
if ( R < TPBRmin ) then
!call PrintStdLogMsg ( TPErrMsg )
!write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) ': R < Rmin: R=', R, ', Rmin=', TPBRmin
!call Error ( 'TPBUInt0', TPErrMsg )
elseif ( R > TPBRcutoff ) then
TPBUInt0 = 0.0d+00
return
endif
RR = ( R - TPBRmin ) / TPBDR
i = int ( RR )
RR = RR - i
Z = 1.0d+00 - RR
TPBUInt0 = TPBU(i) * Z + TPBU(i+1) * RR
end function TPBUInt0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPBUInt1 ( U, dUdR, R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(out) :: U, dUdR
real*8, intent(in) :: R
!-------------------------------------------------------------------------------------------
real*8 :: Z, RR
integer*4 :: i
!-------------------------------------------------------------------------------------------
if ( R < TPBRmin ) then
!call PrintStdLogMsg ( TPErrMsg )
!write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) ': R < Rmin: R=', R, ', Rmin=', TPBRmin
!call Error ( 'TPBUInt1', TPErrMsg )
elseif ( R > TPBRcutoff ) then
TPBU = 0.0d+00
TPBdUdR = 0.0d+00
return
endif
RR = ( R - TPBRmin ) / TPBDR
i = int ( RR )
RR = RR - i
Z = 1.0d+00 - RR
U = TPBU(i) * Z + TPBU(i+1) * RR
dUdR = TPBdUdR(i) * Z + TPBdUdR(i+1) * RR
end subroutine TPBUInt1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Calculation
!---------------------------------------------------------------------------------------------------
real*8 function TPBQCalc0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: R
!-------------------------------------------------------------------------------------------
real*8 :: Z, t, S
!-------------------------------------------------------------------------------------------
if ( R > TPBRcutoff ) then
TPBQCalc0 = 0.0d+00
else if ( R < TPBQR0 ) then
TPBQCalc0 = 1.0d+00
else
Z = TPBQS / R
Z = Z * Z * Z
Z = Z * Z
TPBQCalc0 = 4.0d+00 * ( 1.0d+00 - Z ) * Z
if ( R > TPBQRcutoff1 ) then
t = ( R - TPBQRcutoff1 ) / TPBQDRcutoff
S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
TPBQCalc0 = TPBQCalc0 * S
endif
endif
end function TPBQCalc0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 function TPBUCalc0 ( R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: R
!-------------------------------------------------------------------------------------------
real*8 :: Z, t, S
!-------------------------------------------------------------------------------------------
if ( R > TPBRcutoff ) then
TPBUCalc0 = 0.0d+00
else
Z = TPBS / R
Z = Z * Z * Z
Z = Z * Z
TPBUCalc0 = TPBE4 * ( Z - 1.0d+00 ) * Z
if ( R > TPBRcutoff1 ) then
t = ( R - TPBRcutoff1 ) / TPBDRcutoff
S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
TPBUCalc0 = TPBUCalc0 * S
endif
endif
end function TPBUCalc0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPBUCalc1 ( U, dUdR, R ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(out) :: U, dUdR
real*8, intent(in) :: R
real*8 :: Z, t, S, dSdR
!-------------------------------------------------------------------------------------------
if ( R > TPBRcutoff ) then
U = 0.0d+00
dUdR = 0.0d+00
else
Z = TPBS / R
Z = Z * Z * Z
Z = Z * Z
U = TPBE4 * ( Z - 1.0d+00 ) * Z
dUdR = TPBE24 * ( 2.0d+00 * Z - 1.0d+00 ) * Z / R
if ( R > TPBRcutoff1 ) then
t = ( R - TPBRcutoff1 ) / TPBDRcutoff
S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t )
dSdR = 6.0d+00 * t * ( t - 1.0d+00 ) / TPBDRcutoff
dUdR = dUdR * S + U * dSdR
U = U * S
endif
endif
end subroutine TPBUCalc1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPBSegmentForces ( F1, F2, F, M, Laxis, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(out) :: F1, F2
real*8, dimension(0:2), intent(in) :: F, M, Laxis
real*8, intent(in) :: L
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2) :: FF, MM, FFF
!-------------------------------------------------------------------------------------------
FF = 0.5d+00 * F
MM = M / L
call V3_V3xxV3 ( FFF, MM, Laxis )
F1 = FF - FFF
F2 = FF + FFF
end subroutine TPBSegmentForces !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Initialization
!---------------------------------------------------------------------------------------------------
subroutine TPBInit () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 :: R
integer*4 :: i
!-------------------------------------------------------------------------------------------
TPBE4 = 4.0d+00 * TPBE
TPBE24 = - 24.0d+00 * TPBE
TPBDRcutoff = TPBRcutoff - TPBRcutoff1
TPBQDRcutoff = TPBRcutoff - TPBQRcutoff1
TPBQR0 = TPBQS * 2.0d+00 ** ( 1.0d+00 / 6.0d+00 )
TPBDR = ( TPBRcutoff - TPBRmin ) / ( TPBN - 1 )
R = TPBRmin
do i = 0, TPBN - 1
TPBQ(i) = TPBQCalc0 ( R )
call TPBUCalc1 ( TPBU(i), TPBdUdR(i), R )
R = R + TPBDR
enddo
end subroutine TPBInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TubePotBase !****************************************************************************

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,428 @@
module TubePotTrue !********************************************************************************
!
! True tubular potential and transfer function
!
!---------------------------------------------------------------------------------------------------
!
! This module implements calculation of true potential and transfer functions for interaction
! between two cylinder segments of nanotubes by direct integration over the surfaces of both
! segments.
!
!---------------------------------------------------------------------------------------------------
!
! Intel Fortran
!
! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020
!
!***************************************************************************************************
use TPMGeom
use TubePotBase
implicit none
!---------------------------------------------------------------------------------------------------
! Constants
!---------------------------------------------------------------------------------------------------
integer*4, parameter :: TPTNXMAX = 257
integer*4, parameter :: TPTNEMAX = 128
!---------------------------------------------------------------------------------------------------
! Types
!---------------------------------------------------------------------------------------------------
type TPTSEG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8 :: X, Y, Z
real*8 :: Psi, Theta, Phi ! Euler's angles
real*8 :: R ! Segment radius
real*8 :: L ! Segment length
integer*4 :: NX, NE ! Number of nodes for numerical integration
real*8 :: DX, DE ! Spacings
real*8, dimension(0:2,0:2) :: M ! Transformation matrix
real*8, dimension(0:TPTNXMAX-1,0:TPTNXMAX-1,0:2) :: Rtab! Node coordinates
end type TPTSEG !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Global variables
!---------------------------------------------------------------------------------------------------
type(TPTSEG) :: TPTSeg1, TPTSeg2 ! Two segments
contains !******************************************************************************************
subroutine TPTSegAxisVector ( S, Laxis ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real*8, dimension(0:2), intent(out) :: Laxis
!-------------------------------------------------------------------------------------------
Laxis(0:2) = S%M(2,0:2)
end subroutine TPTSegAxisVector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTSegRadVector ( S, Lrad, Eps ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real*8, dimension(0:2), intent(out) :: Lrad
real*8, intent(in) :: Eps
!-------------------------------------------------------------------------------------------
real*8 :: Ce, Se
!-------------------------------------------------------------------------------------------
Ce = cos ( Eps )
Se = sin ( Eps )
Lrad(0) = Ce * S%M(0,0) + Se * S%M(1,0)
Lrad(1) = Ce * S%M(0,1) + Se * S%M(1,1)
Lrad(2) = Ce * S%M(0,2) + Se * S%M(1,2)
end subroutine TPTSegRadVector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTRadiusVector ( S, R, X, Eps ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real*8, dimension(0:2), intent(out) :: R
real*8, intent(in) :: X, Eps
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2) :: Laxis, Lrad
!-------------------------------------------------------------------------------------------
call TPTSegAxisVector ( S, Laxis )
call TPTSegRadVector ( S, Lrad, Eps )
R(0) = S%X + X * Laxis(0) + S%R * Lrad(0)
R(1) = S%Y + X * Laxis(1) + S%R * Lrad(1)
R(2) = S%Z + X * Laxis(2) + S%R * Lrad(2)
end subroutine TPTRadiusVector !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTCalcSegNodeTable ( S ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(inout) :: S
!-------------------------------------------------------------------------------------------
real*8 :: X, Eps
integer*4 :: i, j
!-------------------------------------------------------------------------------------------
X = - S%L / 2.0
call RotationMatrix3 ( S%M, S%Psi, S%Theta, S%Phi )
do i = 0, S%NX - 1
Eps = 0.0d+00
do j = 0, S%NE - 1
call TPTRadiusVector ( S, S%Rtab(i,j,0:2), X, Eps )
Eps = Eps + S%DE
end do
X = X + S%DX
end do
end subroutine TPTCalcSegNodeTable !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTSetSegPosition1 ( S, Rcenter, Laxis, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(inout) :: S
real*8, dimension(0:2), intent(in) :: Rcenter, Laxis
real*8, intent(in) :: L
!-------------------------------------------------------------------------------------------
S%L = L
S%DX = L / ( S%NX - 1 )
call EulerAngles ( S%Psi, S%Theta, Laxis )
S%Phi= 0.0d+00
S%X = Rcenter(0)
S%Y = Rcenter(1)
S%Z = Rcenter(2)
call TPTCalcSegNodeTable ( S )
end subroutine TPTSetSegPosition1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTSetSegPosition2 ( S, R1, R2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(inout) :: S
real*8, dimension(0:2), intent(in) :: R1, R2
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2) :: R, Laxis
real*8 :: L
!-------------------------------------------------------------------------------------------
R = 0.5 * ( R1 + R2 )
Laxis = R2 - R1
L = S_V3norm3 ( Laxis )
Laxis = Laxis / L
call TPTSetSegPosition1 ( S, R, Laxis, L )
end subroutine TPTSetSegPosition2 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function TPTCheckIntersection ( S1, S2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S1, S2
!-------------------------------------------------------------------------------------------
integer*4 :: i, j
real*8 :: L1, L2, Displacement, D
real*8, dimension(0:2) :: Laxis, Q, R
!-------------------------------------------------------------------------------------------
L2 = S1%L / 2.0
L1 = - L2
call TPTSegAxisVector ( S1, Laxis )
R(0) = S1%X
R(1) = S1%Y
R(2) = S1%Z
do i = 0, S2%NX - 1
do j = 0, S2%NE - 1
call LinePoint ( Displacement, Q, R, Laxis, S2%Rtab(i,j,0:2) )
D = sqrt ( sqr ( Q(0) - S2%Rtab(i,j,0) ) + sqr ( Q(1) - S2%Rtab(i,j,1) ) &
+ sqr ( Q(2) - S2%Rtab(i,j,2) ) )
if ( Displacement > L1 .and. Displacement < L2 .and. D < S1%R ) then
TPTCheckIntersection = 1
return
end if
end do
end do
TPTCheckIntersection = 0
end function TPTCheckIntersection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function TPTCalcPointRange ( S, Xmin, Xmax, Re ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
type(TPTSEG), intent(in) :: S
real*8, intent(out) :: Xmin, Xmax
real*8, dimension(0:2), intent(in) :: Re
!-------------------------------------------------------------------------------------------
real*8 :: Displacement, Distance
real*8, dimension(0:2) :: Laxis, Q, R
!-------------------------------------------------------------------------------------------
call TPTSegAxisVector ( S, Laxis )
R(0) = S%X
R(1) = S%Y
R(2) = S%Z
call LinePoint ( Displacement, Q, R, Laxis, Re )
Distance = sqrt ( sqr ( Q(0) - Re(0) ) + sqr ( Q(1) - Re(1) ) + sqr ( Q(2) - Re(2) ) ) - S%R
if ( TPBRcutoff < Distance ) then
Xmin = 0.0d+00
Xmax = 0.0d+00
TPTCalcPointRange = 0
return
end if
Distance = sqrt ( TPBRcutoff * TPBRcutoff - Distance * Distance )
Xmin = Displacement - Distance
Xmax = Displacement + Distance
TPTCalcPointRange = 1
end function TPTCalcPointRange !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
subroutine TPTGetEnds ( R1_1, R1_2, R2_1, R2_2, X1_1, X1_2, X2_1, X2_2, H, A ) !!!!!!!!!!!!!
real*8, dimension(0:2), intent(out) :: R1_1, R1_2, R2_1, R2_2
real*8, intent(in) :: X1_1, X1_2, X2_1, X2_2, H, A
!-------------------------------------------------------------------------------------------
R1_1(0) = 0.0d+00
R1_1(1) = 0.0d+00
R1_1(2) = X1_1
R1_2(0) = 0.0d+00
R1_2(1) = 0.0d+00
R1_2(2) = X1_2
R2_1(0) = H
R2_1(1) = - X2_1 * sin ( A )
R2_1(2) = X2_1 * cos ( A )
R2_2(0) = H
R2_2(1) = - X2_2 * sin ( A )
R2_2(2) = X2_2 * cos ( A )
end subroutine TPTGetEnds !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Tubular potential
!---------------------------------------------------------------------------------------------------
integer*4 function TPTPointPotential ( Q, U, F, R, S ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns the potential U and force F applied to the atom in position R and
! produced by the segment S.
!-------------------------------------------------------------------------------------------
real*8, intent(out) :: Q, U
real*8, dimension(0:2), intent(out) :: F
real*8, dimension(0:2), intent(in) :: R
type(TPTSEG), intent(in) :: S
!-------------------------------------------------------------------------------------------
integer*4 :: i, j
real*8, dimension(0:2) :: RR, FF
real*8 :: QQ, UU, UUU, FFF, Rabs
real*8 :: Coeff, Xmin, Xmax, X
!-------------------------------------------------------------------------------------------
TPTPointPotential = 0
Q = 0.0d+00
U = 0.0d+00
F = 0.0d+00
if ( TPTCalcPointRange ( S, Xmin, Xmax, R ) == 0 ) return
X = - S%L / 2.0
do i = 0, S%NX - 1
if ( X > Xmin .and. X < Xmax ) then
QQ = 0.0d+00
UU = 0.0d+00
FF = 0.0d+00
do j = 0, S%NE - 1
RR(0:2) = S%Rtab(i,j,0:2) - R(0:2)
Rabs = S_V3norm3 ( RR )
if ( Rabs < TPBRcutoff ) then
QQ = QQ + TPBQCalc0 ( Rabs )
call TPBUCalc1 ( UUU, FFF, Rabs )
UU = UU + UUU
FFF = FFF / Rabs
FF = FF + FFF * RR
TPTPointPotential = 1
end if
end do
if ( i == 0 .or. i == S%NX - 1 ) then
Q = Q + 0.5d+00 * QQ
U = U + 0.5d+00 * UU
F = F + 0.5d+00 * FF
else
Q = Q + QQ
U = U + UU
F = F + FF
end if
end if
X = X + S%DX
end do
Coeff = TPBD * S%DX * S%R * S%DE
Q = Q * S%DX * S%R * S%DE
U = U * Coeff
F = F * Coeff
end function TPTPointPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function TPTSectionPotential ( Q, U, F, M, S, i, Ssource ) !!!!!!!!!!!!!!!!!!!!!!!
! This function returns the potential U, force F and torque M produced by the segment Ssource
! and applied to the i-th circular cross-section of the segment S.
!-------------------------------------------------------------------------------------------
real*8, intent(out) :: Q, U
real*8, dimension(0:2), intent(out) :: F, M
type(TPTSEG), intent(in) :: S, Ssource
integer*4, intent(in) :: i
!-------------------------------------------------------------------------------------------
integer*4 :: j
real*8, dimension(0:2) :: R, Fp, Mp, Lrad
real*8 :: Qp, Up, Eps
real*8 :: Coeff
!-------------------------------------------------------------------------------------------
TPTSectionPotential = 0
Q = 0.0d+00
U = 0.0d+00
F = 0.0d+00
M = 0.0d+00
Eps = 0.0d+00
do j = 0, S%NE - 1
call TPTSegRadVector ( S, Lrad, Eps )
if ( TPTPointPotential ( Qp, Up, Fp, S%Rtab(i,j,0:2), Ssource ) == 1 ) then
Q = Q + Qp
U = U + Up
F = F + Fp
R(0) = S%Rtab(i,j,0) - S%X
R(1) = S%Rtab(i,j,1) - S%Y
R(2) = S%Rtab(i,j,2) - S%Z
call V3_V3xxV3 ( Mp, R, Fp )
M = M + Mp
TPTSectionPotential = 1
end if
Eps = Eps + S%DE
end do
Coeff = TPBD * S%R * S%DE
Q = Q * S%R * S%DE
U = U * Coeff
F = F * Coeff
M = M * Coeff
end function TPTSectionPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function TPTSegmentPotential ( Q, U, F, M, S, Ssource ) !!!!!!!!!!!!!!!!!!!!!!!!!!
! This function returns the potential U, force F and torque M produced by the segment
! Ssource and applied to the segment S.
!-------------------------------------------------------------------------------------------
real*8, intent(out) :: Q, U
real*8, dimension(0:2), intent(out) :: F, M
type(TPTSEG), intent(in) :: S, Ssource
integer*4 :: i
real*8, dimension(0:2) :: Fc, Mc
real*8 :: Qc, Uc
!-------------------------------------------------------------------------------------------
TPTSegmentPotential = 0
Q = 0.0d+00
U = 0.0d+00
F = 0.0d+00
M = 0.0d+00
if ( TPTCheckIntersection ( S, Ssource ) == 1 ) then
TPTSegmentPotential = 2
return
end if
do i = 0, S%NX - 1
if ( TPTSectionPotential ( Qc, Uc, Fc, Mc, S, i, Ssource ) == 1 ) then
if ( i == 0 .or. i == S%NX - 1 ) then
Q = Q + 0.5d+00 * Qc
U = U + 0.5d+00 * Uc
F = F + 0.5d+00 * Fc
M = M + 0.5d+00 * Mc
else
Q = Q + Qc
U = U + Uc
F = F + Fc
M = M + Mc
end if
TPTSegmentPotential = 1
end if
end do
Q = Q * S%DX
U = U * S%DX
F = F * S%DX
M = M * S%DX
end function TPTSegmentPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Forces
!---------------------------------------------------------------------------------------------------
subroutine TPTSegmentForces ( F1, F2, F, M, Laxis, L ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, dimension(0:2), intent(out) :: F1, F2
real*8, dimension(0:2), intent(in) :: F, M, Laxis
real*8, intent(in) :: L
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2) :: MM, FF, FFF
!-------------------------------------------------------------------------------------------
FF = 0.5d+00 * F
MM = M / L
call V3_V3xxV3 ( FFF, MM, Laxis )
F1 = FF - FFF
F2 = FF + FFF
end subroutine TPTSegmentForces !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
integer*4 function TPTInteractionF ( Q, U, F1_1, F1_2, F2_1, F2_2, R1_1, R1_2, R2_1, R2_2 )
! This function returns the potential and forces applied to the ends of segments.
!-------------------------------------------------------------------------------------------
real*8, intent(out) :: Q, U
real*8, dimension(0:2), intent(out) :: F1_1, F1_2, F2_1, F2_2
real*8, dimension(0:2), intent(in) :: R1_1, R1_2, R2_1, R2_2
!-------------------------------------------------------------------------------------------
real*8, dimension(0:2) :: R1, R2, Laxis1, Laxis2, DR, F1, M1, F2, M2
real*8 :: L1, L2
!-------------------------------------------------------------------------------------------
R1 = 0.5 * ( R1_1 + R1_2 )
R2 = 0.5 * ( R2_1 + R2_2 )
Laxis1 = R1_2 - R1_1
Laxis2 = R2_2 - R2_1
L1 = S_V3norm3 ( Laxis1 )
L2 = S_V3norm3 ( Laxis2 )
Laxis1 = Laxis1 / L1
Laxis2 = Laxis2 / L2
DR = R2 - R1
call TPTSetSegPosition1 ( TPTSeg1, R1, Laxis1, L1 )
call TPTSetSegPosition1 ( TPTSeg2, R2, Laxis2, L2 )
TPTInteractionF = TPTSegmentPotential ( Q, U, F1, M1, TPTSeg1, TPTSeg2 )
if ( TPTInteractionF .ne. 1 ) return
call V3_V3xxV3 ( M2, DR, F1 )
F2 = - F1
M2 = - M1 - M2
call TPTSegmentForces ( F1_1, F1_2, F1, M1, Laxis1, L1 )
call TPTSegmentForces ( F2_1, F2_2, F2, M2, Laxis2, L2 )
end function TPTInteractionF !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!---------------------------------------------------------------------------------------------------
! Initialization
!---------------------------------------------------------------------------------------------------
subroutine TPTInit ( R1, R2, NX, NE ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
real*8, intent(in) :: R1, R2
integer*4, intent(in) :: NX, NE
!-------------------------------------------------------------------------------------------
TPTSeg1%X = 0.0d+00
TPTSeg1%Y = 0.0d+00
TPTSeg1%Z = 0.0d+00
TPTSeg1%Psi = 0.0d+00
TPTSeg1%Theta = 0.0d+00
TPTSeg1%Phi = 0.0d+00
TPTSeg1%R = R1
TPTSeg1%NX = NX
TPTSeg1%NE = NE
TPTSeg1%DE = M_2PI / NE
TPTSeg2%X = 0.0d+00
TPTSeg2%Y = 0.0d+00
TPTSeg2%Z = 0.0d+00
TPTSeg2%Psi = 0.0d+00
TPTSeg2%Theta = 0.0d+00
TPTSeg2%Phi = 0.0d+00
TPTSeg2%R = R2
TPTSeg2%NX = NX
TPTSeg2%NE = NE
TPTSeg2%DE = M_2PI / NE
end subroutine TPTInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end module TubePotTrue !****************************************************************************

247
tools/mesont/dump2vtk.cpp Normal file
View File

@ -0,0 +1,247 @@
/* -*- c++ -*- ----------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
http://lammps.sandia.gov, Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
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 author: Maxim Shugaev (UVA), mvs9t@virginia.edu
------------------------------------------------------------------------- */
#include <iostream>
#include <cstdlib>
#include <fstream>
#include <string>
#include <string.h>
#include <vector>
#include <array>
#include <regex>
#include <string.h>
#include <cmath>
//#include <filesystem>
static const std::string data_file0 = "system.init";
static const std::string data_dump0 = "config.dump";
static const std::string out_dir0 = "out";
struct Particle {
double x, y, z, vx, vy, vz, Es, Eb, Et, Ep, Ek;
char type, nx, ny, nz;
};
class Lamps_base {
public:
Lamps_base() = default;
virtual ~Lamps_base() = default;
int open(const std::string& filename);
int next(); //get next snapshot from the opened file
virtual int write(const std::string& filename) const = 0;
inline double get_X1() const { return X1; };
inline double get_X2() const { return X2; };
inline double get_Y1() const { return Y1; };
inline double get_Y2() const { return Y2; };
inline double get_Z1() const { return Z1; };
inline double get_Z2() const { return Z2; };
inline int get_Natoms() const { return Natoms; };
inline int get_Nsteps() const { return Nsteps; };
inline int is_open() const { return open_stat; };
inline const Particle& get(int i) const { return particles[i]; };
inline Particle& get(int i) { return particles[i]; };
protected:
virtual int load() = 0;
int Nsteps, Natoms, open_stat;
double X1, X2, Y1, Y2, Z1, Z2;
std::vector<Particle> particles;
std::ifstream in;
};
class Lamps_dump : public Lamps_base {
public:
Lamps_dump() = default;
~Lamps_dump() = default;
virtual int write(const std::string& filename) const override;
private:
virtual int load() override;
};
int Lamps_base::open(const std::string& filename) {
in.open(filename); if (!in.is_open()) return EXIT_FAILURE;
return load();
}
int Lamps_base::next() {
return load();
}
int Lamps_dump::write(const std::string& filename) const {
return EXIT_FAILURE;
}
int Lamps_dump::load() {
std::string inbuf; char* tmp_cptr;
open_stat = 0;
if (!getline(in, inbuf)) return EXIT_FAILURE;
if (!getline(in, inbuf)) return EXIT_FAILURE;
Nsteps = std::stoi(inbuf);
if (!getline(in, inbuf)) return EXIT_FAILURE;
if (!getline(in, inbuf)) return EXIT_FAILURE;
Natoms = std::stoi(inbuf);
particles.resize(Natoms);
if (!getline(in, inbuf)) return EXIT_FAILURE;
if (!getline(in, inbuf)) return EXIT_FAILURE;
X1 = strtof(inbuf.c_str(), &tmp_cptr);
X2 = strtof(tmp_cptr + 1, &tmp_cptr);
if (!getline(in, inbuf)) return EXIT_FAILURE;
Y1 = strtof(inbuf.c_str(), &tmp_cptr);
Y2 = strtof(tmp_cptr + 1, &tmp_cptr);
if (!getline(in, inbuf)) return EXIT_FAILURE;
Z1 = strtof(inbuf.c_str(), &tmp_cptr);
Z2 = strtof(tmp_cptr + 1, &tmp_cptr);
if (!getline(in, inbuf)) return EXIT_FAILURE;
for (int i = 0; i < Natoms; i++) {
if (!getline(in, inbuf)) return EXIT_FAILURE;
int id = strtol(inbuf.c_str(), &tmp_cptr, 10) - 1; // modify based on a particular file format
particles[id].type = static_cast<char>(strtol(tmp_cptr + 1, &tmp_cptr, 10));
particles[id].x = strtof(tmp_cptr + 1, &tmp_cptr);
particles[id].y = strtof(tmp_cptr + 1, &tmp_cptr);
particles[id].z = strtof(tmp_cptr + 1, &tmp_cptr);
particles[id].Es = strtof(tmp_cptr + 1, &tmp_cptr);
particles[id].Eb = strtof(tmp_cptr + 1, &tmp_cptr);
particles[id].Et = strtof(tmp_cptr + 1, &tmp_cptr);
particles[id].Ep = particles[id].Es + particles[id].Eb + particles[id].Et;
particles[id].Ek = strtof(tmp_cptr + 1, &tmp_cptr);
}
open_stat = true;
return EXIT_SUCCESS;
}
int main(int argc, char* argv[]) {
std::string data_file = (argc > 1) ? argv[1] : data_file0;
std::string data_dump = (argc > 2) ? argv[2] : data_dump0;
std::string out_dir = (argc > 3) ? argv[3] : out_dir0;
//std::filesystem::remove_all(out_dir);
//std::filesystem::create_directories(out_dir);
//list of bonds
std::ifstream in(data_file);
if (!in.is_open()) {
std::cout << "cannot open " << data_file << std::endl;
return EXIT_FAILURE;
}
std::string buf;
std::string atoms_l = "Atoms";
while (std::getline(in, buf)){
if (buf == atoms_l) break;
if (in.eof()) return EXIT_FAILURE;
}
std::getline(in, buf);
char* tmp_cptr;
std::vector<std::array<int, 2>> bonds;
while (std::getline(in, buf)) {
if (in.eof() || buf.size() == 0) break;
int idx = strtol(buf.c_str(), &tmp_cptr, 10);
int m_idx = strtol(tmp_cptr + 1, &tmp_cptr, 10);
int type = strtol(tmp_cptr + 1, &tmp_cptr, 10);
int id1 = strtol(tmp_cptr + 1, &tmp_cptr, 10);
int id2 = strtol(tmp_cptr + 1, &tmp_cptr, 10);
if(id1 >= 0 && id2 >= 0) bonds.push_back({id1 - 1, id2 - 1});
}
//dump
Lamps_dump dump;
dump.open(data_dump);
if (!dump.is_open()) {
std::cout << "cannot open " << data_dump << std::endl;
return EXIT_FAILURE;
}
double Lx = dump.get_X2() - dump.get_X1();
double Ly = dump.get_Y2() - dump.get_Y1();
double Lz = dump.get_Z2() - dump.get_Z1();
while (1) {
std::ofstream out(out_dir + "/cnt" + std::to_string(dump.get_Nsteps()) + ".vtk");
if (!out.is_open()) {
std::cout << "cannot create " << out_dir + "/cnt" + std::to_string(dump.get_Nsteps()) + ".vtk" << std::endl;
std::cout << "create the output directory \"" << out_dir << "\" manually" << std::endl;
return EXIT_FAILURE;
}
out << "# vtk DataFile Version 3.0\n# \nASCII\n\nDATASET UNSTRUCTURED_GRID\n";
out << "POINTS " << dump.get_Natoms() << " float\n";
for (int i = 0; i < dump.get_Natoms(); i++) {
out << dump.get(i).x << " " << dump.get(i).y << " " << dump.get(i).z << " " << "\n";
}
int bond_count = 0;
for (int i = 0; i < bonds.size(); i++) {
double f1 = std::fabs(dump.get(bonds[i][0]).x - dump.get(bonds[i][1]).x);
double f2 = std::fabs(dump.get(bonds[i][0]).y - dump.get(bonds[i][1]).y);
double f3 = std::fabs(dump.get(bonds[i][0]).z - dump.get(bonds[i][1]).z);
if ((std::fabs(dump.get(bonds[i][0]).x - dump.get(bonds[i][1]).x) < 0.5*Lx)
&& (std::fabs(dump.get(bonds[i][0]).y - dump.get(bonds[i][1]).y) < 0.5*Ly)
&& (std::fabs(dump.get(bonds[i][0]).z - dump.get(bonds[i][1]).z) < 0.5*Lz))
bond_count++;
}
out << "\nCELLS " << bond_count << " " << 3*bond_count << "\n";
for (int i = 0; i < bonds.size(); i++) {
if ((std::fabs(dump.get(bonds[i][0]).x - dump.get(bonds[i][1]).x) < 0.5 * Lx)
&& (std::fabs(dump.get(bonds[i][0]).y - dump.get(bonds[i][1]).y) < 0.5 * Ly)
&& (std::fabs(dump.get(bonds[i][0]).z - dump.get(bonds[i][1]).z) < 0.5 * Lz))
out << "2 " << bonds[i][0] << " " << bonds[i][1] << " " << "\n";
}
out << "\nCELL_TYPES " << bond_count << "\n";
for (int i = 0; i < bond_count; i++) {
out << "4\n";
}
out << "\nPOINT_DATA " << dump.get_Natoms() << "\n";
out << "SCALARS Ep float 1\n";
out << "LOOKUP_TABLE default\n";
for (int i = 0; i < dump.get_Natoms(); i++) {
out << dump.get(i).Ep << "\n";
}
out << "\nSCALARS Ek float 1\n";
out << "LOOKUP_TABLE default\n";
for (int i = 0; i < dump.get_Natoms(); i++) {
out << dump.get(i).Ek << "\n";
}
out << "\nSCALARS Es float 1\n";
out << "LOOKUP_TABLE default\n";
for (int i = 0; i < dump.get_Natoms(); i++) {
out << dump.get(i).Es << "\n";
}
out << "\nSCALARS Eb float 1\n";
out << "LOOKUP_TABLE default\n";
for (int i = 0; i < dump.get_Natoms(); i++) {
out << dump.get(i).Eb << "\n";
}
out << "\nSCALARS Et float 1\n";
out << "LOOKUP_TABLE default\n";
for (int i = 0; i < dump.get_Natoms(); i++) {
out << dump.get(i).Et << "\n";
}
if (dump.next() != EXIT_SUCCESS) break;
}
return EXIT_SUCCESS;
}