diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index 0223750ace..43a8ffe72f 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -265,6 +265,7 @@ set(STANDARD_PACKAGES MC MDI MEAM + MESONT MGPT MISC ML-HDNNP @@ -308,9 +309,8 @@ set(STANDARD_PACKAGES YAFF) set(SUFFIX_PACKAGES CORESHELL GPU KOKKOS OPT INTEL OPENMP) -set(EXTRA_PACKAGES MESONT) -foreach(PKG ${STANDARD_PACKAGES} ${EXTRA_PACKAGES} ${SUFFIX_PACKAGES}) +foreach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) option(PKG_${PKG} "Build ${PKG} Package" OFF) endforeach() @@ -520,7 +520,7 @@ else() set(CUDA_REQUEST_PIC) endif() -foreach(PKG_WITH_INCL KSPACE PYTHON ML-IAP VORONOI COLVARS ML-HDNNP MDI MOLFILE MESONT NETCDF +foreach(PKG_WITH_INCL KSPACE PYTHON ML-IAP VORONOI COLVARS ML-HDNNP MDI MOLFILE NETCDF PLUMED QMMM ML-QUIP SCAFACOS MACHDYN VTK KIM LATTE MSCG COMPRESS ML-PACE LEPTON) if(PKG_${PKG_WITH_INCL}) include(Packages/${PKG_WITH_INCL}) @@ -566,7 +566,7 @@ RegisterStyles(${LAMMPS_SOURCE_DIR}) ######################################################## # Fetch missing external files and archives for packages ######################################################## -foreach(PKG ${STANDARD_PACKAGES} ${EXTRA_PACKAGES} ${SUFFIX_PACKAGES}) +foreach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) if(PKG_${PKG}) FetchPotentials(${LAMMPS_SOURCE_DIR}/${PKG} ${LAMMPS_POTENTIALS_DIR}) endif() @@ -706,7 +706,7 @@ target_include_directories(lammps PRIVATE ${LAMMPS_STYLE_HEADERS_DIR}) ###################################### set(temp "#ifndef LMP_INSTALLED_PKGS_H\n#define LMP_INSTALLED_PKGS_H\n") set(temp "${temp}const char * LAMMPS_NS::LAMMPS::installed_packages[] = {\n") -set(temp_PKG_LIST ${STANDARD_PACKAGES} ${EXTRA_PACKAGES} ${SUFFIX_PACKAGES}) +set(temp_PKG_LIST ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) list(SORT temp_PKG_LIST) foreach(PKG ${temp_PKG_LIST}) if(PKG_${PKG}) @@ -927,7 +927,7 @@ message(STATUS "<<< Build configuration >>> # Print package summary ############################################################################### set(ENABLED_PACKAGES) -foreach(PKG ${STANDARD_PACKAGES} ${EXTRA_PACKAGES} ${SUFFIX_PACKAGES}) +foreach(PKG ${STANDARD_PACKAGES} ${SUFFIX_PACKAGES}) if(PKG_${PKG}) list(APPEND ENABLED_PACKAGES ${PKG}) endif() diff --git a/cmake/Modules/Packages/MESONT.cmake b/cmake/Modules/Packages/MESONT.cmake deleted file mode 100644 index ea867234a0..0000000000 --- a/cmake/Modules/Packages/MESONT.cmake +++ /dev/null @@ -1,73 +0,0 @@ - - -set(MESONT_SOURCES_DIR ${LAMMPS_SOURCE_DIR}/MESONT) -include(StyleHeaderUtils) -include(CheckLanguage) - -# always include C++-only sources -file(GLOB MESONT_SOURCES ${CONFIGURE_DEPENDS} ${MESONT_SOURCES_DIR}/[^.]*mesocnt*.cpp) -file(GLOB MESONT_HEADERS ${CONFIGURE_DEPENDS} ${MESONT_SOURCES_DIR}/[^.]*mesocnt*.h) -# remove derived class when base class is not available -if(NOT PKG_MOLECULE) - list(REMOVE_ITEM MESONT_SOURCES ${MESONT_SOURCES_DIR}/bond_mesocnt.cpp) - list(REMOVE_ITEM MESONT_HEADERS ${MESONT_SOURCES_DIR}/bond_mesocnt.h) -endif() - -# include styles dependent on Fortran library only when Fortran is available. -check_language(Fortran) -if(CMAKE_Fortran_COMPILER) - enable_language(Fortran) - file(GLOB MESONT_LIB_SOURCES ${CONFIGURE_DEPENDS} ${LAMMPS_LIB_SOURCE_DIR}/mesont/[^.]*.f90) - add_library(mesont STATIC ${MESONT_LIB_SOURCES}) - set_target_properties(mesont PROPERTIES OUTPUT_NAME lammps_mesont${LAMMPS_MACHINE}) - target_link_libraries(lammps PRIVATE mesont) - - list(APPEND MESONT_SOURCES ${MESONT_SOURCES_DIR}/pair_mesont_tpm.cpp) - list(APPEND MESONT_SOURCES ${MESONT_SOURCES_DIR}/atom_vec_mesont.cpp) - list(APPEND MESONT_SOURCES ${MESONT_SOURCES_DIR}/compute_mesont.cpp) - list(APPEND MESONT_HEADERS ${MESONT_SOURCES_DIR}/pair_mesont_tpm.h) - list(APPEND MESONT_HEADERS ${MESONT_SOURCES_DIR}/atom_vec_mesont.h) - list(APPEND MESONT_HEADERS ${MESONT_SOURCES_DIR}/compute_mesont.h) -endif() - -# check for package files in src directory due to old make system -DetectBuildSystemConflict(${LAMMPS_SOURCE_DIR} ${MESONT_SOURCES} ${MESONT_HEADERS}) - -# manually register style headers -get_property(alist GLOBAL PROPERTY ANGLE) -get_property(blist GLOBAL PROPERTY BOND) -get_property(clist GLOBAL PROPERTY COMPUTE) -get_property(plist GLOBAL PROPERTY PAIR) -get_property(vlist GLOBAL PROPERTY ATOM_VEC) -foreach(fname ${MESONT_HEADERS}) - file(STRINGS ${fname} is_style LIMIT_COUNT 1 REGEX ANGLE_CLASS) - if(is_style) - list(APPEND alist ${fname}) - endif() - file(STRINGS ${fname} is_style LIMIT_COUNT 1 REGEX BOND_CLASS) - if(is_style) - list(APPEND blist ${fname}) - endif() - file(STRINGS ${fname} is_style LIMIT_COUNT 1 REGEX COMPUTE_CLASS) - if(is_style) - list(APPEND clist ${fname}) - endif() - file(STRINGS ${fname} is_style LIMIT_COUNT 1 REGEX PAIR_CLASS) - if(is_style) - list(APPEND plist ${fname}) - endif() - file(STRINGS ${fname} is_style LIMIT_COUNT 1 REGEX ATOM_CLASS) - if(is_style) - list(APPEND vlist ${fname}) - endif() -endforeach() -set_property(GLOBAL PROPERTY ANGLE "${alist}") -set_property(GLOBAL PROPERTY BOND "${blist}") -set_property(GLOBAL PROPERTY COMPUTE "${clist}") -set_property(GLOBAL PROPERTY PAIR "${plist}") -set_property(GLOBAL PROPERTY ATOM_VEC "${vlist}") - -target_sources(lammps PRIVATE ${MESONT_SOURCES}) -target_include_directories(lammps PRIVATE ${MESONT_SOURCES_DIR}) - -RegisterPackages(${MESONT_SOURCES_DIR}) diff --git a/cmake/presets/most.cmake b/cmake/presets/most.cmake index 0d63140506..00c74c81b8 100644 --- a/cmake/presets/most.cmake +++ b/cmake/presets/most.cmake @@ -40,6 +40,7 @@ set(ALL_PACKAGES MANYBODY MC MEAM + MESONT MISC ML-IAP ML-POD diff --git a/cmake/presets/nolib.cmake b/cmake/presets/nolib.cmake index b022d4bb55..00a69cd22d 100644 --- a/cmake/presets/nolib.cmake +++ b/cmake/presets/nolib.cmake @@ -16,7 +16,6 @@ set(PACKAGES_WITH_LIB LEPTON MACHDYN MDI - MESONT ML-HDNNP ML-PACE ML-QUIP diff --git a/cmake/presets/windows.cmake b/cmake/presets/windows.cmake index 7075659964..aa9a4656af 100644 --- a/cmake/presets/windows.cmake +++ b/cmake/presets/windows.cmake @@ -36,6 +36,7 @@ set(WIN_PACKAGES MANYBODY MC MEAM + MESONT MISC ML-IAP ML-POD diff --git a/lib/mesont/.depend b/lib/mesont/.depend deleted file mode 100644 index bd49eadde8..0000000000 --- a/lib/mesont/.depend +++ /dev/null @@ -1,13 +0,0 @@ -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 diff --git a/lib/mesont/.gitignore b/lib/mesont/.gitignore deleted file mode 100644 index 63a7748cf4..0000000000 --- a/lib/mesont/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.mod diff --git a/lib/mesont/CNTPot.f90 b/lib/mesont/CNTPot.f90 deleted file mode 100644 index 296c436049..0000000000 --- a/lib/mesont/CNTPot.f90 +++ /dev/null @@ -1,714 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !********************************************************************************* diff --git a/lib/mesont/ExportCNT.f90 b/lib/mesont/ExportCNT.f90 deleted file mode 100644 index e86ada0c7c..0000000000 --- a/lib/mesont/ExportCNT.f90 +++ /dev/null @@ -1,150 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !******************************************************************************* diff --git a/lib/mesont/Install.py b/lib/mesont/Install.py deleted file mode 100644 index 0a0979c2ee..0000000000 --- a/lib/mesont/Install.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/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 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 /Makefile.* file used for compiling this library") -parser.add_argument("-e", "--extramake", - help="set EXTRAMAKE variable in /Makefile. to Makefile.lammps.") - -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) diff --git a/lib/mesont/LinFun2.f90 b/lib/mesont/LinFun2.f90 deleted file mode 100644 index 2bf1d2872a..0000000000 --- a/lib/mesont/LinFun2.f90 +++ /dev/null @@ -1,113 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !******************************************************************************** diff --git a/lib/mesont/Makefile.gfortran b/lib/mesont/Makefile.gfortran deleted file mode 100644 index 55d6f59b20..0000000000 --- a/lib/mesont/Makefile.gfortran +++ /dev/null @@ -1,46 +0,0 @@ -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) diff --git a/lib/mesont/Makefile.ifort b/lib/mesont/Makefile.ifort deleted file mode 100644 index 5c9d7aae85..0000000000 --- a/lib/mesont/Makefile.ifort +++ /dev/null @@ -1,46 +0,0 @@ -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) diff --git a/lib/mesont/Makefile.lammps.gfortran b/lib/mesont/Makefile.lammps.gfortran deleted file mode 100644 index 5e0ea2f5d8..0000000000 --- a/lib/mesont/Makefile.lammps.gfortran +++ /dev/null @@ -1,5 +0,0 @@ -# Settings that the LAMMPS build will import when this package library is used - -mesont_SYSINC = -mesont_SYSLIB = -lgfortran -mesont_SYSPATH = diff --git a/lib/mesont/Makefile.lammps.ifort b/lib/mesont/Makefile.lammps.ifort deleted file mode 100644 index 228e3d4bd9..0000000000 --- a/lib/mesont/Makefile.lammps.ifort +++ /dev/null @@ -1,5 +0,0 @@ -# Settings that the LAMMPS build will import when this package library is used - -mesont_SYSINC = -mesont_SYSLIB = -lifcore -lsvml -limf -ldl -lstdc++ -mesont_SYSPATH = diff --git a/lib/mesont/Makefile.serial b/lib/mesont/Makefile.serial deleted file mode 120000 index c52fbcb986..0000000000 --- a/lib/mesont/Makefile.serial +++ /dev/null @@ -1 +0,0 @@ -Makefile.gfortran \ No newline at end of file diff --git a/lib/mesont/README b/lib/mesont/README deleted file mode 100644 index 1884cdb7e9..0000000000 --- a/lib/mesont/README +++ /dev/null @@ -1,67 +0,0 @@ -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. - diff --git a/lib/mesont/Spline1.f90 b/lib/mesont/Spline1.f90 deleted file mode 100644 index 77731383b6..0000000000 --- a/lib/mesont/Spline1.f90 +++ /dev/null @@ -1,191 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !******************************************************************************** diff --git a/lib/mesont/Spline2.f90 b/lib/mesont/Spline2.f90 deleted file mode 100644 index 12ed56ab1e..0000000000 --- a/lib/mesont/Spline2.f90 +++ /dev/null @@ -1,186 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !******************************************************************************** diff --git a/lib/mesont/TPMForceField.f90 b/lib/mesont/TPMForceField.f90 deleted file mode 100644 index cc797b3440..0000000000 --- a/lib/mesont/TPMForceField.f90 +++ /dev/null @@ -1,316 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !************************************************************************** diff --git a/lib/mesont/TPMGeom.f90 b/lib/mesont/TPMGeom.f90 deleted file mode 100644 index 5e8ab73645..0000000000 --- a/lib/mesont/TPMGeom.f90 +++ /dev/null @@ -1,155 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !******************************************************************************** diff --git a/lib/mesont/TPMLib.f90 b/lib/mesont/TPMLib.f90 deleted file mode 100644 index c8abaa40b4..0000000000 --- a/lib/mesont/TPMLib.f90 +++ /dev/null @@ -1,215 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !********************************************************************************* diff --git a/lib/mesont/TPMM0.f90 b/lib/mesont/TPMM0.f90 deleted file mode 100644 index 175e1c4cce..0000000000 --- a/lib/mesont/TPMM0.f90 +++ /dev/null @@ -1,194 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !********************************************************************************** diff --git a/lib/mesont/TPMM1.f90 b/lib/mesont/TPMM1.f90 deleted file mode 100644 index c27c239d8b..0000000000 --- a/lib/mesont/TPMM1.f90 +++ /dev/null @@ -1,372 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !********************************************************************************** diff --git a/lib/mesont/TubePotBase.f90 b/lib/mesont/TubePotBase.f90 deleted file mode 100644 index 3c65d19d4e..0000000000 --- a/lib/mesont/TubePotBase.f90 +++ /dev/null @@ -1,306 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !**************************************************************************** diff --git a/lib/mesont/TubePotMono.f90 b/lib/mesont/TubePotMono.f90 deleted file mode 100644 index 049b5bcb26..0000000000 --- a/lib/mesont/TubePotMono.f90 +++ /dev/null @@ -1,1697 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing author: Alexey N. Volkov, UA, avolkov1@ua.edu -!------------------------------------------------------------------------- - -module TubePotMono !******************************************************************************** -! -! Approximate tubular potentials and transfer functions for mono-radius tubes. -! -!--------------------------------------------------------------------------------------------------- -! -! Intel Fortran -! -! Alexey N. Volkov, University of Alabama, avolkov1@ua.edu, Version 13.00, 2020 -! -!--------------------------------------------------------------------------------------------------- -! -! Four potentials and transfer functions are calculated in this module: -! -! 1. SSTP (segment - semi-infinite tube parallel): Linear density of the potential along -! the segment axis which is produced by a parallel semi-infinite tube. 2D tables for this potential -! are generated at initialization or can be loaded from a file. -! -! 2. STP (segment - tube parallel): Linear density of the potential along the segment axis -! which is produced by a parallel infinite tubes. This is only a particular case of the SSTP potential, -! but it is considered separately for computational efficiency. 1D tables of this potential are taken -! from 2D tables of SSTP potential. -! -! 3. SST (segment - semi-infinite tube): Potential for a segment produced by an arbitrary- -! oriented semi-infinite tube. This potential can not be kept in 2D tables, therefore, all -! data are calculated 'on fly' with the help of SSTP potential and numerical integration along the -! segment axis -! -! 4. ST (segment - tube): Potential for a segment produced by an arbitrary-oriented -! infinitely long tube. 2D tables for this potential are generated at initialization or can be -! loaded from a file. -! -!*************************************************************************************************** - -use TPMLib -use TPMGeom -use TubePotBase -use TubePotTrue -use LinFun2 -use Spline2 -use iso_c_binding, only : c_int, c_double, c_char -implicit none - -!--------------------------------------------------------------------------------------------------- -! Constants -!--------------------------------------------------------------------------------------------------- - - integer(c_int), parameter :: TPMNZMAX = 129 - integer(c_int), parameter :: TPMNEMAX = 128 - - integer(c_int), parameter :: TPMNHMAX = 1001 - integer(c_int), parameter :: TPMNXMAX = 1001 - integer(c_int), parameter :: TPMNMAX = 1001 - -!--------------------------------------------------------------------------------------------------- -! Global variables -!--------------------------------------------------------------------------------------------------- - - integer(c_int) :: TPMStartMode = 1 - character(len=512) :: TPMFile = 'MESONT-TABTP.xrs' - integer(c_int) :: TPMUnitID ! Unit for the tabulated potential file - - integer(c_int) :: TPMNZ = TPMNZMAX - integer(c_int) :: TPMNZ1 = TPMNZMAX - 1 - integer(c_int) :: TPMNE = TPMNEMAX - integer(c_int) :: TPMNE1 = TPMNEMAX - 1 - - integer(c_int) :: TPMNH = TPMNHMAX - integer(c_int) :: TPMNH1 = TPMNHMAX - 1 - integer(c_int) :: TPMNX = TPMNXMAX - integer(c_int) :: TPMNX1 = TPMNXMAX - 1 - - integer :: TPMChiIndM ! Chirality index M - integer :: TPMChiIndN ! Chirality index N - real(c_double) :: TPMR1 - real(c_double) :: TPMR2 - - real(c_double) :: TPMHmax - real(c_double) :: TPMDH - - ! Parameters of empirical correction functions - - integer(c_int) :: TPMAN = 20 - real(c_double) :: TPMAHmin - real(c_double) :: TPMAHmax - real(c_double) :: TPMADH - real(c_double), dimension(0:TPMNHMAX-1) :: TPMAH, TPMAF, TPMAFxx - - ! Fitting parameters that depend on the SWCNT chirality - - real(c_double) :: TPMCaA = 0.22d+00 ! 0.22 for (10,10) CNTs - real(c_double) :: TPMCeA = 0.35d+00 ! 0.35 for (10,10) CNTs - real(c_double) :: TPMAHmin0 = 10.0d+00 ! 10.0 A for (10,10) CNTs - - ! Parameters of SSTP integrator - - real(c_double) :: TPMDE - real(c_double), dimension(0:TPMNEMAX-1) :: TPMCE, TPMSE - - ! Additional parameters for SSTP potential - - real(c_double) :: TPMSSTPDelta = 0.25d+00 - integer(c_int) :: TPMSSTPNH - integer(c_int) :: TPMSSTPNX - - real(c_double) :: TPMSSTPX1 - real(c_double) :: TPMSSTPXmax - real(c_double) :: TPMSSTPDX - - real(c_double), dimension(0:TPMNHMAX-1,0:TPMNXMAX-1) :: TPMSSTPG - real(c_double), dimension(0:TPMNHMAX-1,0:TPMNXMAX-1) :: TPMSSTPF, TPMSSTPFxx, TPMSSTPFyy, TPMSSTPFxxyy - real(c_double), dimension(0:TPMNHMAX-1) :: TPMSSTPH - real(c_double), dimension(0:TPMNXMAX-1) :: TPMSSTPX - - ! Additional parameters for STP potential - - ! In calculations of this potential, some parameters of SSTP potential are also used. - ! In particular, STP potential has no its own integrator. All data comes from SSTP integrator. - ! It does not result in any computational inefficiency unless the STP potential is used without SSTP one. - - integer(c_int) :: TPMNN = 10 - real(c_double), dimension(0:TPMNHMAX-1) :: TPMSTPG - real(c_double), dimension(0:TPMNHMAX-1) :: TPMSTPF, TPMSTPFxx - - ! Parameters for ST potential - - ! Minimum gap dh for ST-potential - real(c_double) :: TPMSTDelta = 1.0d+00 - ! Number of subdivisions for every grid step in ST-integrator - integer(c_int) :: TPMSTNXS = 10 - real(c_double) :: TPMSTXmax - real(c_double) :: TPMSTH1 - real(c_double) :: TPMSTH2 - real(c_double) :: TPMSTDH12 - - real(c_double), dimension(0:TPMNHMAX-1,0:TPMNXMAX-1) :: TPMSTG - real(c_double), dimension(0:TPMNHMAX-1,0:TPMNXMAX-1) :: TPMSTF, TPMSTFxx, TPMSTFyy, TPMSTFxxyy - real(c_double), dimension(0:TPMNHMAX-1) :: TPMSTH - real(c_double), dimension(0:TPMNXMAX-1) :: TPMSTX - - ! Switching parameters - - ! Height switch (at H=0 in SST-potential) - integer(c_int) :: TPMHSwitch = 0 ! 1, use h-switch; 0, do not use the switch - real(c_double) :: TPMHS = 3.0d+00 ! Switch height, Angstrom - - ! Angle switch - integer(c_int) :: TPMASwitch = 0 ! 1, use a-switch; 0, do not use the switch - real(c_double) :: TPMAS = 3.0d+00 ! Switch angle, degree - real(c_double) :: TPMASMin - real(c_double) :: TPMASMax - real(c_double) :: TPMASDelta - - ! These variables are used to print error message if intertube force filed fails - integer(c_int) :: Err_CNT1 = 0, Err_CNT1_Node = 0, Err_CNT2 = 0, & - Err_CNT2_Node1 = 0, Err_CNT2_Node2 = 0, Err_EType = 0 - -contains !****************************************************************************************** - - integer(c_int) function TPMsizeof () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - TPMsizeof = 8 * ( size ( TPMAH ) + size ( TPMAF ) + size ( TPMAFxx ) & - + size ( TPMCE ) + size ( TPMSE ) + size ( TPMSSTPG ) + size ( TPMSSTPF ) & - + size ( TPMSSTPFxx ) + size ( TPMSSTPFyy ) + size ( TPMSSTPFxxyy ) & - + size ( TPMSSTPH ) + size ( TPMSSTPX ) + size ( TPMSTPG ) + size ( TPMSTPF ) & - + size ( TPMSTPFxx ) + size ( TPMSTG ) + size ( TPMSTF ) + size ( TPMSTFxx ) & - + size ( TPMSTFyy ) + size ( TPMSTFxxyy ) + size ( TPMSTH ) + size ( TPMSTX ) ) - end function TPMsizeof !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! Printing error message if intertube force field fails -!--------------------------------------------------------------------------------------------------- - - subroutine PrintTPErrMsg () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !write ( TPErrMsg, fmt = '(a,i8,a,i8,a,i8,a,i8,a,i8,a,i1)' ) 'CNT ', Err_CNT1, ' [', & - ! Err_CNT1_Node,'] with CNT ', Err_CNT2, ' [', Err_CNT2_Node1, ', ', Err_CNT2_Node2, '] E=', Err_EType - !call PrintStdLogMsg ( TPErrMsg ) - end subroutine PrintTPErrMsg !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! SSTP: Linear potential density for the tube interacting with parallel semi-infinite tube -!--------------------------------------------------------------------------------------------------- - - subroutine TPMSSTPIntegrator ( Q, U, H, D ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function calculates the transfer function Q and potential U between an infinitely long - ! tube and a cross-section of another parallel tube for given height H and displacement D. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U - real(c_double), intent(in) :: H, D - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j, k - real(c_double) :: C, Zmin, Zmax, DZ, R1X, R1Y, R2X, R2Y, R2Z, R, Rcutoff2 - !------------------------------------------------------------------------------------------- - Q = 0.0d+00 - U = 0.0d+00 - Zmin = D - TPBRcutoff - Zmax = D + TPBRcutoff - Rcutoff2 = TPBRcutoff * TPBRcutoff - if ( Zmin < 0.0d+00 ) Zmin = 0.0d+00 - DZ = ( Zmax - Zmin ) / TPMNZ1 - do i = 0, TPMNE1 ! Integration over the section of the first tube - R1X = TPMR1 * TPMCE(i) - R1Y = TPMR1 * TPMSE(i) - do j = 0, TPMNE1 ! !Integration over the section of the second tube - R2X = TPMR1 * TPMCE(j) + H - R2Y = TPMR1 * TPMSE(j) - R2Z = Zmin - D - do k = 0, TPMNZ1 ! Integration over the length of the second tube - R = sqr ( R2X - R1X ) + sqr ( R2Y - R1Y ) + sqr ( R2Z ) - if ( R < Rcutoff2 ) then - R = dsqrt ( R ) - if ( k == 0 .or. k == TPMNZ1 ) then - Q = Q + 0.5d+00 * TPBQCalc0 ( R ) - U = U + 0.5d+00 * TPBUCalc0 ( R ) - else - Q = Q + TPBQCalc0 ( R ) - U = U + TPBUCalc0 ( R ) - end if - end if - R2Z = R2Z + DZ - end do - end do - end do - C = sqr ( TPMDE ) * TPMR1 * TPMR2 * DZ - Q = Q * C - U = U * sqr ( TPBD ) * C - end subroutine TPMSSTPIntegrator !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSSTPInt0 ( Q, U, H, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the transfer function Q and potential U for the SSTP potential - ! calculated by interpolation in the table without switch. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U - real(c_double), intent(in) :: H, X - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j - real(c_double) :: XX - !------------------------------------------------------------------------------------------- - i = 1 + int ( H / TPMDH ) - j = 1 + int ( ( X + TPMSSTPXMax ) / TPMSSTPDX ) - if ( ( i < TPMSSTPNH ) .and. ( j > TPMSSTPNX ) ) then - !call PrintTPErrMsg () - !!call PrintStdLogMsg (TPErrMsg ) - !write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) 'Tubes intersect each other: H=', H, ', X=', X - !call Error ( 'TPMSSTPInt0', TPErrMsg ) - end if - if ( i > TPMNH1 ) then - Q = 0.0d+00 - U = 0.0d+00 - TPMSSTPInt0 = 0 - return - end if - if ( X .le. - TPMSSTPXmax ) then - j = 1 - XX = - TPMSSTPXmax - else if ( X .ge. TPMSSTPXmax ) then - j = TPMNX1 - XX = TPMSSTPXmax - else - XX = X - end if - Q = CalcLinFun2_0 ( i, j, H, XX, TPMNH, TPMNX, TPMSSTPH, TPMSSTPX, TPMSSTPG ) - U = CalcSpline2_0 ( i, j, H, XX, TPMNH, TPMNX, TPMSSTPH, TPMSSTPX, TPMSSTPF, TPMSSTPFxx, TPMSSTPFyy, TPMSSTPFxxyy ) - TPMSSTPInt0 = 1 - end function TPMSSTPInt0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSSTPInt0S ( Q, U, H, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the transfer function Q and potential U for the SSTP potential - ! calculated by interpolation in the table and switch to the case of zero H. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U - real(c_double), intent(in) :: H, X - !------------------------------------------------------------------------------------------- - integer(c_int) :: IntSign - real(c_double) :: t, W, Qa, Ua - !------------------------------------------------------------------------------------------- - if ( TPMHSwitch == 0 ) then - TPMSSTPInt0S = TPMSSTPInt0 ( Q, U, H, X ) - else - if ( H > TPMHS ) then - TPMSSTPInt0S = TPMSSTPInt0 ( Q, U, H, X ) - else - t = H / TPMHS - W = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t ) - TPMSSTPInt0S = TPMSSTPInt0 ( Q, U, H, X ) - IntSign = TPMSSTPInt0 ( Qa, Ua, 0.0d+00, X ) - Q = W * Qa + ( 1.0d+00 - W ) * Q - U = W * Ua + ( 1.0d+00 - W ) * U - end if - end if - end function TPMSSTPInt0S !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSSTPInt1 ( Q, U, Uh, Ux, H, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the transfer function Q, potential U, and derivatives Uh=dU/dH and - ! Ux=dU/dX for the SSTP potential calculated by interpolation in the table without switch - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U, Uh, Ux - real(c_double), intent(in) :: H, X - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j - real(c_double) :: XX - !------------------------------------------------------------------------------------------- - i = 1 + int ( H / TPMDH ) - j = 1 + int ( ( X + TPMSSTPXMax ) / TPMSSTPDX ) - if ( ( i < TPMSSTPNH ) .and. ( j > TPMSSTPNX ) ) then - !call PrintTPErrMsg () - !!call PrintStdLogMsg ( TPErrMsg ) - !write ( TPErrMsg, '(a,e20.10,a,e20.10)' ) 'Tubes intersect each other: H=', H, ', X=', X - !call Error ( 'TPMSSTPInt1', TPErrMsg ) - end if - if ( i > TPMNH1 ) then - Q = 0.0d+00 - U = 0.0d+00 - Uh = 0.0d+00 - Ux = 0.0d+00 - TPMSSTPInt1 = 0 - return - end if - if ( X .le. - TPMSSTPXmax ) then - j = 1 - XX = - TPMSSTPXmax - else if ( X .ge. TPMSSTPXmax ) then - j = TPMNX1 - XX = TPMSSTPXmax - else - XX = X - end if - Q = CalcLinFun2_0 ( i, j, H, XX, TPMNH, TPMNX, TPMSSTPH, TPMSSTPX, TPMSSTPG ) - call CalcSpline2_1 ( U, Uh, Ux, i, j, H, XX, TPMNH, TPMNX, TPMSSTPH, TPMSSTPX, TPMSSTPF, & - TPMSSTPFxx, TPMSSTPFyy, TPMSSTPFxxyy ) - TPMSSTPInt1 = 1 - end function TPMSSTPInt1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSSTPInt1S ( Q, U, Uh, Ux, H, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the transfer function Q, potential U, and derivatives Uh=dU/dH and - ! Ux=dU/dX for the SSTP potential calculated by interpolation in the table and switch to - ! the case of zero H. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U, Uh, Ux - real(c_double), intent(in) :: H, X - !------------------------------------------------------------------------------------------- - integer(c_int) :: IntSign - real(c_double) :: t, W, W1, dWdH, Qa, Ua, Uha, Uxa - !------------------------------------------------------------------------------------------- - if ( TPMHSwitch == 0 ) then - TPMSSTPInt1S = TPMSSTPInt1 ( Q, U, Uh, Ux, H, X ) - else - if ( H > TPMHS ) then - TPMSSTPInt1S = TPMSSTPInt1 ( Q, U, Uh, Ux, H, X ) - else - t = H / TPMHS - W = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t ) - dWdH = 6.0d+00 * t * ( t - 1.0d+00 ) / TPMHS - TPMSSTPInt1S = TPMSSTPInt1 ( Q, U, Uh, Ux, H, X ) - IntSign = TPMSSTPInt1 ( Qa, Ua, Uha, Uxa, 0.0d+00, X ) - W1 = 1.0d+00 - W - Q = W * Qa + W1 * Q - U = W * Ua + W1 * U - Uh = W1 * Uh + ( Ua - U ) * dWdH - Ux = W * Uxa + W1 * Ux - end if - end if - end function TPMSSTPInt1S !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMSSTPWrite () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function writes the table of the SSTP potential to a disk file. - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j - !------------------------------------------------------------------------------------------- - write ( unit = TPMUnitID, fmt = '(4i8)' ) TPMChiIndM, TPMChiIndN, TPMNH1, TPMNX1 - do i = 0, TPMNH1 - do j = 0, TPMNX1 - if ( ( i .ge. TPMSSTPNH ) .or. ( j .le. TPMSSTPNX ) ) & - write ( unit = TPMUnitID, fmt = '(2e26.17)' ) TPMSSTPG(i,j), TPMSSTPF(i,j) - end do - end do - end subroutine TPMSSTPWrite !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMSSTPRead () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function reads the table of the SSTP potential from a disk file. - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j - integer(c_int) :: iTPMChiIndM, iTPMChiIndN, iTPMNH1, iTPMNX1 - !------------------------------------------------------------------------------------------- - read ( unit = TPMUnitID, fmt = '(4i8)' ) iTPMChiIndM, iTPMChiIndN, iTPMNH1, iTPMNX1 - if ( iTPMChiIndM .NE. TPMChiIndM .OR. iTPMChiIndN .NE. TPMChiIndN ) then - print *, 'ERROR in [TPMSSTPRead]: iTPMChiIndM .NE. TPMChiIndM .OR. iTPMChiIndN .NE. TPMChiIndN' - stop - end if - if ( iTPMNH1 .NE. TPMNH1 .OR. iTPMNX1 .NE. TPMNX1 ) then - print *, 'ERROR in [TPMSSTPRead]: iTPMNH1 .NE. TPMNH1 .OR. iTPMNX1 .NE. TPMNX1' - stop - end if - do i = 0, TPMNH1 - do j = 0, TPMNX1 - if ( ( i .ge. TPMSSTPNH ) .or. ( j .le. TPMSSTPNX ) ) & - read ( unit = TPMUnitID, fmt = '(2e26.17)' ) TPMSSTPG(i,j), TPMSSTPF(i,j) - end do - end do - end subroutine TPMSSTPRead !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMSSTPInit () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function calculates the table of the SSTP potential. - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j - real(c_double) :: E - character(c_char) :: Msg - real(c_double), dimension(0:TPMNMAX-1) :: FF, DD, MM, K0, K1, K2 - !------------------------------------------------------------------------------------------- - TPMDE = M_2PI / TPMNE - E = 0.0d+00 - do i = 0, TPMNE1 - TPMCE(i) = cos ( E ) - TPMSE(i) = sin ( E ) - E = E + TPMDE - end do - do i = 0, TPMNH1 - TPMSSTPH(i) = TPMDH * i - end do - TPMSSTPX1 = - 2.0d+00 * TPMSSTPDelta - TPMSSTPXmax = TPBRcutoff + TPMSSTPDelta - TPMSSTPDX = 2.0 * TPMSSTPXmax / TPMNX1 - do j = 0, TPMNX1 - TPMSSTPX(j) = - TPMSSTPXmax + TPMSSTPDX * j - end do - TPMSSTPNH = 1 + int ( ( TPMR1 + TPMR2 + TPMSSTPDelta ) / TPMDH ) - TPMSSTPNX = int ( ( TPMSSTPXMax + TPMSSTPX1 ) / TPMSSTPDX ) - 1 - if ( TPMStartMode == 0 ) then - do i = 0, TPMNH1 - do j = 0, TPMNX1 - if ( ( i .ge. TPMSSTPNH ) .or. ( j .le. TPMSSTPNX ) ) then - call TPMSSTPIntegrator ( TPMSSTPG(i,j), TPMSSTPF(i,j), TPMSSTPH(i), TPMSSTPX(j) ) - print '(2i5,a,e20.10,a,e20.10,a,e20.10,a,e20.10)', i, j, ' H=', TPMSSTPH(i), & - ', X=', TPMSSTPX(j), ', Q=', TPMSSTPG(i,j), ', U=', TPMSSTPF(i,j) - end if - end do - end do - call TPMSSTPWrite () - else - call TPMSSTPRead () - end if - call CreateSpline2Ext ( 3, 3, 3, 3, TPMNH, TPMSSTPNH, TPMNX, TPMSSTPNX, TPMNMAX, TPMSSTPH, TPMSSTPX, & - TPMSSTPF, TPMSSTPFxx, TPMSSTPFyy, TPMSSTPFxxyy, FF, MM, DD, K0, K1, K2 ) - end subroutine TPMSSTPInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! STP potential for an infinite tube interacting with a parallel segment. No actual initialization -! is necessary for this potential, since the data are taken from the table for the SSTP potential. -!--------------------------------------------------------------------------------------------------- - - integer(c_int) function TPMSTPInt0 ( Q, U, H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the transfer function Q and potential U for the STP potential - ! calculated by interpolation in the table. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U - real(c_double), intent(in) :: H - !------------------------------------------------------------------------------------------- - integer(c_int) :: i - !------------------------------------------------------------------------------------------- - i = 1 + int ( H / TPMDH ) - if ( i < TPMSSTPNH ) then - !call PrintTPErrMsg () - !!call PrintStdLogMsg ( TPErrMsg ) - !write ( TPErrMsg, '(a,e20.10)' ) 'Tubes intersect each other: H=', H - !call Error ( 'TPMSTPInt0', TPErrMsg ) - end if - if ( H > TPMHmax ) then - Q = 0.0d+00 - U = 0.0d+00 - TPMSTPInt0 = 0 - return - end if - if ( i == TPMNH ) i = TPMNH - 1 - Q = CalcLinFun1_0 ( i, H, TPMNH, TPMSSTPH, TPMSTPG ) - U = CalcSpline1_0 ( i, H, TPMNH, TPMSSTPH, TPMSTPF, TPMSTPFxx ) - TPMSTPInt0 = 1 - end function TPMSTPInt0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSTPInt1 ( Q, U, dUdH, H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the transfer function Q, potential U, and derivative dUdH for - ! the STP potential calculated by interpolation in the table. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U, dUdH - real(c_double), intent(in) :: H - integer(c_int) :: i - !------------------------------------------------------------------------------------------- - i = 1 + int ( H / TPMDH ) - if ( i < TPMSSTPNH ) then - !call PrintTPErrMsg () - !!call PrintStdLogMsg ( TPErrMsg ) - !write ( TPErrMsg, '(a,e20.10)' ) 'Tubes intersect each other: H=', H - !call Error ( 'TPMSTPInt0', TPErrMsg ) - end if - if ( H > TPMHmax ) then - Q = 0.0d+00 - U = 0.0d+00 - dUdH = 0.0d+00 - TPMSTPInt1 = 0 - return - end if - Q = CalcLinFun1_0 ( i, H, TPMNH, TPMSSTPH, TPMSTPG ) - call CalcSpline1_1 ( U, dUdH, i, H, TPMNH, TPMSSTPH, TPMSTPF, TPMSTPFxx ) - TPMSTPInt1 = 1 - end function TPMSTPInt1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMSTPInit () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function initializes the table of the STP potential - !------------------------------------------------------------------------------------------- - TPMSTPG(0:TPMNH1) = TPMSSTPG(0:TPMNH1,TPMNX1) - TPMSTPF(0:TPMNH1) = TPMSSTPF(0:TPMNH1,TPMNX1) - TPMSTPFxx(0:TPMNH1) = TPMSSTPFxx(0:TPMNH1,TPMNX1) - end subroutine TPMSTPInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! Fitting functions for the SST and ST potentials. -! This correction functions are chosen empirically to improve accuracy of the SST and ST potentials. -!--------------------------------------------------------------------------------------------------- - - subroutine TPMAInit ( X1_1, X1_2, X2_1, X2_2 ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(in) :: X1_1, X1_2, X2_1, X2_2 - !------------------------------------------------------------------------------------------- - real(c_double), dimension(0:2) :: R1_1, R1_2, R2_1, R2_2 - real(c_double), dimension(0:2) :: Fa, Ma - real(c_double) :: Qa, Ua, Qb, Ub, X, H, HH, Ucoeff, Uamin, Ubmin - integer(c_int) :: i, j, IntSign - real(c_double), dimension(0:TPMNHMAX-1) :: D, K0, K1, K2 - integer(c_int) :: iTPMChiIndM, iTPMChiIndN, iTPMAN - !------------------------------------------------------------------------------------------- - TPMAHmin = TPMR1 + TPMR2 + TPMSTDelta - TPMAHmax = TPMR1 + TPMR2 + 0.95d+00 * TPBRcutoff - TPMADH = ( TPMAHmax - TPMAHmin ) / ( TPMAN - 1 ) - if ( TPMStartMode == 1 ) then - read ( unit = TPMUnitID, fmt = '(4i8)' ) iTPMChiIndM, iTPMChiIndN, iTPMAN - if ( iTPMChiIndM .NE. TPMChiIndM .OR. iTPMChiIndN .NE. TPMChiIndN ) then - print *, 'ERROR in [TPMAInit]: iTPMChiIndM .NE. TPMChiIndM .OR. iTPMChiIndN .NE. TPMChiIndN' - stop - end if - if ( iTPMAN .NE. TPMAN ) then - print *, 'ERROR in [TPMAInit]: iTPMAN .NE. TPMAN' - stop - end if - do i = 0, TPMAN - 1 - TPMAH(i) = TPMAHmin + i * TPMADH - read ( unit = TPMUnitID, fmt = * ) TPMAF(i) - end do - call CreateSpline1 ( 3, 3, TPMAN, TPMAH, TPMAF, TPMAFxx, D, K0, K1, K2 ) - return - end if - call TPTInit ( TPMR1, TPMR2, TPTNXMAX, TPTNEMAX ) - do i = 0, TPMAN - 1 - TPMAH(i) = TPMAHmin + i * TPMADH - call TPTGetEnds ( R1_1, R1_2, R2_1, R2_2, X1_1, X1_2, X2_1, X2_2, TPMAH(i), M_PI_2 ) - X = - ( X1_2 - X1_1 ) / 2.0d+00 - do j = 0, ( TPTNXMAX - 1 ) / 2 - HH = sqrt ( TPMAH(i) * TPMAH(i) + sqr ( X * sin ( M_PI_2 ) ) ) - IntSign = TPMSTPInt0 ( Qb, Ub, HH ) - call TPTSetSegPosition2 ( TPTSeg1, R1_1, R1_2 ) - call TPTSetSegPosition2 ( TPTSeg2, R2_1, R2_2 ) - IntSign = TPTSectionPotential ( Qa, Ua, Fa, Ma, TPTSeg1, j, TPTSeg2 ) - if ( j == 0 ) then - Uamin = Ua - Ubmin = Ub - else - if ( Ua < Uamin ) then - Uamin = Ua - end if - if ( Ub < Ubmin ) then - Ubmin = Ub - end if - end if - X = X + TPTSeg1%DX - end do - TPMAF(i) = Uamin / Ubmin - end do - write ( unit = TPMUnitID, fmt = '(4i8)' ) TPMChiIndM, TPMChiIndN, TPMAN - do i = 0, TPMAN - 1 - write ( unit = TPMUnitID, fmt = * ) TPMAF(i) - end do - call CreateSpline1 ( 3, 3, TPMAN, TPMAH, TPMAF, TPMAFxx, D, K0, K1, K2 ) - end subroutine TPMAInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - real(c_double) function TPMA0 ( H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(in) :: H - !------------------------------------------------------------------------------------------- - integer(c_int) :: i - real(c_double) :: A0, t, S - !------------------------------------------------------------------------------------------- - if ( H > TPMAHmax ) then - TPMA0 = 1.0d+00 - return - else if ( H < TPMAHmin ) then - if ( H < TPMAHmin0 ) then - TPMA0 = 1.5d+00 - return - end if - A0 = 1.5d+00 - t = ( H - TPMAHmin0 ) / TPMAHmin - S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t ) - TPMA0 = ( 1.0d+00 - S ) * CalcSpline1_0 ( 1, H, TPMAN, TPMAH, TPMAF, TPMAFxx ) + A0 * S - return - end if - i = 1 + int ( ( H - TPMAHmin ) / TPMADH ) - TPMA0 = CalcSpline1_0 ( i, H, TPMAN, TPMAH, TPMAF, TPMAFxx ) - end function TPMA0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMA1 ( A, Ah, H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(out) :: A, Ah - real(c_double), intent(in) :: H - !------------------------------------------------------------------------------------------- - integer(c_int) :: i - real(c_double) :: A0, t, S, dSdH - !------------------------------------------------------------------------------------------- - if ( H > TPMAHmax ) then - A = 1.0d+00 - Ah = 0.0d+00 - return - else if ( H < TPMAHmin ) then - if ( H < TPMAHmin0 ) then - A = 1.5d+00 - Ah = 0.0d+00 - return - end if - A0 = 1.5d+00 - t = ( H - TPMAHmin0 ) / TPMAHmin - S = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t ) - dSdH = 6.0d+00 * t * ( t - 1.0d+00 ) / TPMAHmin - call CalcSpline1_1 ( A, Ah, 1, H, TPMAN, TPMAH, TPMAF, TPMAFxx ) - Ah = Ah * ( 1.0d+00 - S ) + dSdH * ( A0 - A ) - A = A * ( 1.0d+00 - S ) + A0 * S - return - end if - i = 1 + int ( ( H - TPMAHmin ) / TPMADH ) - call CalcSpline1_1 ( A, Ah, i, H, TPMAN, TPMAH, TPMAF, TPMAFxx ) - end subroutine TPMA1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - real(c_double) function TPMCu0 ( H, cosA, sinA ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the correction function for the magnitude of the potential. - !------------------------------------------------------------------------------------------- - real(c_double), intent(in) :: H, cosA, sinA - !------------------------------------------------------------------------------------------- - TPMCu0 = 1.0d+00 + ( TPMA0 ( H ) - 1.0d+00 ) * sqr ( sinA ) - end function TPMCu0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMCu1 ( Cu, CuH, CuA, H, cosA, sinA ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! The subroutine calculates the correction function Cu for the magnitude of the potential and - ! its derivatives CuH and CuA. - !------------------------------------------------------------------------------------------- - real(c_double), intent(ouT) :: Cu, CuH, CuA - real(c_double), intent(in) :: H, cosA, sinA - real(c_double) :: AA, AAh, D - !------------------------------------------------------------------------------------------- - call TPMA1 ( AA, AAh, H ) - D = sqr ( sinA ) - AA = AA - 1.0d+00 - Cu = 1.0d+00 + AA * D - CuH = AAh * D - CuA = AA * 2.0d+0 * cosA * sinA - end subroutine TPMCu1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - real(c_double) function TPMCa0 ( cosA, sinA ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the correction function for the argument of the potential. - ! If correction is not necessary, it should return sinA. - !------------------------------------------------------------------------------------------- - real(c_double), intent(in) :: cosA, sinA - !------------------------------------------------------------------------------------------- - TPMCa0 = sinA / ( 1.0d+00 - TPMCaA * sqr ( sinA ) ) - end function TPMCa0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMCa1 ( Ca, CaA, Ka, KaA, cosA, sinA ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This subroutine calculates the correction function Cu for the depth of the potential well - ! and its derivatives CuH and CuA. If correction is not necessary, it returns Ca = sinA - ! and CaA = cosA. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Ca, CaA, Ka, KaA - real(c_double), intent(in) :: cosA, sinA - !------------------------------------------------------------------------------------------- - Ka = 1.0d+00 / ( 1.0d+00 - TPMCaA * sqr ( sinA ) ) - Ca = sinA * Ka - KaA = 2.0d+00 * TPMCaA * sinA * cosA * sqr ( Ka ) - CaA = cosA * Ka + sinA * KaA - end subroutine TPMCa1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - real(c_double) function TPMCe0 ( sinA ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! This function returns the correction function for the argument of the potential. - ! If correction is not necessary, it returns sinA. - !------------------------------------------------------------------------------------------- - real(c_double), intent(in) :: sinA - !------------------------------------------------------------------------------------------- - TPMCe0 = 1.0d+00 - TPMCeA * sinA * sinA - end function TPMCe0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMCe1 ( Ce, CeA, Ke, cosA, sinA ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - ! If correction is not necessary, it returns Ce = 1 and CeA = 0. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Ce, CeA, Ke - real(c_double), intent(in) :: cosA, sinA - !------------------------------------------------------------------------------------------- - Ce = 1.0d+00 - TPMCeA * sinA * sinA - CeA = - 2.0d+00 * TPMCeA * sinA * cosA - Ke = TPMCeA - end subroutine TPMCe1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! SST potential for the semi-infinite tube interacting with segment. -! This potential does not need any initialization. All necessary data is taken from tables of the -! SSTP potential. -!--------------------------------------------------------------------------------------------------- - - integer(c_int) function TPMSSTPotential ( Q, U, X1, X2, H, cosA, D, N ) !!!!!!!!!!!!!!!!!!!! - ! This function calculates the transfer function Q and potential U applied to a segment - ! from a semi-infinite tube based on the numerical integration (trapezoidal rule) along the segment - ! axis for non-parallel objects. - ! Relative position of the nanotube and segment is given by axial positions of the segment - ! ends X1 and X2, height H, cosA= cos(A), where A is the cross-axis angle, and the displacement - ! D of a nanotube end. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U - real(c_double), intent(in) :: X1, X2, H, cosA, D - integer(c_int), intent(in) :: N ! Number of nodes for numerical integration - real(c_double) :: sinA, Qs, Us, DX, X, XX, HH, Cu, Ca, Ce - integer(c_int) :: i - !------------------------------------------------------------------------------------------- - Q = 0.0d+00 - U = 0.0d+00 - DX = ( X2 - X1 ) / ( N - 1 ) - X = X1 - sinA = dsqrt ( 1.0d+00 - cosA * cosA ) - Cu = TPMCu0 ( H, cosA, sinA ) - Ca = TPMCa0 ( cosA, sinA ) - Ce = TPMCe0 ( sinA ) - TPMSSTPotential = 0 - do i = 0, N - 1 - XX = X * cosA - Ce * D - HH = sqrt ( H * H + sqr ( X * Ca ) ) - if ( TPMSSTPInt0S ( Qs, Us, HH, XX ) > 0 ) TPMSSTPotential = 1 - if ( i == 0 .or. i == N - 1 ) then - Q = Q + 0.5d+00 * Qs - U = U + 0.5d+00 * Us - else - Q = Q + Qs - U = U + Us - end if - X = X + DX - end do - Q = Cu * Q * DX - U = Cu * U * DX - end function TPMSSTPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSSTPotentialPar ( Q, U, R1_1, Laxis1, R2_1, Laxis2, L1, N ) !!!!! - ! Potential for a segment and a semi-infinite tube is calculated by the numerical - ! integration (trapezoidal rule) along the segment axis for parallel objects. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U - real(c_double), dimension(0:2), intent(in) :: R1_1, Laxis1, R2_1, Laxis2 - real(c_double), intent(in) :: L1 - integer(c_int), intent(in) :: N ! Number of nodes for numerical integration - !------------------------------------------------------------------------------------------- - real(c_double) :: Qs, Us, DX, X, S, H - real(c_double), dimension(0:2) :: R1, L12 - integer(c_int) :: i - !------------------------------------------------------------------------------------------- - DX = L1 / ( N - 1 ) - X = 0.0d+00 - Q = 0.0d+00 - U = 0.0d+00 - TPMSSTPotentialPar = 0 - do i = 0, N - 1 - R1 = R1_1 + X * Laxis1 - call LinePoint ( S, L12, R2_1, Laxis2, R1 ) - L12 = L12 - R1 - call ApplyPeriodicBC ( L12 ) - H = S_V3norm3 ( L12 ) - if ( TPMSSTPInt0S ( Qs, Us, H, S ) > 0 ) then - TPMSSTPotentialPar = 1 - if ( i == 0 .or. i == TPMNN - 1 ) then - Q = Q + 0.5d+00 * Qs - U = U + 0.5d+00 * Us - else - Q = Q + Qs - U = U + Us - end if - X = X + DX - end if - end do - Q = Q * DX - U = U * DX - end function TPMSSTPotentialPar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSSTForces ( Q, U, F1, F2, Fd, X1, X2, H, cosA, D, N ) !!!!!!!!!!! - ! Potential and forces applied to the segment from a semi-infinite tube are calculated - ! by the numerical integration (trapezoidal rule) along the segment axis. - ! Non-parallel case. - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U, Fd - real(c_double), dimension(0:2), intent(out) :: F1, F2 - real(c_double), intent(in) :: X1, X2, H, cosA, D - integer(c_int), intent(in) :: N ! Number of nodes for numerical integration - !------------------------------------------------------------------------------------------- - real(c_double) :: DX, sinA - real(c_double) :: Qs, Us, Ush, Usx, Fx, Fy, Fz - real(c_double) :: C, C1, C2, I0, Ih, Ih1, Ih2, Ix, Ix1, X, XX, HH - real(c_double) :: Ca, CaA, Ka, KaA, Cu, CuH, CuA, Ce, CeA, Ke, Uh, Ua - integer(c_int) :: IntSign, i - !------------------------------------------------------------------------------------------- - I0 = 0.0d+00 - Ih = 0.0d+00 - Ih1 = 0.0d+00 - Ih2 = 0.0d+00 - Ix = 0.0d+00 - Ix1 = 0.0d+00 - Q = 0.0d+00 - U = 0.0d+00 - F1 = 0.0d+00 - F2 = 0.0d+00 - Fd = 0.0d+00 - sinA = dsqrt ( 1.0d+00 - cosA * cosA ) - X = X1 - DX = ( X2 - X1 ) / ( N - 1 ) - TPMSSTForces = 0 - call TPMCa1 ( Ca, CaA, Ka, KaA, cosA, sinA ) - call TPMCu1 ( Cu, CuH, CuA, H, cosA, sinA ) - call TPMCe1 ( Ce, CeA, Ke, cosA, sinA ) - do i = 0, N - 1 - XX = X * cosA - Ce * D - HH = sqrt ( H * H + sqr ( X * Ca ) ) - if ( TPMSSTPInt1S ( Qs, Us, Ush, Usx, HH, XX ) > 0 ) TPMSSTForces = 1 - if ( i == 0 .or. i == N - 1 ) then - Qs = 0.5d+0 * Qs - Us = 0.5d+0 * Us - Ush = 0.5d+0 * Ush - Usx = 0.5d+0 * Usx - end if - if ( HH .le. TPGeomPrec ) then - Ush = 0.0d+00 - else - Ush = Ush / HH - end if - Q = Q + Qs - I0 = I0 + Us - Ih = Ih + Ush - Ih1 = Ih1 + X * Ush - Ih2 = Ih2 + X * X * Ush - Ix = Ix + Usx - Ix1 = Ix1 + X * Usx - X = X + DX - end do - if ( TPMSSTForces == 0 ) return - - C = DX * Cu - I0 = I0 * C - Ih = Ih * C - Ih1 = Ih1 * C - Ih2 = Ih2 * C - Ix = Ix * C - Ix1 = Ix1 * C - - DX = X2 - X1 - - Q = Q * C - U = I0 - Uh = ( CuH * U / Cu + h * Ih ) / DX - Ua = ( CuA * I0 / Cu + Ca * CaA * Ih2 - sinA * Ix1 - CeA * D * Ix ) / DX - - C1 = Ka * Ka * Ih1 - C = h * ( C1 + cosA * Ke * Ix ) / DX - F1(0) = X2 * Uh - C - F2(0) = C - X1 * Uh - - C = ( cosA * sinA * C1 + ( Ke * sinA - sinA ) * Ix ) / DX - F1(1) = Ua - X2 * C - F2(1) = X1 * C - Ua - - C1 = Ca * Ca * Ih1 + cosA * Ix - C2 = Ca * Ca * Ih2 + cosA * Ix1 - F1(2) = ( U - X2 * C1 + C2 ) / DX - F2(2) = ( X1 * C1 - C2 - U ) / DX - - Fd = Ce * Ix - end function TPMSSTForces !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSSTForcesPar ( Q, U, F1, F2, Fd, R1_1, Laxis1, R2_1, Laxis2, L1, N ) - ! Potential and forces applied to the segment from a semi-infinite tube are calculated by - ! the numerical integration (trapezoidal rule) along the segment axis. - ! Parallel case - !------------------------------------------------------------------------------------------- - real(c_double), intent(out) :: Q, U, Fd - real(c_double), dimension(0:2), intent(out) :: F1, F2 - real(c_double), dimension(0:2), intent(in) :: R1_1, Laxis1, R2_1, Laxis2 - real(c_double), intent(in) :: L1 - integer(c_int), intent(in) :: N ! Number of nodes for numerical integration - !------------------------------------------------------------------------------------------- - real(c_double) :: Qs, Us, Ush, Usx, DX, X, S, H, Beta, Gamma - real(c_double), dimension(0:2) :: R1, L12, Fs - integer(c_int) :: i, N1 - !------------------------------------------------------------------------------------------- - Q = 0.0d+00 - U = 0.0d+00 - F1 = 0.0d+00 - F2 = 0.0d+00 - Fd = 0.0d+00 - X = 0.0d+00 - N1 = N - 1 - DX = L1 / N1 - TPMSSTForcesPar = 0 - do i = 0, N1 - R1 = R1_1 + X * Laxis1 - call LinePoint ( S, L12, R2_1, Laxis2, R1 ) - L12 = L12 - R1 - call ApplyPeriodicBC ( L12 ) - H = S_V3norm3 ( L12 ) - if ( TPMSSTPInt1S ( Qs, Us, Ush, Usx, H, S ) > 0 ) then - TPMSSTForcesPar = 1 - if ( H .ge. TPGeomPrec ) then - Fs = Ush * L12 / H - Usx * Laxis2 - else - Fs = - Usx * Laxis2 - end if - Beta = real ( i ) / N1 - Gamma = 1.0d+00 - Beta - if ( i == 0 .or. i == N1 ) then - Q = Q + 0.5d+00 * Qs - U = U + 0.5d+00 * Us - Fd = Fd + 0.5d+00 * Usx - Gamma = 0.5d+00 * Gamma - Beta = 0.5d+000 * Beta - else - Q = Q + Qs - U = U + Us - Fd = Fd + Usx - end if - F1 = F1 + Gamma * Fs - F2 = F2 + Beta * Fs - end if - X = X + DX - end do - Q = Q * DX - U = U * DX - Fd = Fd * DX - Fs = U * Laxis1 / L1 - F1 = DX * F1 + Fs - F2 = DX * F2 - Fs - end function TPMSSTForcesPar !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! ST: Potential for a infinite tube interacting with a segment -!-------------------------------------------------------------------------------------------------- - - ! - ! These functions are used to smooth boundaries in (H,X) domain for ST potential - ! - - real(c_double) function TPMSTXMin0 ( H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(in) :: H - !------------------------------------------------------------------------------------------- - real(c_double) :: X - !------------------------------------------------------------------------------------------- - if ( H < TPMSTH1 ) then - TPMSTXMin0 = sqrt ( TPMSTH2 * TPMSTH2 - H * H ) - return - else if ( H > TPMSTH2 ) then - TPMSTXMin0 = 0.0d+00 - return - end if - X = ( H - TPMSTH1 ) / TPMSTDH12 - TPMSTXMin0 = sqrt ( TPMSTH2 * TPMSTH2 - H * H ) & - * ( 1.0d+00 - X * X * X * ( 3.0d+00 * X * ( 2.0d+00 * X - 5.0d+00 ) + 10.0d+00 ) ) - end function TPMSTXMin0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - real(c_double) function TPMSTXMax0 ( H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(in) :: H - !------------------------------------------------------------------------------------------- - TPMSTXMax0 = sqrt ( TPMSTXMax * TPMSTXMax - H * H ) - end function TPMSTXMax0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMSTXMin1 ( XMin, dXMindH, H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(out) :: XMin, dXMindH - real(c_double), intent(in) :: H - !------------------------------------------------------------------------------------------- - real(c_double) :: X, F, dFdX - !------------------------------------------------------------------------------------------- - if ( H < TPMSTH1 ) then - XMin = sqrt ( TPMSTH2 * TPMSTH2 - H * H ) - dXMindH = - H / XMin - return - else if ( H > TPMSTH2 ) then - XMin = 0.0d+00 - dXMindH = 0.0d+00 - return - end if - X = ( H - TPMSTH1 ) / TPMSTDH12 - F = 1.0d+00 - X * X * X * ( 3.0d+00 * X * ( 2.0d+00 * X - 5.0d+00 ) + 10.0d+00 ) - X = X * ( X - 1.0d+00 ) - dFdX = - 30.0d+00 * X * X - XMin = sqrt ( TPMSTH2 * TPMSTH2 - H * H ) - dXMindH = - H * F / XMin + XMin * dFdX / TPMSTDH12 - XMin = XMin * F - end subroutine TPMSTXMin1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMSTXMax1 ( XMax, dXMaxdH, H ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(out) :: XMax, dXMaxdH - real(c_double), intent(in) :: H - !------------------------------------------------------------------------------------------- - XMax = sqrt ( TPMSTXMax * TPMSTXMax - H * H ) - dXMaxdH = - H / XMax - end subroutine TPMSTXMax1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - ! - ! ST (segment-tube) table - ! - - subroutine TPMSTIntegrator ( G, F, Q, U, H, X, DX ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(inout) :: G, F, Q, U - real(c_double), intent(in) :: H, X, DX - !------------------------------------------------------------------------------------------- - real(c_double) :: FFx, HH, DDX - integer(c_int) :: IntSign - !------------------------------------------------------------------------------------------- - DDX = 0.5 * DX - G = G + Q * DDX - F = F + U * DDX - Q = 0.0d+00 - U = 0.0d+00 - HH = dsqrt ( sqr ( H ) + sqr ( X ) ) - if ( HH > TPMHmax ) return - IntSign = TPMSTPInt0 ( Q, U, HH ) - if ( IntSign == 1 ) then - G = G + Q * DDX - F = F + U * DDX - end if - end subroutine TPMSTIntegrator !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSTInt0 ( G, F, H, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(out) :: G, F - real(c_double), intent(in) :: H, X - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j - real(c_double) :: S, XA, XXX, XXXX, XMin, XMax - !------------------------------------------------------------------------------------------- - if ( H > TPMHmax ) then - G = 0.0d+00 - F = 0.0d+00 - TPMSTInt0 = 0 - return - else if ( H < 0.0d+00 ) then - G = 0.0d+00 - F = 0.0d+00 - TPMSTInt0 = 2 - !call PrintTPErrMsg () - !!call PrintStdLogMsg ( TPErrMsg ) - !all Error ( 'TPMSTInt0', 'H < 0' ) - !!return - end if - S = signum ( X ) - XA = dabs ( X ) - i = 1 + int ( H / TPMDH ) - if ( i > TPMNH1 ) i = TPMNH1 - XMin = TPMSTXMin0 ( H ) - XMax = TPMSTXMax0 ( H ) - XXX = ( XA - XMin ) / ( XMax - XMin ) - if ( XXX < 0.0d+00 ) then - j = 1 - XXXX = 0.0d+00 - !call PrintTPErrMsg () - !write ( TPErrMsg, '(a,e20.10,a,e20.10,a,e20.10)' ) 'X < XMin, X=', XA, ', XMin=', XMin, ', H=', H - !call Error ( 'TPMSTInt0', TPErrMsg ) - else if ( XXX .ge. 1.0d+00 ) then - j = TPMNX1 - XXXX = 1.0d+00 - else - XXXX = XXX - j = 1 + int ( XXXX * TPMNX1 ) - end if - G = S * CalcLinFun2_0 ( i, j, H, XXXX, TPMNH, TPMNX, TPMSTH, TPMSTX, TPMSTG ) - F = S * CalcSpline2_0 ( i, j, H, XXXX, TPMNH, TPMNX, TPMSTH, TPMSTX, TPMSTF, TPMSTFxx, TPMSTFyy, TPMSTFxxyy ) - TPMSTInt0 = 1 - end function TPMSTInt0 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSTInt1 ( G, F, Fh, Fx, H, X ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double), intent(inout) :: G, F, Fh, Fx - real(c_double), intent(in) :: H, X - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j - real(c_double) :: S, XA, DX, XXX, XXXX, XMin, XMax, dXMindH, dXMaxdH - !------------------------------------------------------------------------------------------- - if ( H > TPMHmax ) then - G = 0.0d+00 - F = 0.0d+00 - Fh = 0.0d+00 - Fx = 0.0d+00 - TPMSTInt1 = 0 - return - else if ( H < 0.0d+00 ) then - G = 0.0d+00 - F = 0.0d+00 - Fh = 0.0d+00 - Fx = 0.0d+00 - TPMSTInt1 = 2 - !call PrintTPErrMsg () - !!call PrintStdLogMsg ( trim ( TPErrMsg ) ) - !call Error ( 'TPMSTInt1', 'H < 0' ) - !!return - end if - S = signum ( X ) - XA = dabs ( X ) - i = 1 + int ( H / TPMDH ) - if ( i > TPMNH1 ) i = TPMNH1 - call TPMSTXMin1 ( XMin, dXMindH, H ) - call TPMSTXMax1 ( XMax, dXMaxdH, H ) - DX = XMax - XMin - XXX = ( XA - XMin ) / DX - if ( XXX < 0.0d+00 ) then - j = 1 - XXX = 0.0d+00 - XXXX = 0.0d+00 - !call PrintTPErrMsg () - !write ( TPErrMsg, '(a,e20.10,a,e20.10,a,e20.10)' ) 'X < XMin, X=', XA, ', XMin=', XMin, ', H=', H - !call Error ( 'TPMSTInt', TPErrMsg ) - else if ( XXX .ge. 1.0d+00 ) then - j = TPMNX1 - XXX = 1.0d+00 - XXXX = 1.0d+00 - else - XXXX = XXX - j = 1 + int ( XXXX * TPMNX1 ) - end if - G = S * CalcLinFun2_0 ( i, j, H, XXXX, TPMNH, TPMNX, TPMSTH, TPMSTX, TPMSTG ) - call CalcSpline2_1 ( F, Fh, Fx, i, j, H, XXXX, TPMNH, TPMNX, TPMSTH, TPMSTX, & - TPMSTF, TPMSTFxx, TPMSTFyy, TPMSTFxxyy ) - Fx = Fx / DX - Fh = Fh - Fx * ( dXMaxdH * XXX + dXMindH * ( 1.0d+00 - XXX ) ) - F = F * S - Fh = Fh * S - TPMSTInt1 = 1 - end function TPMSTInt1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSTPotential ( Q, U, X1, X2, H, cosA, CaseID ) !!!!!!!!!!!!!!!!!!! - real(c_double), intent(out) :: Q, U - real(c_double), intent(in) :: X1, X2, H, cosA - integer(c_int), intent(in) :: CaseID - !------------------------------------------------------------------------------------------- - real(c_double) :: sinA, GG1, GG2, FF1, FF2, Ca, Cu - !------------------------------------------------------------------------------------------- - if ( CaseID == MD_LINES_PAR ) then - TPMSTPotential = TPMSTPInt0 ( Q, U, H ) - U = U * ( X2 - X1 ) - return - end if - TPMSTPotential = 0 - sinA = dsqrt ( 1.0d+00 - cosA * cosA ) - Cu = TPMCu0 ( H, cosA, sinA ) - Ca = TPMCa0 ( cosA, sinA ) - if ( TPMSTInt0 ( GG1, FF1, H, X1 * Ca ) > 0 ) TPMSTPotential = 1 - if ( TPMSTInt0 ( GG2, FF2, H, X2 * Ca ) > 0 ) TPMSTPotential = 1 - Q = Cu * ( GG2 - GG1 ) / Ca - U = Cu * ( FF2 - FF1 ) / Ca - end function TPMSTPotential !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSTForces ( Q, U, F1, F2, X1, X2, H, cosA, CaseID ) !!!!!!!!!!!!!! - real(c_double), intent(out) :: Q, U - real(c_double), dimension(0:2), intent(out) :: F1, F2 - real(c_double), intent(in) :: X1, X2, H, cosA - integer(c_int), intent(in) :: CaseID - !------------------------------------------------------------------------------------------- - real(c_double) :: DX, sinA - real(c_double) :: GG1, GG2, FF1, FF2, Fh1, Fh2, Fx1, Fx2 - real(c_double) :: B, C, D - real(c_double) :: Ca, CaA, Ka, KaA, Cu, CuH, CuA - integer(c_int) :: IntSign1, IntSign2 - !------------------------------------------------------------------------------------------- - DX = X2 - X1 - if ( CaseID == MD_LINES_PAR ) then - F1 = 0.0d+00 - F2 = 0.0d+00 - TPMSTForces = TPMSTPInt1 ( Q, U, F1(0), H ) - F1(0) = F1(0) * 0.5 * DX - F2(0) = F1(0) - F1(2) = U - F2(2) = - U - Q = Q * DX - U = U * DX - return - end if - - sinA = dsqrt ( 1.0d+00 - cosA * cosA ) - call TPMCa1 ( Ca, CaA, Ka, KaA, cosA, sinA ) - IntSign1 = TPMSTInt1 ( GG1, FF1, Fh1, Fx1, H, X1 * Ca ) - IntSign2 = TPMSTInt1 ( GG2, FF2, Fh2, Fx2, H, X2 * Ca ) - if ( ( IntSign1 .ne. 1 ) .and. ( IntSign2 .ne. 1 ) ) then - Q = 0.0d+00 - U = 0.0d+00 - F1 = 0.0d+00 - F2 = 0.0d+00 - TPMSTForces = 0 - return - end if - - call TPMCu1 ( Cu, CuH, CuA, H, cosA, sinA ) - - Q = Cu * ( GG2 - GG1 ) / Ca - U = Cu * ( FF2 - FF1 ) / Ca - - B = Cu * ( Fx2 - Fx1 ) / sinA - C = H * B / sinA - D = CuH * U / Cu + Cu * ( Fh2 - Fh1 ) / Ca - F1(0) = ( X2 * D - C ) / DX - F2(0) = ( C - X1 * D ) / DX - - C = cosA * B - D = ( CuA / Cu - CaA / Ca ) * U + CaA * Cu * ( X2 * Fx2 - X1 * Fx1 ) / Ca - F1(1) = ( D - X2 * C ) / DX - F2(1) = ( X1 * C - D ) / DX - - F1(2) = Cu * Fx1 - F2(2) = - Cu * Fx2 - - TPMSTForces = 1 - end function TPMSTForces !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMSTForceTorque( Qi, Ui, Fi, Ti, Q, U, F, T, Psi, PsiA, Cap, L, H, cosA, CaseID ) - real(c_double), intent(out) :: Qi, Ui, Fi, Ti, Q, U, F, T, Psi, PsiA, Cap - real(c_double), intent(in) :: L, H, cosA - integer(c_int), intent(in) :: CaseID - !------------------------------------------------------------------------------------------- - real(c_double) :: L2, sinA - real(c_double) :: GG, FF, Fh, Fx, GGi, FFi, Fhi, Fxi - real(c_double) :: B, C, D - real(c_double) :: Ca, CaA, Ka, KaA, Cu, CuH, CuA - integer(c_int) :: IntSign - !------------------------------------------------------------------------------------------- - if ( CaseID == MD_LINES_PAR ) then - TPMSTForceTorque = TPMSTPInt1 ( Q, U, F, H ) - Q = Q * L - U = U * L - F = - F * L - T = 0.0d+00 - Qi = 0.0d+00 - Ui = 0.0d+00 - Fi = 0.0d+00 - Ti = 0.0d+00 - Psi = 0.0d+00 - PsiA = 0.0d+00 - Cap = 0.0d+00 - return - end if - - L2 = 0.5d+00 * L - sinA = dsqrt ( 1.0d+00 - cosA * cosA ) - call TPMCa1 ( Ca, CaA, Ka, KaA, cosA, sinA ) - IntSign = TPMSTInt1 ( GG, FF, Fh, Fx, H, L2 * Ca ) - IntSign = TPMSTInt1 ( GGi, FFi, Fhi, Fxi, H, TPMSTXmax ) - if ( IntSign .ne. 1 ) then - Qi = 0.0d+00 - Ui = 0.0d+00 - Fi = 0.0d+00 - Ti = 0.0d+00 - Q = 0.0d+00 - U = 0.0d+00 - F = 0.0d+00 - T = 0.0d+00 - Psi = 0.0d+00 - PsiA = 0.0d+00 - Cap = 0.0d+00 - TPMSTForceTorque = 0 - return - end if - - call TPMCu1 ( Cu, CuH, CuA, H, cosA, sinA ) - - Psi = Cu / Ca - PsiA = ( CuA * Ca - Cu * CaA ) / Ca / Ca - Cap = CuA / Cu - KaA / Ka - cosA / sinA - Qi = 2.0d+00 * Psi * GGi - Ui = 2.0d+00 * Psi * FFi - Fi = - 2.0d+00 * ( CuH * FFi / Ca + Psi * Fhi ) - Ti = - Cap * Ui - - Q = 2.0d+00 * Cu * GG / Ca - U = 2.0d+00 * Cu * FF / Ca - F = - 2.0d+00 * ( CuH * FF / Ca + Psi * Fh ) - T = - 2.0d+00 * ( ( CuA * Ka - Cu * KaA ) / ( Ka * Ka * sinA ) - Cu * cosA / ( Ka * sinA * sinA ) ) * FF & - - 2.0d+00 * Cu / ( Ka * sinA ) * Fx * L2 * ( KaA * sinA + Ka * cosA ) - - TPMSTForceTorque = 1 - end function TPMSTForceTorque !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - subroutine TPMSTInit () !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - real(c_double) :: X, Q, U, DX, DDX, XMin, XMax - integer(c_int) :: i, j, k - real(c_double), dimension(0:TPMNMAX-1) :: FF, DD, MM, K0, K1, K2 - !------------------------------------------------------------------------------------------- - TPMSTH1 = TPMR1 + TPMR2 - TPMSTH2 = TPMSTH1 + TPMSTDelta - TPMSTDH12 = TPMSTH2 - TPMSTH1 - TPMSTXmax = TPMHMax + TPMSTDelta - DX = 1.0 / TPMNX1 - do j = 0, TPMNX1 - TPMSTX(j) = DX * j - end do - do i = 0, TPMNH1 - TPMSTH(i) = TPMDH * i - XMin = TPMSTXmin0 ( TPMSTH(i) ) - XMax = TPMSTXMax0 ( TPMSTH(i) ) - Q = 0.0d+00 - U = 0.0d+00 - DX = ( XMax - XMin ) * TPMSTX(1) / TPMSTNXS - X = XMin - call TPMSTIntegrator ( TPMSTG(i,0), TPMSTF(i,0), Q, U, TPMSTH(i), X, DX ) - TPMSTG(i,0) = 0.0d+00 - TPMSTF(i,0) = 0.0d+00 - TPMSTFyy(i,0) = U - TPMSTFyy(i,TPMNX1) = 0.0d+00 - do j = 1, TPMNX1 - TPMSTG(i,j) = TPMSTG(i,j-1) - TPMSTF(i,j) = TPMSTF(i,j-1) - do k = 0, TPMSTNXS - 1 - X = X + DX - call TPMSTIntegrator ( TPMSTG(i,j), TPMSTF(i,j), Q, U, TPMSTH(i), X, DX ) - end do - if ( j < TPMNX1 ) DX = ( XMax - XMin ) * ( TPMSTX(j+1) - TPMSTX(j) ) / TPMSTNXS - end do - end do - call CreateSpline2 ( 3, 3, 3, 3, TPMNH, TPMNX, TPMNMAX, TPMSTH, TPMSTX, TPMSTF, TPMSTFxx, & - TPMSTFyy, TPMSTFxxyy, FF, MM, DD, K0, K1, K2 ) - end subroutine TPMSTInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! Interaction functions: They can be used for calculation of the potential and forces between a -! segment and an infinite or semi-infinite nanotube. -!--------------------------------------------------------------------------------------------------- - - subroutine TPMSegmentForces ( F2_1, F2_2, F1_1, F1_2, R1_1, R1_2, R2, Laxis2, L2 ) !!!!!!!!! - real(c_double), dimension(0:2), intent(out) :: F2_1, F2_2 - real(c_double), dimension(0:2), intent(in) :: F1_1, F1_2, R1_1, R1_2, R2, Laxis2 - real(c_double), intent(in) :: L2 - !------------------------------------------------------------------------------------------- - real(c_double), dimension(0:2) :: F, M, RR - !------------------------------------------------------------------------------------------- - RR = R1_1 - R2 - ! Taking into account periodic boundary conditions - call ApplyPeriodicBC ( RR ) - call V3_V3xxV3 ( M, RR, F1_1 ) - RR = R1_2 - R2 - ! Taking into account periodic boundary conditions - call ApplyPeriodicBC ( RR ) - call V3_V3xxV3 ( F, RR, F1_2 ) - M = - ( M + F ) - F = - ( F1_1 + F1_2 ) - call TPBSegmentForces ( F2_1, F2_2, F, M, Laxis2, L2 ) - end subroutine TPMSegmentForces !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - ! - ! Interaction of a segment with a semi-infinite or infinite tube - ! - - integer(c_int) function TPMInteractionF ( Q, U, F1_1, F1_2, F2_1, F2_2, Fd, R1_1, R1_2, R2_1, R2_2, SType2 ) - ! SType2 in the type of the second segment: - ! SType2 == 0, internal segment; - ! Stype2 == 1, point R2_1 is the end of the tube; - ! Stype2 == 2, point R2_2 in the end of the tube. - !------------------------------------------------------------------------------------------- - real(c_double), intent(inout) :: Q, U, Fd - 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) :: SType2 - real(c_double), dimension(0:2) :: R1, R2, Laxis1, Laxis2, F1, F2, L12, Ly, DR, F1_1a, F1_2a, F1_1b, F1_2b - real(c_double) :: H, cosA, D1, D2, L1, L2, cosA2, t, W, W1, dWdt, Qa, Ua, Qb, Ub, Fda, Fdb, FF - integer(c_int) :: GeomID, SwitchID, S, IntSigna, IntSignb - !------------------------------------------------------------------------------------------- - R1 = 0.5d+00 * ( R1_1 + R1_2 ) - R2 = 0.5d+00 * ( 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 - L1 = 0.5d+00 * L1 - L2 = 0.5d+00 * L2 - if ( SType2 == 2 ) Laxis2 = - Laxis2 - GeomID = LineLine ( H, cosA, D1, D2, L12, R1, Laxis1, R2, Laxis2, TPGeomPrec ) - - ! Angle switch - if ( TPMASwitch == 0 ) then - if ( GeomID == MD_LINES_PAR ) then - SwitchID = 2 - else - SwitchID = 0 - end if - else - cosA2 = cosA * cosA - if ( cosA2 .ge. TPMASMax .or. GeomID == MD_LINES_PAR ) then - SwitchID = 2 - else if ( cosA2 .le. TPMASMin ) then - SwitchID = 0 - else - t = ( cosA2 - TPMASMin ) / TPMASDelta - W = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t ) - dWdt = 6.0d+00 * t * ( t - 1.0d+00 ) / TPMASDelta - SwitchID = 1 - end if - end if - - if ( SwitchID < 2 ) then - D2 = D2 - L2 - if ( SType2 == 0 ) then - IntSigna = TPMSTForces ( Qa, Ua, F1, F2, D1 - L1, D1 + L1, H, cosA, MD_LINES_NONPAR ) - Fda = 0.0d+00 - else - IntSigna = TPMSSTForces ( Qa, Ua, F1, F2, Fda, D1 - L1, D1 + L1, H, cosA, D2, TPMNN ) - end if - call V3_V3xxV3 ( Ly, Laxis1, Laxis2 ) - S = signum ( S_V3xV3 ( Ly, L12 ) ) - call V3_V3xxV3 ( Ly, Laxis1, L12 ) - Ly = Ly * S - if ( IntSigna > 0 ) then - F1_1a = F1(0) * L12 + F1(1) * Ly + F1(2) * Laxis1 - F1_2a = F2(0) * L12 + F2(1) * Ly + F2(2) * Laxis1 - else - F1_1a = 0.0d+00 - F1_2a = 0.0d+00 - end if - end if - - if ( SwitchID > 0 ) then - if ( SType2 == 0 ) then - call LinePoint ( H, L12, R2, Laxis2, R1 ) - L12 = L12 - R1 - call ApplyPeriodicBC ( L12 ) - H = S_V3norm3 ( L12 ) - IntSignb = TPMSTForces ( Qb, Ub, F1, F2, - L1, L1, H, cosA, MD_LINES_PAR ) - Fdb = 0.0d+00 - if ( IntSignb > 0 ) then - if ( H .le. TPGeomPrec ) then - F1_1b = F1(2) * Laxis1 - F1_2b = F2(2) * Laxis1 - else - L12 = L12 / H - F1_1b = F1(0) * L12 + F1(2) * Laxis1 - F1_2b = F2(0) * L12 + F2(2) * Laxis1 - end if - else - F1_1b = 0.0d+00 - F1_2b = 0.0d+00 - end if - else if ( Stype2 == 1 ) then - IntSignb = TPMSSTForcesPar ( Qb, Ub, F1_1b, F1_2b, Fdb, R1_1, Laxis1, R2_1, Laxis2, & - 2.0d+00 * L1, TPMNN ) - else - IntSignb = TPMSSTForcesPar ( Qb, Ub, F1_1b, F1_2b, Fdb, R1_1, Laxis1, R2_2, Laxis2, & - 2.0d+00 * L1, TPMNN ) - end if - end if - - if ( SwitchID == 0 ) then - Q = Qa - U = Ua - F1_1 = F1_1a - F1_2 = F1_2a - Fd = Fda - TPMInteractionF = IntSigna - else if ( SwitchID == 2 ) then - Q = Qb - U = Ub - F1_1 = F1_1b - F1_2 = F1_2b - Fd = Fdb - TPMInteractionF = IntSignb - else - W1 = 1.0d+00 - W - Q = W * Qa + W1 * Qb - U = W * Ua + W1 * Ub - Ly = Ly * ( Ua - Ub ) * dWdt * cosA * sqrt ( 1.0d+00 - sqr ( cosA ) ) / L1 - F1_1 = W * F1_1a + W1 * F1_1b - Ly - F1_2 = W * F1_2a + W1 * F1_2b + Ly - Fd = W * Fda + W1 * Fdb - TPMInteractionF = 0 - if ( IntSigna > 0 .or. IntSignb > 0 ) TPMInteractionF = 1 - end if - - ! Calculation of forces for the complimentary tube - if ( SType2 == 2 ) Laxis2 = - Laxis2 - call TPMSegmentForces ( F2_1, F2_2, F1_1, F1_2, R1_1, R1_2, R2, Laxis2, 2.0d+00 * L2 ) - ! After the previous subroutine call, F2_1*Laxis2 = F2_2*Laxis2, but this is not true for a semi-infinite tube. - ! The force along the tube should be applied to the end of the tube, while for the - ! another point corresponding force is equal to zero. - if ( SType2 == 1 ) then - FF = S_V3xV3 ( F2_1, Laxis2 ) - DR = ( Fd - FF ) * Laxis2 - F2_1 = F2_1 + DR - F2_2 = F2_2 - DR - else if ( SType2 == 2 ) then - FF = S_V3xV3 ( F2_2, Laxis2 ) - DR = ( - Fd - FF ) * Laxis2 - F2_2 = F2_2 + DR - F2_1 = F2_1 - DR - end if - end function TPMInteractionF !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMInteractionU ( Q, U, R1_1, R1_2, R2_1, R2_2, SType2 ) !!!!!!!!!!! - real(c_double), intent(inout) :: Q, U - real(c_double), dimension(0:2), intent(in) :: R1_1, R1_2, R2_1, R2_2 - integer(c_int), intent(in) :: SType2 - !------------------------------------------------------------------------------------------- - real(c_double), dimension(0:2) :: R1, R2, Laxis1, Laxis2, F1, F2, L12, DR - real(c_double) :: H, cosA, D1, D2, L1, L2, cosA2, t, W, Qa, Ua, Qb, Ub - integer(c_int) :: GeomID, SwitchID, IntSigna, IntSignb - !------------------------------------------------------------------------------------------- - R1 = 0.5d+00 * ( R1_1 + R1_2 ) - R2 = 0.5d+00 * ( 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 - if ( SType2 == 2 ) Laxis2 = - Laxis2 - GeomID = LineLine ( H, cosA, D1, D2, L12, R1, Laxis1, R2, Laxis2, TPGeomPrec ) - L1 = 0.5d+00 * L1 - L2 = 0.5d+00 * L2 - - ! Angle switch - if ( TPMASwitch == 0 ) then - if ( GeomID == MD_LINES_PAR ) then - SwitchID = 2 - else - SwitchID = 0 - end if - else - cosA2 = cosA * cosA - if ( cosA2 .ge. TPMASMax .or. GeomID == MD_LINES_PAR ) then - SwitchID = 2 - else if ( cosA2 .le. TPMASMin ) then - SwitchID = 0 - else - t = ( cosA2 - TPMASMin ) / TPMASDelta - W = 1.0d+00 - t * t * ( 3.0d+00 - 2.0d+00 * t ) - SwitchID = 1 - end if - end if - - if ( SwitchID < 2 ) then - if ( Stype2 == 0 ) then - IntSigna = TPMSTPotential ( Qa, Ua, D1 - L1, D1 + L1, H, cosA, MD_LINES_NONPAR ) - else - IntSigna = TPMSSTPotential ( Qa, Ua, D1 - L1, D1 + L1, H, cosA, D2 - L2, TPMNN ) - end if - end if - - if ( SwitchID > 0 ) then - if ( Stype2 == 0 ) then - call LinePoint ( H, L12, R2, Laxis2, R1 ) - L12 = L12 - R1 - call ApplyPeriodicBC ( L12 ) - IntSignb = TPMSTPotential ( Qb, Ub, - L1, L1, S_V3norm3 ( L12 ), cosA, MD_LINES_PAR ) - else if ( Stype2 == 1 ) then - IntSignb = TPMSSTPotentialPar ( Qb, Ub, R1_1, Laxis1, R2_1, Laxis2, 2.0d+00 * L1, TPMNN ) - else - IntSignb = TPMSSTPotentialPar ( Qb, Ub, R1_1, Laxis1, R2_2, Laxis2, 2.0d+00 * L1, TPMNN ) - end if - end if - - if ( SwitchID == 0 ) then - Q = Qa - U = Ua - TPMInteractionU = IntSigna - else if ( SwitchID == 2 ) then - Q = Qb - U = Ub - TPMInteractionU = IntSignb - else - Q = W * Qa + ( 1.0d+00 - W ) * Qb - U = W * Ua + ( 1.0d+00 - W ) * Ub - TPMInteractionU = 0 - if ( IntSigna > 0 .or. IntSignb > 0 ) TPMInteractionU = 1 - end if - end function TPMInteractionU !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - integer(c_int) function TPMInteractionFNum ( Q, U, F1_1, F1_2, F2_1, F2_2, R1_1, R1_2, R2_1, R2_2, Stype2, Delta ) - 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) :: SType2 - real(c_double), intent(in) :: Delta - !------------------------------------------------------------------------------------------- - integer(c_int) :: i, j, IntSign - real(c_double) :: QQ, DD, D2 - real(c_double), dimension(0:1,0:2) :: U1_1, U1_2, U2_1, U2_2 - real(c_double), dimension(0:2) :: RR - !------------------------------------------------------------------------------------------- - U = 0.0d+00 - F1_1 = 0.0d+00 - F1_2 = 0.0d+00 - F2_1 = 0.0d+00 - F2_2 = 0.0d+00 - TPMInteractionFNum = TPMInteractionU ( Q, U, R1_1, R1_2, R2_1, R2_2, SType2 ) - if ( TPMInteractionFNum == 0 ) return - D2 = 2.0d+00 * Delta - do i = 0, 2 - DD = - Delta - do j = 0 , 1 - RR = R1_1 - RR(i) = RR(i) + DD - IntSign = TPMInteractionU ( QQ, U1_1(j,i), RR, R1_2, R2_1, R2_2, SType2 ) - RR = R1_2 - RR(i) = RR(i) + DD - IntSign = TPMInteractionU ( QQ, U1_2(j,i), R1_1, RR, R2_1, R2_2, SType2 ) - RR = R2_1 - RR(i) = RR(i) + DD; - IntSign = TPMInteractionU ( QQ, U2_1(j,i), R1_1, R1_2, RR, R2_2, SType2 ) - RR = R2_2 - RR(i) = RR(i) + DD - IntSign = TPMInteractionU ( QQ, U2_2(j,i), R1_1, R1_2, R2_1, RR, SType2 ) - DD = DD + D2 - end do - end do - do i = 0, 2 - F1_1(i) = ( U1_1(0,i) - U1_1(1,i) ) / D2 - F1_2(i) = ( U1_2(0,i) - U1_2(1,i) ) / D2 - F2_1(i) = ( U2_1(0,i) - U2_1(1,i) ) / D2 - F2_2(i) = ( U2_2(0,i) - U2_2(1,i) ) / D2 - end do - end function TPMInteractionFNum !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!--------------------------------------------------------------------------------------------------- -! Initialization -!--------------------------------------------------------------------------------------------------- - - subroutine TPMInit ( ChiIndM, ChiIndN ) !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - integer(c_int), intent(in) :: ChiIndM, ChiIndN - real(c_double) :: RT, DX - character(len=512) :: PDate - !------------------------------------------------------------------------------------------- - TPPotType = TP_POT_MONO_R - - ! Here we calculate the radius of nanotubes - RT = TPBAcc * sqrt ( 3.0d+00 * ( ChiIndM * ChiIndM + ChiIndN * ChiIndN + ChiIndM * ChiIndN ) ) / M_2PI - - TPMChiIndM = ChiIndM - TPMChiIndN = ChiIndN - TPMR1 = RT - TPMR2 = RT - - TPMCaA = 0.275d+00 * ( 1.0d+00 - 1.0d+00 / ( 1.0d+00 + 0.59d+00 * RT ) ) - TPMCeA = 0.35d+00 + 0.0226d+00 * ( RT - 6.785d+00 ) - TPMAHmin0 = 10.0d+00 * ( RT / 6.785d+00 )**1.5 - - TPMHmax = TPMR1 + TPMR2 + TPBRcutoff - TPMDH = TPMHmax / TPMNH1 - - ! Parameters of the angle switch - TPMASMin = sqr ( cos ( rad ( TPMAS ) ) ) - TPMASMax = 1.0d+00 - TPGeomPrec - TPMASDelta = TPMASMax - TPMASMin - - if ( TPMStartMode == 1 ) then - TPMUnitID = OpenFile ( TPMFile, 'rt', '' ) - read ( unit = TPMUnitID, fmt = '()' ) - read ( unit = TPMUnitID, fmt = '()' ) - read ( unit = TPMUnitID, fmt = '()' ) - else - TPMUnitID = OpenFile ( TPMFile, 'wt', '' ) - write ( unit = TPMUnitID, fmt = '(a,a)' ) 'DATE (unknown)' - write ( unit = TPMUnitID, fmt = '(a,i3,a,i3,a)' ) & - 'Tabulated data of the tubular potential for (', ChiIndM, ',', ChiIndN, ') CNTs' - write ( unit = TPMUnitID, fmt = '(a)' ) & - 'A. N. Volkov, L. V. Zhigilei, J. Phys. Chem. C 114, 5513-5531, 2010. doi: 10.1021/jp906142h' - end if - - call TPMSSTPInit () - - call TPMSTPInit () - - DX = TPMR1 + TPMR2 + TPBRcutoff - call TPMAInit ( - DX, DX, - DX, DX ) - - call TPMSTInit () - - call CloseFile ( TPMUnitID ) - - end subroutine TPMInit !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -end module TubePotMono !**************************************************************************** diff --git a/lib/mesont/TubePotTrue.f90 b/lib/mesont/TubePotTrue.f90 deleted file mode 100644 index 4631cc1a1c..0000000000 --- a/lib/mesont/TubePotTrue.f90 +++ /dev/null @@ -1,443 +0,0 @@ -! ------------ ---------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! https://www.lammps.org/ Sandia National Laboratories -! LAMMPS development team: developers@lammps.org -! -! Copyright (2003) Sandia Corporation. Under the terms of Contract -! DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains -! certain rights in this software. This software is distributed under -! the GNU General Public License. -! -! See the README file in the top-level LAMMPS directory. -! -! Contributing 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 !**************************************************************************** diff --git a/src/MESONT/Install.sh b/src/MESONT/Install.sh deleted file mode 100644 index 6fa76f3e3c..0000000000 --- a/src/MESONT/Install.sh +++ /dev/null @@ -1,79 +0,0 @@ -# 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 -} - -# list of files with optional dependencies -action angle_mesocnt.cpp -action angle_mesocnt.h -action bond_mesocnt.cpp bond_harmonic.cpp -action bond_mesocnt.h bond_harmonic.h -action compute_mesont.cpp -action compute_mesont.h -action pair_mesocnt.cpp -action pair_mesocnt.h -action pair_mesocnt_viscous.cpp -action pair_mesocnt_viscous.h - -action export_mesont.h -action atom_vec_mesont.cpp -action atom_vec_mesont.h -action pair_mesont_tpm.cpp -action pair_mesont_tpm.h - -# 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 '/^[ \t]*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 '/^[ \t]*include.*mesont.*$/d' ../Makefile.package.settings - fi - -fi diff --git a/src/MESONT/README b/src/MESONT/README index 0c66cb7b82..4a2eca2989 100644 --- a/src/MESONT/README +++ b/src/MESONT/README @@ -9,33 +9,20 @@ is provided in the papers listed below. -- -This package was created by Maxim Shugaev (mvs9t@virginia.edu) +This package was originally 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) +by this package was developed by Alexey N. Volkov (avolkov1@ua.edu) at the University of Alabama. --- +Since then the functionality has been re-implemented in C++ by +Philipp Kloza (U Cambridge) with some additions and the Fortran +implementation was removed in early 2023 since C++ version is +faster and easier to compile and maintain. -The following commands are contained in this package: - -atom_style mesont - This command enables mesont atom_style containing variables used for - further commands in 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'. +Please see the LAMMPS manual for more information about this package +and how to install and use it. -- diff --git a/src/MESONT/atom_vec_mesont.cpp b/src/MESONT/atom_vec_mesont.cpp deleted file mode 100644 index 23cb4b8146..0000000000 --- a/src/MESONT/atom_vec_mesont.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. - - Contributing 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 = Atom::ATOMIC; - mass_type = PER_TYPE; - - 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 = {"rmass", "radius", "length", "buckling", "bond_nt", "molecule"}; - fields_copy = {"rmass", "radius", "length", "buckling", "bond_nt", "molecule"}; - fields_border = {"rmass", "radius", "length", "buckling", "bond_nt", "molecule"}; - fields_border_vel = {"rmass", "radius", "length", "buckling", "bond_nt", "molecule"}; - fields_exchange = {"rmass", "radius", "length", "buckling", "bond_nt", "molecule"}; - fields_restart = {"rmass", "radius", "length", "buckling", "bond_nt", "molecule"}; - fields_create = {"rmass", "radius", "length", "buckling", "bond_nt", "molecule"}; - fields_data_atom = {"id", "molecule", "type", "bond_nt", "rmass", - "radius", "length", "buckling", "x"}; - fields_data_vel = {"id", "v"}; - - setup_fields(); -} diff --git a/src/MESONT/atom_vec_mesont.h b/src/MESONT/atom_vec_mesont.h deleted file mode 100644 index 44f3f97084..0000000000 --- a/src/MESONT/atom_vec_mesont.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. - - Contributing author: Maxim Shugaev (UVA), mvs9t@virginia.edu -------------------------------------------------------------------------- */ - -#ifdef ATOM_CLASS -// clang-format off -AtomStyle(mesont,AtomVecMesoNT); -// clang-format on -#else - -#ifndef LMP_ATOM_VEC_MESONT_H -#define LMP_ATOM_VEC_MESONT_H - -#include "atom_vec.h" - -namespace LAMMPS_NS { - -class AtomVecMesoNT : virtual public AtomVec { - public: - AtomVecMesoNT(class LAMMPS *); -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/MESONT/compute_mesont.cpp b/src/MESONT/compute_mesont.cpp deleted file mode 100644 index a2831e5d7a..0000000000 --- a/src/MESONT/compute_mesont.cpp +++ /dev/null @@ -1,156 +0,0 @@ -// clang-format off -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. - - Contributing author: Maxim Shugaev (UVA), mvs9t@virginia.edu -------------------------------------------------------------------------- */ - -#include "compute_mesont.h" - -#include "atom.h" -#include "comm.h" -#include "error.h" -#include "force.h" -#include "memory.h" -#include "pair.h" -#include "update.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -ComputeMesoNT::ComputeMesoNT(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), energy(nullptr) { - 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 = nullptr; - if (compute_type == ES) - ptr = static_cast(force->pair->extract("mesonttpm_Es_tot",i)); - else if (compute_type == EB) - ptr = static_cast(force->pair->extract("mesonttpm_Eb_tot",i)); - else if (compute_type == ET) - ptr = static_cast(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 = nullptr; - if (compute_type == ES) - ptr = static_cast(force->pair->extract("mesonttpm_Es",i)); - else if (compute_type == EB) - ptr = static_cast(force->pair->extract("mesonttpm_Eb",i)); - else if (compute_type == ET) - ptr = static_cast(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(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 = (double)nmax * sizeof(double); - return bytes; -} diff --git a/src/MESONT/compute_mesont.h b/src/MESONT/compute_mesont.h deleted file mode 100644 index 893d61a990..0000000000 --- a/src/MESONT/compute_mesont.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. - - Contributing author: Maxim Shugaev (UVA), mvs9t@virginia.edu -------------------------------------------------------------------------- */ - -#ifdef COMPUTE_CLASS -// clang-format off -ComputeStyle(mesont,ComputeMesoNT); -// clang-format on -#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() override; - void init() override {} - void compute_peratom() override; - double compute_scalar() override; - int pack_reverse_comm(int, int, double *) override; - void unpack_reverse_comm(int, int *, double *) override; - double memory_usage() override; - - private: - int nmax; - double *energy; - - enum ComputeType { ES, EB, ET }; - ComputeType compute_type; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/MESONT/export_mesont.h b/src/MESONT/export_mesont.h deleted file mode 100644 index 92ce1acf95..0000000000 --- a/src/MESONT/export_mesont.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. - - 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 diff --git a/src/MESONT/pair_mesont_tpm.cpp b/src/MESONT/pair_mesont_tpm.cpp deleted file mode 100644 index 39582f3e6a..0000000000 --- a/src/MESONT/pair_mesont_tpm.cpp +++ /dev/null @@ -1,777 +0,0 @@ -// clang-format off -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. - Contributing author: Maxim Shugaev (UVA), mvs9t@virginia.edu -------------------------------------------------------------------------- */ - -#include "pair_mesont_tpm.h" -#include "export_mesont.h" - -#include "atom.h" -#include "comm.h" -#include "force.h" -#include "memory.h" -#include "error.h" -#include "neighbor.h" -#include "neigh_list.h" - -#include -#include - -#include -#include -#include - -using namespace LAMMPS_NS; - -class MESONTList { -public: - MESONTList(const Atom* atom, const NeighList* nblist); - ~MESONTList() = default;; - //list of segments - const std::vector>& get_segments() const; - //list of triplets - const std::vector>& get_triplets() const; - //list of neighbor chains [start,end] for segments - //(use idx() to get real indexes) - const std::vector>>& 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& 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& get_idxb_list() const; - //check if the node is the end of the tube - bool is_end(int idx) const; - - std::array get_segment(int idx) const; - std::array 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> chain_list, segments; - std::vector> triplets; - std::vector>> nb_chains; - std::vector index_list, index_list_b; -}; - -//============================================================================= - -inline const std::vector>> & - MESONTList::get_nbs() const { - return nb_chains; -} - -inline int MESONTList::get_idx(int idx) const { - return index_list[idx]; -} - -inline const std::vector& 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& MESONTList::get_idxb_list() const { - return index_list_b; -}; - -inline const std::vector> & MESONTList::get_segments() - const { - return segments; -} - -inline const std::vector> & MESONTList::get_triplets() - const { - return triplets; -} - -inline std::array MESONTList::get_segment(int idx) const { - std::array result; - result[0] = chain_list[idx][0]; - result[1] = idx; - return result; -} - -inline std::array MESONTList::get_triplet(int idx) const { - std::array 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 -void vector_union(std::vector& v1, std::vector& v2, - std::vector& merged) { - std::sort(v1.begin(), v1.end()); - std::sort(v2.begin(), v2.end()); - merged.reserve(v1.size() + v2.size()); - typename std::vector::iterator it1 = v1.begin(); - typename std::vector::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) { - if (atom == nullptr || nblist == nullptr) return; - //number of local atoms at the node - int nlocal = atom->nlocal; - //total number of atoms in the node and ghost shell treated as NTs - int nall = nblist->inum + nblist->gnum; - //total number of atoms in the node and ghost shell - 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 - chain_list.resize(ntot, {not_cnt,not_cnt}); - 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 (true) { - 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]]) - segments.push_back({i,chain_list[i][0]}); - if (chain_list[i][1] != cnt_end && chain_list[i][1] != domain_end && - g_id[i] < g_id[chain_list[i][1]]) - segments.push_back({i,chain_list[i][1]}); - } - 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 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)) { - std::array 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 = nullptr; - tab_path_length = 0; - - eatom_s = nullptr; - eatom_b = nullptr; - eatom_t = nullptr; - nmax = 0; - 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 != nullptr) memory->destroy(tab_path); -} - -/* ---------------------------------------------------------------------- */ - -void PairMESONTTPM::compute(int eflag, int vflag) { - // set per atom values and accumulators - // reallocate per-atom arrays if necessary - ev_init(eflag,vflag); - if (atom->nmax > nmax && eflag_atom) { - 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"); - nmax = atom->nmax; - } - //total number of atoms in the node and ghost shell treated as NTs - int nall = list->inum + list->gnum; - //total number of atoms in the node and ghost shell - 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) { - error->all(FLERR, "The selected cutoff is too small for the current system : " - "L_max = {:.8}, R_max = {:.8}, Rc = {:.8}, Rcut_min = {:.8}", - Lmax, RT, cut_global, Rcut_min); - } - - //generate bonds and chain nblist - MESONTList ntlist(atom, list); - - //reorder data to make it contiguous within tubes - //and compatible with Fortran functions - std::vector x_sort(3*nall), f_sort(3*nall), s_sort(9*nall); - std::vector u_ts_sort(nall), u_tb_sort(nall), u_tt_sort(nall); - std::vector 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 std::array& 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(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 std::array& 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 std::array& 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) { - error->all(FLERR, "The selected cutoff is too small for the current system : " - "L_max = {:.8}, R_max = {:.8}, Rc = {:.8}, Rcut_min = {:.8}", - Lmax, RT, cut_global, Rcut_min); - } - - //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]; - buckling[idx] = b_sort[i]; - } - if (eflag_global) { - energy_s = energy_b = energy_t = 0.0; - for (int i = 0; i < nall; i++) { - energy_s += u_ts_sort[i]; - energy_b += u_tb_sort[i]; - energy_t += u_tt_sort[i]; - } - eng_vdwl += energy_s + energy_b + energy_t; - } - if (eflag_atom) { - for (int i = 0; i < ntot; i++) - eatom_s[i] = eatom_b[i] = eatom_t[i] = 0.0; - - for (int i = 0; i < nall; i++) { - int idx = ntlist.get_idx(i); - 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]; - } - } - if (vflag_global) { - for (int i = 0; i < nall; i++) { - virial[0] += s_sort[9*i+0]; //xx - virial[1] += s_sort[9*i+4]; //yy - virial[2] += s_sort[9*i+8]; //zz - virial[3] += s_sort[9*i+1]; //xy - virial[4] += s_sort[9*i+2]; //xz - virial[5] += s_sort[9*i+5]; //yz - } - } - if (vflag_atom) { - for (int i = 0; i < nall; i++) { - int idx = ntlist.get_idx(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 - } - } - -} - -/* ---------------------------------------------------------------------- - 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 = utils::numeric(FLERR,arg[0],false,lmp); - - // 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 != nullptr) 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 = utils::numeric(FLERR,arg[2],false,lmp); - if ((BendingMode < 0) || (BendingMode > 1)) - error->all(FLERR,"Incorrect BendingMode"); - } - if (narg > 3) { - TPMType = utils::numeric(FLERR,arg[3],false,lmp); - 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; - utils::bounds(FLERR,arg[0],1,atom->ntypes,ilo,ihi,error); - utils::bounds(FLERR,arg[1],1,atom->ntypes,jlo,jhi,error); - - double cut_one = cut_global; - if (narg == 3) cut_one = utils::numeric(FLERR,arg[2],false,lmp); - - 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 != nullptr) 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) - neighbor->add_request(this, NeighConst::REQ_FULL | NeighConst::REQ_GHOST); -} - -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 nullptr; -}; diff --git a/src/MESONT/pair_mesont_tpm.h b/src/MESONT/pair_mesont_tpm.h deleted file mode 100644 index a83e124b56..0000000000 --- a/src/MESONT/pair_mesont_tpm.h +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. - - Contributing author: Maxim Shugaev (UVA), mvs9t@virginia.edu -------------------------------------------------------------------------- */ - -#ifdef PAIR_CLASS -// clang-format off -PairStyle(mesont/tpm,PairMESONTTPM); -// clang-format on -#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 *); - ~PairMESONTTPM() override; - void compute(int, int) override; - void settings(int, char **) override; - void coeff(int, char **) override; - double init_one(int, int) override; - void write_restart(FILE *) override; - void read_restart(FILE *) override; - void write_restart_settings(FILE *) override; - void read_restart_settings(FILE *) override; - void write_data(FILE *) override; - void write_data_all(FILE *) override; - void init_style() override; - - 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; - int nmax; - - virtual void allocate(); - void *extract(const char *, int &) override; -}; - -} // namespace LAMMPS_NS - -#endif -#endif diff --git a/src/MESONT/potentials.txt b/src/MESONT/potentials.txt index 8dc30da619..8798ba3ab9 100644 --- a/src/MESONT/potentials.txt +++ b/src/MESONT/potentials.txt @@ -1,4 +1,3 @@ # list of potential files to be fetched when this package is installed # potential file md5sum C_10_10.mesocnt 68b5ca26283968fd9889aa0a37f7b7fb -TABTP_10_10.mesont 744a739da49ad5e78492c1fc9fd9f8c1 diff --git a/src/Makefile b/src/Makefile index 13eeac58e7..a7c9985708 100644 --- a/src/Makefile +++ b/src/Makefile @@ -228,7 +228,6 @@ PACKLIB = \ latboltz \ lepton \ mdi \ - mesont \ molfile \ netcdf \ ml-pace \ @@ -243,7 +242,7 @@ PACKLIB = \ PACKSYS = compress latboltz mpiio python -PACKINT = atc awpmd colvars electrode gpu kokkos lepton mesont ml-pod poems +PACKINT = atc awpmd colvars electrode gpu kokkos lepton ml-pod poems PACKEXT = \ adios \ diff --git a/src/Purge.list b/src/Purge.list index 186454e0a2..a1fcc88b00 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -51,7 +51,15 @@ lmpinstalledpkgs.h lmpgitversion.h mliap_model_python_couple.cpp mliap_model_python_couple.h -# removed on 11 January 2022 +# removed on 20 January 2023 +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 +# removed on 11 January 2023 min_fire_old.cpp min_fire_old.h # renamed on 11 July 2022 diff --git a/src/compute_deprecated.cpp b/src/compute_deprecated.cpp index 8a32130b43..1ef86d5646 100644 --- a/src/compute_deprecated.cpp +++ b/src/compute_deprecated.cpp @@ -28,6 +28,11 @@ ComputeDeprecated::ComputeDeprecated(LAMMPS *lmp, int narg, char **arg) : Comput if (lmp->comm->me == 0) utils::logmesg(lmp, "\nCompute style 'DEPRECATED' is a dummy style\n\n"); return; + } else if (my_style == "mesont") { + if (lmp->comm->me == 0) + utils::logmesg(lmp, + "\nCompute style 'mesont' and the associated pair style have been " + "removed. Please use pair style 'mesocnt' instead.\n\n"); } error->all(FLERR, "This compute style is no longer available"); } diff --git a/src/compute_deprecated.h b/src/compute_deprecated.h index 0e19cca3f0..cc480c9a78 100644 --- a/src/compute_deprecated.h +++ b/src/compute_deprecated.h @@ -15,6 +15,7 @@ // clang-format off // list all deprecated and removed compute styles here ComputeStyle(DEPRECATED,ComputeDeprecated); +ComputeStyle(mesont,ComputeDeprecated); // clang-format on #else @@ -30,8 +31,6 @@ class ComputeDeprecated : public Compute { ComputeDeprecated(class LAMMPS *, int, char **); void init() override {} }; - } // namespace LAMMPS_NS - #endif #endif diff --git a/src/pair_deprecated.cpp b/src/pair_deprecated.cpp index eeb36d2171..db05cd1e06 100644 --- a/src/pair_deprecated.cpp +++ b/src/pair_deprecated.cpp @@ -48,6 +48,11 @@ void PairDeprecated::settings(int, char **) utils::logmesg(lmp, "\nPair style 'reax' has been removed from LAMMPS " "after the 12 December 2018 version\n\n"); + } else if (my_style == "mesont/tpm") { + if (lmp->comm->me == 0) + utils::logmesg(lmp, + "\nPair style 'mesont/tpm' has been removed from LAMMPS. " + "Please use pair style 'mesocnt' instead\n\n"); } error->all(FLERR, "This pair style is no longer available"); } diff --git a/src/pair_deprecated.h b/src/pair_deprecated.h index 3f6e72ab0f..c4753e7bbf 100644 --- a/src/pair_deprecated.h +++ b/src/pair_deprecated.h @@ -15,6 +15,7 @@ // clang-format off PairStyle(DEPRECATED,PairDeprecated); PairStyle(reax,PairDeprecated); +PairStyle(mesont/tpm,PairDeprecated); // clang-format on #else