From 56ca901cdbd65fe2351b33e93dd90c07eaa5bc34 Mon Sep 17 00:00:00 2001 From: Ian Bogle Date: Tue, 24 Jan 2023 09:36:18 -0600 Subject: [PATCH 001/448] Implement a "caching in LDS" approach for EAM to improve performance on HIP - Use a TeamPolicy rather than a RangePolicy to expose scratch - Team cooperates to load row-zero of spline into LDS - At runtime, decide whether value can be 'cached' in LDS, and conditionally load from LDS based on this Should be easily extendable / tunable for other architectures if ever required. Change-Id: Ie4254c8db1a7b14abafffe2b581014c5137bf7ed --- src/KOKKOS/pair_eam_kokkos.cpp | 302 +++++++++++++++++++++++++++++++-- src/KOKKOS/pair_eam_kokkos.h | 16 ++ 2 files changed, 302 insertions(+), 16 deletions(-) diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 6e1cd1feea..6837992f8b 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -31,9 +31,25 @@ #include "pair_kokkos.h" #include - using namespace LAMMPS_NS; +#define MAX_CACHE_ROWS 500 +#define MAX_CACHE_COLS 7 + +/* ---------------------------------------------------------------------- */ +template +auto policyInstance(int inum){ + #ifdef KOKKOS_ENABLE_HIP + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) + .set_scratch_size(0, + Kokkos::PerTeam(MAX_CACHE_ROWS*MAX_CACHE_COLS*sizeof(double))); + return policy; + #else + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + #endif +} + /* ---------------------------------------------------------------------- */ template @@ -182,9 +198,13 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) // compute kernel AB if (eflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + policyInstance>(inum), + *this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } if (eflag) { @@ -203,41 +223,65 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (evflag) { if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + policyInstance>(inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + policyInstance>(inum), + *this,ev); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + policyInstance>(inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + policyInstance>(inum), + *this,ev); } } else if (neighflag == FULL) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + policyInstance>(inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + policyInstance>(inum), + *this,ev); } } } else { if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } else if (neighflag == FULL) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } } @@ -614,7 +658,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelB, const int & EV_FLOAT ev; this->template operator()(TagPairEAMKernelB(), ii, ev); } - +/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ ////Specialisation for Neighborlist types Half, HalfThread, Full @@ -799,6 +843,232 @@ void PairEAMKokkos::operator()(TagPairEAMKernelCtemplate operator()(TagPairEAMKernelC(), ii, ev); } +/* ---------------------------------------------------------------------- */ + +////Specialisation for Neighborlist types Half, HalfThread, Full +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMKokkos::operator()(TagPairEAMKernelAB, + const typename Kokkos::TeamPolicy::member_type& team_member, + EV_FLOAT& ev) const { + int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); + // rho = density at each atom + // loop over neighbors of my atoms + const int m_max = d_rhor_spline.extent_int(1); + const int j_max = d_rhor_spline.extent_int(2); + const int d_rhor_spline_cached = (m_max > MAX_CACHE_ROWS || j_max > MAX_CACHE_COLS) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + + if(d_rhor_spline_cached){ + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()){ + int j = i%j_max; + int m = i/j_max; + A(m,j) = d_rhor_spline(0,m,j); + } + team_member.team_barrier(); + } + + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + + const int jnum = d_numneigh[i]; + + F_FLOAT rhotmp = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const int jtype = type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + F_FLOAT p = sqrt(rsq)*rdr + 1.0; + int m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + if(d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { + rhotmp += ((A(m,3)*p + A(m,4))*p + + A(m,5))*p + A(m,6); + } else + rhotmp += ((d_rhor_spline(d_type2rhor_ji,m,3)*p + d_rhor_spline(d_type2rhor_ji,m,4))*p + + d_rhor_spline(d_type2rhor_ji,m,5))*p + d_rhor_spline(d_type2rhor_ji,m,6); + } + + } + d_rho[i] += rhotmp; + + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + // if rho > rhomax (e.g. due to close approach of two atoms), + // will exceed table, so add linear term to conserve energy + + F_FLOAT p = d_rho[i]*rdrho + 1.0; + int m = static_cast (p); + m = MAX(1,MIN(m,nrho-1)); + p -= m; + p = MIN(p,1.0); + const int d_type2frho_i = d_type2frho[itype]; + d_fp[i] = (d_frho_spline(d_type2frho_i,m,0)*p + d_frho_spline(d_type2frho_i,m,1))*p + d_frho_spline(d_type2frho_i,m,2); + if (EFLAG) { + F_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + + d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); + if (d_rho[i] > rhomax) phi += d_fp[i] * (d_rho[i]-rhomax); + if (eflag_global) ev.evdwl += phi; + if (eflag_atom) d_eatom[i] += phi; + } + +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMKokkos::operator()(TagPairEAMKernelAB, + const typename Kokkos::TeamPolicy::member_type& team_member) const { + EV_FLOAT ev; + this->template operator()(TagPairEAMKernelAB(), team_member, ev); +} + +/* ---------------------------------------------------------------------- */ + +////Specialisation for Neighborlist types Half, HalfThread, Full +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMKokkos::operator()(TagPairEAMKernelC, + const typename Kokkos::TeamPolicy::member_type& team_member, + EV_FLOAT& ev) const { + + // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); + + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); + + const int m_max = d_z2r_spline.extent_int(1); + const int j_max = d_z2r_spline.extent_int(2); + const int d_z2r_spline_cached = (m_max > MAX_CACHE_ROWS || j_max > MAX_CACHE_COLS) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + + if(d_z2r_spline_cached){ + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()){ + int j = i%j_max; + int m = i/j_max; + A(m,j) = d_z2r_spline(0,m,j); + } + team_member.team_barrier(); + } + + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + + const int jnum = d_numneigh[i]; + + F_FLOAT fxtmp = 0.0; + F_FLOAT fytmp = 0.0; + F_FLOAT fztmp = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const int jtype = type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + const F_FLOAT r = sqrt(rsq); + F_FLOAT p = r*rdr + 1.0; + int m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + // z2 = phi * r + // z2p = (phi * r)' = (phi' r) + phi + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip + + const int d_type2rhor_ij = d_type2rhor(itype,jtype); + const F_FLOAT rhoip = (d_rhor_spline(d_type2rhor_ij,m,0)*p + d_rhor_spline(d_type2rhor_ij,m,1))*p + + d_rhor_spline(d_type2rhor_ij,m,2); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + const F_FLOAT rhojp = (d_rhor_spline(d_type2rhor_ji,m,0)*p + d_rhor_spline(d_type2rhor_ji,m,1))*p + + d_rhor_spline(d_type2rhor_ji,m,2); + const int d_type2z2r_ij = d_type2z2r(itype,jtype); + + const auto have_cache = (d_z2r_spline_cached == 1) && (0 == d_type2z2r_ij); + const auto z2r_spline_3 = (have_cache) ? A(m,3) : d_z2r_spline(d_type2z2r_ij,m,3); + const auto z2r_spline_4 = (have_cache) ? A(m,4) : d_z2r_spline(d_type2z2r_ij,m,4); + const auto z2r_spline_5 = (have_cache) ? A(m,5) : d_z2r_spline(d_type2z2r_ij,m,5); + const auto z2r_spline_6 = (have_cache) ? A(m,6) : d_z2r_spline(d_type2z2r_ij,m,6); + + const F_FLOAT z2p = (3.0*rdr*z2r_spline_3*p + 2.0*rdr*z2r_spline_4)*p + + rdr*z2r_spline_5; // the rdr and the factors of 3.0 and 2.0 come out of the interpolate function + const F_FLOAT z2 = ((z2r_spline_3*p + z2r_spline_4)*p + + z2r_spline_5)*p + z2r_spline_6; + + const F_FLOAT recip = 1.0/r; + const F_FLOAT phi = z2*recip; + const F_FLOAT phip = z2p*recip - phi*recip; + const F_FLOAT psip = d_fp[i]*rhojp + d_fp[j]*rhoip + phip; + const F_FLOAT fpair = -psip*recip; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { + a_f(j,0) -= delx*fpair; + a_f(j,1) -= dely*fpair; + a_f(j,2) -= delz*fpair; + } + + if (EVFLAG) { + if (eflag) { + ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,phi,fpair,delx,dely,delz); + } + + } + } + + a_f(i,0) += fxtmp; + a_f(i,1) += fytmp; + a_f(i,2) += fztmp; +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMKokkos::operator()(TagPairEAMKernelC, + /*const int &ii*/ + const typename Kokkos::TeamPolicy::member_type& team_member) const { + EV_FLOAT ev; + this->template operator()(TagPairEAMKernelC(), team_member, ev); +} /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index 006dceb1f2..21cf188cd6 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -89,6 +89,14 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMKernelAB, const int&) const; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMKernelAB, const typename Kokkos::TeamPolicy::member_type&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMKernelAB, const typename Kokkos::TeamPolicy::member_type&) const; + template KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMKernelC, const int&, EV_FLOAT&) const; @@ -97,6 +105,14 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMKernelC, const int&) const; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMKernelC, const typename Kokkos::TeamPolicy::member_type&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMKernelC, const typename Kokkos::TeamPolicy::member_type&) const; + template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &ev, const int &i, const int &j, From 55f454db2d2eef62d9551047be26086361f89b7d Mon Sep 17 00:00:00 2001 From: Ian Bogle Date: Fri, 3 Feb 2023 13:35:38 -0600 Subject: [PATCH 002/448] Addressed feedback from LAMMPS developers: - moved policyInstance into the EAM class - eliminated MAX_CACHE_COLS define, in favor of the static_extent of the spline view type - made inum a protected member var that allows range checking inside TeamPolicy kernels - added range checking after initializing the cached table in TeamPolicy kernels - correctness and perf checks pass Change-Id: Iaaf34f7560c37e0a2a34e980761246d3ef42be99 --- src/KOKKOS/pair_eam_kokkos.cpp | 294 +++++++++++++++++---------------- src/KOKKOS/pair_eam_kokkos.h | 7 +- 2 files changed, 155 insertions(+), 146 deletions(-) diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 6837992f8b..cc3b606b17 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -34,15 +34,18 @@ using namespace LAMMPS_NS; #define MAX_CACHE_ROWS 500 -#define MAX_CACHE_COLS 7 /* ---------------------------------------------------------------------- */ -template -auto policyInstance(int inum){ +template +template +auto PairEAMKokkos::policyInstance(int inum){ #ifdef KOKKOS_ENABLE_HIP + static_assert(t_ffloat_2d_n7::static_extent(2) == 7, + "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) .set_scratch_size(0, - Kokkos::PerTeam(MAX_CACHE_ROWS*MAX_CACHE_COLS*sizeof(double))); + Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); return policy; #else auto policy = Kokkos::RangePolicy(0,inum); @@ -129,7 +132,7 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) d_numneigh = k_list->d_numneigh; d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - int inum = list->inum; + inum = list->inum; need_dup = lmp->kokkos->need_dup(); if (need_dup) { @@ -199,11 +202,11 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (eflag) Kokkos::parallel_reduce( - policyInstance>(inum), + policyInstance>(inum), *this,ev); else Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>(inum), *this); } @@ -224,31 +227,31 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_reduce( - policyInstance>(inum), + policyInstance>(inum), *this,ev); } else { Kokkos::parallel_reduce( - policyInstance>(inum), + policyInstance>(inum), *this,ev); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_reduce( - policyInstance>(inum), + policyInstance>(inum), *this,ev); } else { Kokkos::parallel_reduce( - policyInstance>(inum), + policyInstance>(inum), *this,ev); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_reduce( - policyInstance>(inum), + policyInstance>(inum), *this,ev); } else { Kokkos::parallel_reduce( - policyInstance>(inum), + policyInstance>(inum), *this,ev); } } @@ -256,31 +259,31 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>(inum), *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>(inum), *this); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>(inum), *this); } } @@ -857,8 +860,8 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, // loop over neighbors of my atoms const int m_max = d_rhor_spline.extent_int(1); const int j_max = d_rhor_spline.extent_int(2); - const int d_rhor_spline_cached = (m_max > MAX_CACHE_ROWS || j_max > MAX_CACHE_COLS) ? 0 : 1; - Kokkos::View MAX_CACHE_ROWS || j_max > t_ffloat_2d_n7::static_extent(2)) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); if(d_rhor_spline_cached){ @@ -869,65 +872,65 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, } team_member.team_barrier(); } + if (ii < inum){ + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); - const int i = d_ilist[ii]; - const X_FLOAT xtmp = x(i,0); - const X_FLOAT ytmp = x(i,1); - const X_FLOAT ztmp = x(i,2); - const int itype = type(i); + const int jnum = d_numneigh[i]; - const int jnum = d_numneigh[i]; + F_FLOAT rhotmp = 0.0; - F_FLOAT rhotmp = 0.0; + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; - for (int jj = 0; jj < jnum; jj++) { - int j = d_neighbors(i,jj); - j &= NEIGHMASK; + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const int jtype = type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; - const X_FLOAT delx = xtmp - x(j,0); - const X_FLOAT dely = ytmp - x(j,1); - const X_FLOAT delz = ztmp - x(j,2); - const int jtype = type(j); - const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + if (rsq < cutforcesq) { + F_FLOAT p = sqrt(rsq)*rdr + 1.0; + int m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + if(d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { + rhotmp += ((A(m,3)*p + A(m,4))*p + + A(m,5))*p + A(m,6); + } else + rhotmp += ((d_rhor_spline(d_type2rhor_ji,m,3)*p + d_rhor_spline(d_type2rhor_ji,m,4))*p + + d_rhor_spline(d_type2rhor_ji,m,5))*p + d_rhor_spline(d_type2rhor_ji,m,6); + } - if (rsq < cutforcesq) { - F_FLOAT p = sqrt(rsq)*rdr + 1.0; - int m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); - const int d_type2rhor_ji = d_type2rhor(jtype,itype); - if(d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { - rhotmp += ((A(m,3)*p + A(m,4))*p + - A(m,5))*p + A(m,6); - } else - rhotmp += ((d_rhor_spline(d_type2rhor_ji,m,3)*p + d_rhor_spline(d_type2rhor_ji,m,4))*p + - d_rhor_spline(d_type2rhor_ji,m,5))*p + d_rhor_spline(d_type2rhor_ji,m,6); } + d_rho[i] += rhotmp; + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + // if rho > rhomax (e.g. due to close approach of two atoms), + // will exceed table, so add linear term to conserve energy + + F_FLOAT p = d_rho[i]*rdrho + 1.0; + int m = static_cast (p); + m = MAX(1,MIN(m,nrho-1)); + p -= m; + p = MIN(p,1.0); + const int d_type2frho_i = d_type2frho[itype]; + d_fp[i] = (d_frho_spline(d_type2frho_i,m,0)*p + d_frho_spline(d_type2frho_i,m,1))*p + d_frho_spline(d_type2frho_i,m,2); + if (EFLAG) { + F_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + + d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); + if (d_rho[i] > rhomax) phi += d_fp[i] * (d_rho[i]-rhomax); + if (eflag_global) ev.evdwl += phi; + if (eflag_atom) d_eatom[i] += phi; + } } - d_rho[i] += rhotmp; - - // fp = derivative of embedding energy at each atom - // phi = embedding energy at each atom - // if rho > rhomax (e.g. due to close approach of two atoms), - // will exceed table, so add linear term to conserve energy - - F_FLOAT p = d_rho[i]*rdrho + 1.0; - int m = static_cast (p); - m = MAX(1,MIN(m,nrho-1)); - p -= m; - p = MIN(p,1.0); - const int d_type2frho_i = d_type2frho[itype]; - d_fp[i] = (d_frho_spline(d_type2frho_i,m,0)*p + d_frho_spline(d_type2frho_i,m,1))*p + d_frho_spline(d_type2frho_i,m,2); - if (EFLAG) { - F_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + - d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); - if (d_rho[i] > rhomax) phi += d_fp[i] * (d_rho[i]-rhomax); - if (eflag_global) ev.evdwl += phi; - if (eflag_atom) d_eatom[i] += phi; - } - } template @@ -957,8 +960,8 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC MAX_CACHE_ROWS || j_max > MAX_CACHE_COLS) ? 0 : 1; - Kokkos::View MAX_CACHE_ROWS || j_max > t_ffloat_2d_n7::static_extent(2)) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); if(d_z2r_spline_cached){ @@ -969,95 +972,96 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); - if (rsq < cutforcesq) { - const F_FLOAT r = sqrt(rsq); - F_FLOAT p = r*rdr + 1.0; - int m = static_cast (p); - m = MIN(m,nr-1); - p -= m; - p = MIN(p,1.0); + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + // z2 = phi * r + // z2p = (phi * r)' = (phi' r) + phi + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip - // rhoip = derivative of (density at atom j due to atom i) - // rhojp = derivative of (density at atom i due to atom j) - // phi = pair potential energy - // phip = phi' - // z2 = phi * r - // z2p = (phi * r)' = (phi' r) + phi - // psip needs both fp[i] and fp[j] terms since r_ij appears in two - // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) - // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip - - const int d_type2rhor_ij = d_type2rhor(itype,jtype); - const F_FLOAT rhoip = (d_rhor_spline(d_type2rhor_ij,m,0)*p + d_rhor_spline(d_type2rhor_ij,m,1))*p + + const int d_type2rhor_ij = d_type2rhor(itype,jtype); + const F_FLOAT rhoip = (d_rhor_spline(d_type2rhor_ij,m,0)*p + d_rhor_spline(d_type2rhor_ij,m,1))*p + d_rhor_spline(d_type2rhor_ij,m,2); - const int d_type2rhor_ji = d_type2rhor(jtype,itype); - const F_FLOAT rhojp = (d_rhor_spline(d_type2rhor_ji,m,0)*p + d_rhor_spline(d_type2rhor_ji,m,1))*p + - d_rhor_spline(d_type2rhor_ji,m,2); - const int d_type2z2r_ij = d_type2z2r(itype,jtype); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + const F_FLOAT rhojp = (d_rhor_spline(d_type2rhor_ji,m,0)*p + d_rhor_spline(d_type2rhor_ji,m,1))*p + + d_rhor_spline(d_type2rhor_ji,m,2); + const int d_type2z2r_ij = d_type2z2r(itype,jtype); - const auto have_cache = (d_z2r_spline_cached == 1) && (0 == d_type2z2r_ij); - const auto z2r_spline_3 = (have_cache) ? A(m,3) : d_z2r_spline(d_type2z2r_ij,m,3); - const auto z2r_spline_4 = (have_cache) ? A(m,4) : d_z2r_spline(d_type2z2r_ij,m,4); - const auto z2r_spline_5 = (have_cache) ? A(m,5) : d_z2r_spline(d_type2z2r_ij,m,5); - const auto z2r_spline_6 = (have_cache) ? A(m,6) : d_z2r_spline(d_type2z2r_ij,m,6); + const auto have_cache = (d_z2r_spline_cached == 1) && (0 == d_type2z2r_ij); + const auto z2r_spline_3 = (have_cache) ? A(m,3) : d_z2r_spline(d_type2z2r_ij,m,3); + const auto z2r_spline_4 = (have_cache) ? A(m,4) : d_z2r_spline(d_type2z2r_ij,m,4); + const auto z2r_spline_5 = (have_cache) ? A(m,5) : d_z2r_spline(d_type2z2r_ij,m,5); + const auto z2r_spline_6 = (have_cache) ? A(m,6) : d_z2r_spline(d_type2z2r_ij,m,6); - const F_FLOAT z2p = (3.0*rdr*z2r_spline_3*p + 2.0*rdr*z2r_spline_4)*p + - rdr*z2r_spline_5; // the rdr and the factors of 3.0 and 2.0 come out of the interpolate function - const F_FLOAT z2 = ((z2r_spline_3*p + z2r_spline_4)*p + - z2r_spline_5)*p + z2r_spline_6; + const F_FLOAT z2p = (3.0*rdr*z2r_spline_3*p + 2.0*rdr*z2r_spline_4)*p + + rdr*z2r_spline_5; // the rdr and the factors of 3.0 and 2.0 come out of the interpolate function + const F_FLOAT z2 = ((z2r_spline_3*p + z2r_spline_4)*p + + z2r_spline_5)*p + z2r_spline_6; - const F_FLOAT recip = 1.0/r; - const F_FLOAT phi = z2*recip; - const F_FLOAT phip = z2p*recip - phi*recip; - const F_FLOAT psip = d_fp[i]*rhojp + d_fp[j]*rhoip + phip; - const F_FLOAT fpair = -psip*recip; + const F_FLOAT recip = 1.0/r; + const F_FLOAT phi = z2*recip; + const F_FLOAT phip = z2p*recip - phi*recip; + const F_FLOAT psip = d_fp[i]*rhojp + d_fp[j]*rhoip + phip; + const F_FLOAT fpair = -psip*recip; - fxtmp += delx*fpair; - fytmp += dely*fpair; - fztmp += delz*fpair; + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; - if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { - a_f(j,0) -= delx*fpair; - a_f(j,1) -= dely*fpair; - a_f(j,2) -= delz*fpair; - } - - if (EVFLAG) { - if (eflag) { - ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,phi,fpair,delx,dely,delz); } - if (vflag_either || eflag_atom) this->template ev_tally(ev,i,j,phi,fpair,delx,dely,delz); } - } - } - a_f(i,0) += fxtmp; - a_f(i,1) += fytmp; - a_f(i,2) += fztmp; + a_f(i,0) += fxtmp; + a_f(i,1) += fytmp; + a_f(i,2) += fztmp; + } } template diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index 21cf188cd6..a42f1efef6 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -55,10 +55,14 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { typedef ArrayTypes AT; typedef EV_FLOAT value_type; + template + auto policyInstance(int inum); + PairEAMKokkos(class LAMMPS *); ~PairEAMKokkos() override; void compute(int, int) override; void init_style() override; + KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMPackForwardComm, const int&) const; @@ -138,7 +142,8 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { typename AT::t_virial_array d_vatom; int need_dup; - + int inum; + using KKDeviceType = typename KKDevice::value; template From 1c77ffc28894c94007ea5a47e86ea596420424ae Mon Sep 17 00:00:00 2001 From: Nick Curtis Date: Fri, 3 Feb 2023 14:57:56 -0500 Subject: [PATCH 003/448] catch missing static extents Change-Id: I456282b172053a3566b1ce9a36bc33d377bd801a --- src/KOKKOS/pair_eam_kokkos.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index cc3b606b17..5d441df6a9 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -859,8 +859,8 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, // rho = density at each atom // loop over neighbors of my atoms const int m_max = d_rhor_spline.extent_int(1); - const int j_max = d_rhor_spline.extent_int(2); - const int d_rhor_spline_cached = (m_max > MAX_CACHE_ROWS || j_max > t_ffloat_2d_n7::static_extent(2)) ? 0 : 1; + const int j_max = t_ffloat_2d_n7::static_extent(2); + const int d_rhor_spline_cached = (m_max > MAX_CACHE_ROWS) ? 0 : 1; Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); @@ -959,8 +959,8 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC>(); const int m_max = d_z2r_spline.extent_int(1); - const int j_max = d_z2r_spline.extent_int(2); - const int d_z2r_spline_cached = (m_max > MAX_CACHE_ROWS || j_max > t_ffloat_2d_n7::static_extent(2)) ? 0 : 1; + const int j_max = t_ffloat_2d_n7::static_extent(2); + const int d_z2r_spline_cached = (m_max > MAX_CACHE_ROWS) ? 0 : 1; Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); From 19bcf6b43cf25062743f2aae15f465c548180de6 Mon Sep 17 00:00:00 2001 From: Nick Curtis Date: Wed, 8 Feb 2023 13:43:47 -0500 Subject: [PATCH 004/448] revert to simple ParReduce policy for reductions Change-Id: Ib3018e85f7bc6c97ce9c0320d0ea43c743addacf --- src/KOKKOS/pair_eam_kokkos.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 5d441df6a9..0f5bfdec39 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -202,7 +202,7 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (eflag) Kokkos::parallel_reduce( - policyInstance>(inum), + Kokkos::RangePolicy>(0,inum), *this,ev); else Kokkos::parallel_for( @@ -227,31 +227,31 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_reduce( - policyInstance>(inum), + Kokkos::RangePolicy>(0,inum), *this,ev); } else { Kokkos::parallel_reduce( - policyInstance>(inum), + Kokkos::RangePolicy>(0,inum), *this,ev); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_reduce( - policyInstance>(inum), + Kokkos::RangePolicy>(0,inum), *this,ev); } else { Kokkos::parallel_reduce( - policyInstance>(inum), + Kokkos::RangePolicy>(0,inum), *this,ev); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_reduce( - policyInstance>(inum), + Kokkos::RangePolicy>(0,inum), *this,ev); } else { Kokkos::parallel_reduce( - policyInstance>(inum), + Kokkos::RangePolicy>(0,inum), *this,ev); } } From 23bfc1666cb48a48b32920662784e1fd7daedc16 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 10 Feb 2023 09:24:18 -0700 Subject: [PATCH 005/448] Use range_policy if running on host, small cleanup --- src/KOKKOS/pair_eam_kokkos.cpp | 61 +++++++++++++++++++--------------- src/KOKKOS/pair_eam_kokkos.h | 6 ++-- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 0f5bfdec39..2317f2d367 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -35,24 +35,6 @@ using namespace LAMMPS_NS; #define MAX_CACHE_ROWS 500 -/* ---------------------------------------------------------------------- */ -template -template -auto PairEAMKokkos::policyInstance(int inum){ - #ifdef KOKKOS_ENABLE_HIP - static_assert(t_ffloat_2d_n7::static_extent(2) == 7, - "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); - - auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) - .set_scratch_size(0, - Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); - return policy; - #else - auto policy = Kokkos::RangePolicy(0,inum); - return policy; - #endif -} - /* ---------------------------------------------------------------------- */ template @@ -864,15 +846,15 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); - if(d_rhor_spline_cached){ - for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()){ + if (d_rhor_spline_cached) { + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { int j = i%j_max; int m = i/j_max; A(m,j) = d_rhor_spline(0,m,j); } team_member.team_barrier(); } - if (ii < inum){ + if (ii < inum) { const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); const X_FLOAT ytmp = x(i,1); @@ -900,7 +882,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, p -= m; p = MIN(p,1.0); const int d_type2rhor_ji = d_type2rhor(jtype,itype); - if(d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { + if (d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { rhotmp += ((A(m,3)*p + A(m,4))*p + A(m,5))*p + A(m,6); } else @@ -952,9 +934,10 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC::member_type& team_member, EV_FLOAT& ev) const { - // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); + // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); auto a_f = v_f.template access>(); @@ -964,15 +947,15 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC> A(team_member.team_scratch(0), MAX_CACHE_ROWS); - if(d_z2r_spline_cached){ - for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()){ + if (d_z2r_spline_cached) { + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { int j = i%j_max; int m = i/j_max; A(m,j) = d_z2r_spline(0,m,j); } team_member.team_barrier(); } - if (ii < inum){ + if (ii < inum) { const int i = d_ilist[ii]; const X_FLOAT xtmp = x(i,0); const X_FLOAT ytmp = x(i,1); @@ -1172,6 +1155,32 @@ void PairEAMKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int & } } +/* ---------------------------------------------------------------------- */ + +template +template +auto PairEAMKokkos::policyInstance(int inum) { + #ifdef KOKKOS_ENABLE_HIP + if (execution_space != Host) { + static_assert(t_ffloat_2d_n7::static_extent(2) == 7, + "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); + + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) + .set_scratch_size(0, + Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); + return policy; + } else { + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + } + #else + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + #endif +} + +/* ---------------------------------------------------------------------- */ + namespace LAMMPS_NS { template class PairEAMKokkos; #ifdef LMP_KOKKOS_GPU diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index a42f1efef6..7f4ec67f6f 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -55,9 +55,6 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { typedef ArrayTypes AT; typedef EV_FLOAT value_type; - template - auto policyInstance(int inum); - PairEAMKokkos(class LAMMPS *); ~PairEAMKokkos() override; void compute(int, int) override; @@ -183,6 +180,9 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { void file2array() override; void array2spline() override; + template + auto policyInstance(int inum); + typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d d_ilist; typename AT::t_int_1d d_numneigh; From d0c6c310d95af99482f5e41e8cffdc2eaa1d758a Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 10 Feb 2023 10:50:36 -0700 Subject: [PATCH 006/448] Port changes to other EAM flavors --- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 348 +++++++++++++++++++++++--- src/KOKKOS/pair_eam_alloy_kokkos.h | 28 ++- src/KOKKOS/pair_eam_fs_kokkos.cpp | 349 ++++++++++++++++++++++++--- src/KOKKOS/pair_eam_fs_kokkos.h | 27 ++- src/KOKKOS/pair_eam_kokkos.cpp | 94 ++++---- src/KOKKOS/pair_eam_kokkos.h | 5 +- 6 files changed, 724 insertions(+), 127 deletions(-) diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index e14b78a36f..477220b65e 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -32,10 +32,10 @@ #include "potential_file_reader.h" #include -#include - using namespace LAMMPS_NS; +#define MAX_CACHE_ROWS 500 + // Cannot use virtual inheritance on the GPU, so must duplicate code /* ---------------------------------------------------------------------- */ @@ -46,6 +46,7 @@ PairEAMAlloyKokkos::PairEAMAlloyKokkos(LAMMPS *lmp) : PairEAM(lmp) respa_enable = 0; single_enable = 0; one_coeff = 1; + manybody_flag = 1; kokkosable = 1; atomKK = (AtomKokkos *) atom; @@ -59,10 +60,10 @@ PairEAMAlloyKokkos::PairEAMAlloyKokkos(LAMMPS *lmp) : PairEAM(lmp) template PairEAMAlloyKokkos::~PairEAMAlloyKokkos() { - if (!copymode) { - memoryKK->destroy_kokkos(k_eatom,eatom); - memoryKK->destroy_kokkos(k_vatom,vatom); - } + if (copymode) return; + + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->destroy_kokkos(k_vatom,vatom); } /* ---------------------------------------------------------------------- */ @@ -118,7 +119,7 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) d_numneigh = k_list->d_numneigh; d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - int inum = list->inum; + inum = list->inum; need_dup = lmp->kokkos->need_dup(); if (need_dup) { @@ -138,9 +139,9 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) // zero out density if (newton_pair) - Kokkos::parallel_for(Kokkos::RangePolicy(0,nall),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,nall),*this); else - Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); // loop over neighbors of my atoms @@ -152,15 +153,15 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } } @@ -178,18 +179,22 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) // compute kernel B if (eflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else if (neighflag == FULL) { // compute kernel AB if (eflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } if (eflag) { @@ -208,41 +213,65 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) if (evflag) { if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } } else if (neighflag == FULL) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } } } else { if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } else if (neighflag == FULL) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } } @@ -427,7 +456,7 @@ int PairEAMAlloyKokkos::pack_forward_comm_kokkos(int n, DAT::tdual_i d_sendlist = k_sendlist.view(); iswap = iswap_in; v_buf = buf.view(); - Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); return n; } @@ -445,7 +474,7 @@ void PairEAMAlloyKokkos::unpack_forward_comm_kokkos(int n, int first { first = first_in; v_buf = buf.view(); - Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); } template @@ -588,6 +617,7 @@ template template KOKKOS_INLINE_FUNCTION void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelB, const int &ii, EV_FLOAT& ev) const { + // fp = derivative of embedding energy at each atom // phi = embedding energy at each atom // if rho > rhomax (e.g. due to close approach of two atoms), @@ -625,7 +655,7 @@ void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelB, c ////Specialisation for Neighborlist types Half, HalfThread, Full template template -KOKKOS_INLINE_FUNCTION + void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelAB, const int &ii, EV_FLOAT& ev) const { // rho = density at each atom @@ -644,6 +674,7 @@ void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelAB, for (int jj = 0; jj < jnum; jj++) { int j = d_neighbors(i,jj); j &= NEIGHMASK; + const X_FLOAT delx = xtmp - x(j,0); const X_FLOAT dely = ytmp - x(j,1); const X_FLOAT delz = ztmp - x(j,2); @@ -806,6 +837,235 @@ void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelC +template +KOKKOS_INLINE_FUNCTION +void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelAB, + const typename Kokkos::TeamPolicy::member_type& team_member, + EV_FLOAT& ev) const { + int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); + // rho = density at each atom + // loop over neighbors of my atoms + const int m_max = d_rhor_spline.extent_int(1); + const int j_max = t_ffloat_2d_n7::static_extent(2); + const int d_rhor_spline_cached = (m_max > MAX_CACHE_ROWS) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + + if (d_rhor_spline_cached) { + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { + int j = i%j_max; + int m = i/j_max; + A(m,j) = d_rhor_spline(0,m,j); + } + team_member.team_barrier(); + } + if (ii < inum) { + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + + const int jnum = d_numneigh[i]; + + F_FLOAT rhotmp = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const int jtype = type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + F_FLOAT p = sqrt(rsq)*rdr + 1.0; + int m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + if (d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { + rhotmp += ((A(m,3)*p + A(m,4))*p + + A(m,5))*p + A(m,6); + } else + rhotmp += ((d_rhor_spline(d_type2rhor_ji,m,3)*p + d_rhor_spline(d_type2rhor_ji,m,4))*p + + d_rhor_spline(d_type2rhor_ji,m,5))*p + d_rhor_spline(d_type2rhor_ji,m,6); + } + + } + d_rho[i] += rhotmp; + + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + // if rho > rhomax (e.g. due to close approach of two atoms), + // will exceed table, so add linear term to conserve energy + + F_FLOAT p = d_rho[i]*rdrho + 1.0; + int m = static_cast (p); + m = MAX(1,MIN(m,nrho-1)); + p -= m; + p = MIN(p,1.0); + const int d_type2frho_i = d_type2frho[itype]; + d_fp[i] = (d_frho_spline(d_type2frho_i,m,0)*p + d_frho_spline(d_type2frho_i,m,1))*p + d_frho_spline(d_type2frho_i,m,2); + if (EFLAG) { + F_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + + d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); + if (d_rho[i] > rhomax) phi += d_fp[i] * (d_rho[i]-rhomax); + if (eflag_global) ev.evdwl += phi; + if (eflag_atom) d_eatom[i] += phi; + } + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelAB, + const typename Kokkos::TeamPolicy::member_type& team_member) const { + EV_FLOAT ev; + this->template operator()(TagPairEAMAlloyKernelAB(), team_member, ev); +} + +/* ---------------------------------------------------------------------- */ + +////Specialisation for Neighborlist types Half, HalfThread, Full +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelC, + const typename Kokkos::TeamPolicy::member_type& team_member, + EV_FLOAT& ev) const { + + int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); + + // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); + + const int m_max = d_z2r_spline.extent_int(1); + const int j_max = t_ffloat_2d_n7::static_extent(2); + const int d_z2r_spline_cached = (m_max > MAX_CACHE_ROWS) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + + if (d_z2r_spline_cached) { + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { + int j = i%j_max; + int m = i/j_max; + A(m,j) = d_z2r_spline(0,m,j); + } + team_member.team_barrier(); + } + if (ii < inum) { + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + + const int jnum = d_numneigh[i]; + + F_FLOAT fxtmp = 0.0; + F_FLOAT fytmp = 0.0; + F_FLOAT fztmp = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const int jtype = type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + const F_FLOAT r = sqrt(rsq); + F_FLOAT p = r*rdr + 1.0; + int m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + // z2 = phi * r + // z2p = (phi * r)' = (phi' r) + phi + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip + + const int d_type2rhor_ij = d_type2rhor(itype,jtype); + const F_FLOAT rhoip = (d_rhor_spline(d_type2rhor_ij,m,0)*p + d_rhor_spline(d_type2rhor_ij,m,1))*p + + d_rhor_spline(d_type2rhor_ij,m,2); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + const F_FLOAT rhojp = (d_rhor_spline(d_type2rhor_ji,m,0)*p + d_rhor_spline(d_type2rhor_ji,m,1))*p + + d_rhor_spline(d_type2rhor_ji,m,2); + const int d_type2z2r_ij = d_type2z2r(itype,jtype); + + const auto have_cache = (d_z2r_spline_cached == 1) && (0 == d_type2z2r_ij); + const auto z2r_spline_3 = (have_cache) ? A(m,3) : d_z2r_spline(d_type2z2r_ij,m,3); + const auto z2r_spline_4 = (have_cache) ? A(m,4) : d_z2r_spline(d_type2z2r_ij,m,4); + const auto z2r_spline_5 = (have_cache) ? A(m,5) : d_z2r_spline(d_type2z2r_ij,m,5); + const auto z2r_spline_6 = (have_cache) ? A(m,6) : d_z2r_spline(d_type2z2r_ij,m,6); + + const F_FLOAT z2p = (3.0*rdr*z2r_spline_3*p + 2.0*rdr*z2r_spline_4)*p + + rdr*z2r_spline_5; // the rdr and the factors of 3.0 and 2.0 come out of the interpolate function + const F_FLOAT z2 = ((z2r_spline_3*p + z2r_spline_4)*p + + z2r_spline_5)*p + z2r_spline_6; + + const F_FLOAT recip = 1.0/r; + const F_FLOAT phi = z2*recip; + const F_FLOAT phip = z2p*recip - phi*recip; + const F_FLOAT psip = d_fp[i]*rhojp + d_fp[j]*rhoip + phip; + const F_FLOAT fpair = -psip*recip; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { + a_f(j,0) -= delx*fpair; + a_f(j,1) -= dely*fpair; + a_f(j,2) -= delz*fpair; + } + + if (EVFLAG) { + if (eflag) { + ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,phi,fpair,delx,dely,delz); + } + + } + } + + a_f(i,0) += fxtmp; + a_f(i,1) += fytmp; + a_f(i,2) += fztmp; + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelC, + /*const int &ii*/ + const typename Kokkos::TeamPolicy::member_type& team_member) const { + EV_FLOAT ev; + this->template operator()(TagPairEAMAlloyKernelC(), team_member, ev); +} + +/* ---------------------------------------------------------------------- */ + template template KOKKOS_INLINE_FUNCTION @@ -1219,6 +1479,30 @@ void PairEAMAlloyKokkos::file2array_alloy() /* ---------------------------------------------------------------------- */ +template +template +auto PairEAMAlloyKokkos::policyInstance(int inum) { + #ifdef KOKKOS_ENABLE_HIP + if (execution_space != Host) { + static_assert(t_ffloat_2d_n7::static_extent(2) == 7, + "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); + + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) + .set_scratch_size(0, + Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); + return policy; + } else { + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + } + #else + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + #endif +} + +/* ---------------------------------------------------------------------- */ + namespace LAMMPS_NS { template class PairEAMAlloyKokkos; #ifdef LMP_KOKKOS_GPU diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.h b/src/KOKKOS/pair_eam_alloy_kokkos.h index c6cb73ca5d..f9703ef473 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.h +++ b/src/KOKKOS/pair_eam_alloy_kokkos.h @@ -61,7 +61,6 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { ~PairEAMAlloyKokkos() override; void compute(int, int) override; void init_style() override; - void *extract(const char *, int &) override { return nullptr; } void coeff(int, char **) override; KOKKOS_INLINE_FUNCTION @@ -93,6 +92,14 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMAlloyKernelAB, const int&) const; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMAlloyKernelAB, const typename Kokkos::TeamPolicy::member_type&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMAlloyKernelAB, const typename Kokkos::TeamPolicy::member_type&) const; + template KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMAlloyKernelC, const int&, EV_FLOAT&) const; @@ -101,6 +108,14 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMAlloyKernelC, const int&) const; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMAlloyKernelC, const typename Kokkos::TeamPolicy::member_type&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMAlloyKernelC, const typename Kokkos::TeamPolicy::member_type&) const; + template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &ev, const int &i, const int &j, @@ -125,7 +140,7 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; - int need_dup; + int need_dup,inum; using KKDeviceType = typename KKDevice::value; @@ -139,7 +154,6 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { DupScatterView dup_f; DupScatterView dup_eatom; DupScatterView dup_vatom; - NonDupScatterView ndup_rho; NonDupScatterView ndup_f; NonDupScatterView ndup_eatom; @@ -163,17 +177,18 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { t_ffloat_2d_n7 d_frho_spline; t_ffloat_2d_n7 d_rhor_spline; t_ffloat_2d_n7 d_z2r_spline; - + void interpolate(int, double, double *, t_host_ffloat_2d_n7, int); void file2array() override; void file2array_alloy(); void array2spline() override; - void interpolate(int, double, double *, t_host_ffloat_2d_n7, int); void read_file(char *) override; + template + auto policyInstance(int inum); + typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d d_ilist; typename AT::t_int_1d d_numneigh; - //NeighListKokkos k_list; int iswap; int first; @@ -187,7 +202,6 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { }; } - #endif #endif diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index 811b80e3a0..4a1258f18c 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -32,10 +32,10 @@ #include "potential_file_reader.h" #include -#include - using namespace LAMMPS_NS; +#define MAX_CACHE_ROWS 500 + // Cannot use virtual inheritance on the GPU, so must duplicate code /* ---------------------------------------------------------------------- */ @@ -46,6 +46,7 @@ PairEAMFSKokkos::PairEAMFSKokkos(LAMMPS *lmp) : PairEAM(lmp) respa_enable = 0; single_enable = 0; one_coeff = 1; + manybody_flag = 1; kokkosable = 1; atomKK = (AtomKokkos *) atom; @@ -59,10 +60,10 @@ PairEAMFSKokkos::PairEAMFSKokkos(LAMMPS *lmp) : PairEAM(lmp) template PairEAMFSKokkos::~PairEAMFSKokkos() { - if (!copymode) { - memoryKK->destroy_kokkos(k_eatom,eatom); - memoryKK->destroy_kokkos(k_vatom,vatom); - } + if (copymode) return; + + memoryKK->destroy_kokkos(k_eatom,eatom); + memoryKK->destroy_kokkos(k_vatom,vatom); } /* ---------------------------------------------------------------------- */ @@ -118,7 +119,7 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) d_numneigh = k_list->d_numneigh; d_neighbors = k_list->d_neighbors; d_ilist = k_list->d_ilist; - int inum = list->inum; + inum = list->inum; need_dup = lmp->kokkos->need_dup(); if (need_dup) { @@ -138,9 +139,9 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) // zero out density if (newton_pair) - Kokkos::parallel_for(Kokkos::RangePolicy(0,nall),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,nall),*this); else - Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,nlocal),*this); // loop over neighbors of my atoms @@ -152,15 +153,15 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } } @@ -178,18 +179,22 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) // compute kernel B if (eflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else if (neighflag == FULL) { // compute kernel AB if (eflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } if (eflag) { @@ -197,7 +202,7 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) ev.evdwl = 0.0; } - // communicate derivative of embedding function (on the device) + // communicate derivative of embedding function k_fp.template modify(); comm->forward_comm(this); @@ -208,41 +213,65 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) if (evflag) { if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } } else if (neighflag == FULL) { if (newton_pair) { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0,inum), + *this,ev); } } } else { if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } else if (neighflag == FULL) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for( + policyInstance>(inum), + *this); } } } @@ -427,7 +456,7 @@ int PairEAMFSKokkos::pack_forward_comm_kokkos(int n, DAT::tdual_int_ d_sendlist = k_sendlist.view(); iswap = iswap_in; v_buf = buf.view(); - Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); return n; } @@ -445,7 +474,7 @@ void PairEAMFSKokkos::unpack_forward_comm_kokkos(int n, int first_in { first = first_in; v_buf = buf.view(); - Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); + Kokkos::parallel_for(Kokkos::RangePolicy(0,n),*this); } template @@ -645,6 +674,7 @@ void PairEAMFSKokkos::operator()(TagPairEAMFSKernelAB, const for (int jj = 0; jj < jnum; jj++) { int j = d_neighbors(i,jj); j &= NEIGHMASK; + const X_FLOAT delx = xtmp - x(j,0); const X_FLOAT dely = ytmp - x(j,1); const X_FLOAT delz = ztmp - x(j,2); @@ -691,7 +721,7 @@ template template KOKKOS_INLINE_FUNCTION void PairEAMFSKokkos::operator()(TagPairEAMFSKernelAB, const int &ii) const { - EV_FLOAT ev; + EV_FLOAT ev; this->template operator()(TagPairEAMFSKernelAB(), ii, ev); this->template operator()(TagPairEAMFSKernelAB(), ii, ev); } @@ -807,6 +837,235 @@ void PairEAMFSKokkos::operator()(TagPairEAMFSKernelC +template +KOKKOS_INLINE_FUNCTION +void PairEAMFSKokkos::operator()(TagPairEAMFSKernelAB, + const typename Kokkos::TeamPolicy::member_type& team_member, + EV_FLOAT& ev) const { + int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); + // rho = density at each atom + // loop over neighbors of my atoms + const int m_max = d_rhor_spline.extent_int(1); + const int j_max = t_ffloat_2d_n7::static_extent(2); + const int d_rhor_spline_cached = (m_max > MAX_CACHE_ROWS) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + + if (d_rhor_spline_cached) { + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { + int j = i%j_max; + int m = i/j_max; + A(m,j) = d_rhor_spline(0,m,j); + } + team_member.team_barrier(); + } + if (ii < inum) { + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + + const int jnum = d_numneigh[i]; + + F_FLOAT rhotmp = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const int jtype = type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + F_FLOAT p = sqrt(rsq)*rdr + 1.0; + int m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + if (d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { + rhotmp += ((A(m,3)*p + A(m,4))*p + + A(m,5))*p + A(m,6); + } else + rhotmp += ((d_rhor_spline(d_type2rhor_ji,m,3)*p + d_rhor_spline(d_type2rhor_ji,m,4))*p + + d_rhor_spline(d_type2rhor_ji,m,5))*p + d_rhor_spline(d_type2rhor_ji,m,6); + } + + } + d_rho[i] += rhotmp; + + // fp = derivative of embedding energy at each atom + // phi = embedding energy at each atom + // if rho > rhomax (e.g. due to close approach of two atoms), + // will exceed table, so add linear term to conserve energy + + F_FLOAT p = d_rho[i]*rdrho + 1.0; + int m = static_cast (p); + m = MAX(1,MIN(m,nrho-1)); + p -= m; + p = MIN(p,1.0); + const int d_type2frho_i = d_type2frho[itype]; + d_fp[i] = (d_frho_spline(d_type2frho_i,m,0)*p + d_frho_spline(d_type2frho_i,m,1))*p + d_frho_spline(d_type2frho_i,m,2); + if (EFLAG) { + F_FLOAT phi = ((d_frho_spline(d_type2frho_i,m,3)*p + d_frho_spline(d_type2frho_i,m,4))*p + + d_frho_spline(d_type2frho_i,m,5))*p + d_frho_spline(d_type2frho_i,m,6); + if (d_rho[i] > rhomax) phi += d_fp[i] * (d_rho[i]-rhomax); + if (eflag_global) ev.evdwl += phi; + if (eflag_atom) d_eatom[i] += phi; + } + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMFSKokkos::operator()(TagPairEAMFSKernelAB, + const typename Kokkos::TeamPolicy::member_type& team_member) const { + EV_FLOAT ev; + this->template operator()(TagPairEAMFSKernelAB(), team_member, ev); +} + +/* ---------------------------------------------------------------------- */ + +////Specialisation for Neighborlist types Half, HalfThread, Full +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMFSKokkos::operator()(TagPairEAMFSKernelC, + const typename Kokkos::TeamPolicy::member_type& team_member, + EV_FLOAT& ev) const { + + int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); + + // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + + auto v_f = ScatterViewHelper,decltype(dup_f),decltype(ndup_f)>::get(dup_f,ndup_f); + auto a_f = v_f.template access>(); + + const int m_max = d_z2r_spline.extent_int(1); + const int j_max = t_ffloat_2d_n7::static_extent(2); + const int d_z2r_spline_cached = (m_max > MAX_CACHE_ROWS) ? 0 : 1; + Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + + if (d_z2r_spline_cached) { + for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { + int j = i%j_max; + int m = i/j_max; + A(m,j) = d_z2r_spline(0,m,j); + } + team_member.team_barrier(); + } + if (ii < inum) { + const int i = d_ilist[ii]; + const X_FLOAT xtmp = x(i,0); + const X_FLOAT ytmp = x(i,1); + const X_FLOAT ztmp = x(i,2); + const int itype = type(i); + + const int jnum = d_numneigh[i]; + + F_FLOAT fxtmp = 0.0; + F_FLOAT fytmp = 0.0; + F_FLOAT fztmp = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i,jj); + j &= NEIGHMASK; + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const int jtype = type(j); + const F_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq < cutforcesq) { + const F_FLOAT r = sqrt(rsq); + F_FLOAT p = r*rdr + 1.0; + int m = static_cast (p); + m = MIN(m,nr-1); + p -= m; + p = MIN(p,1.0); + + // rhoip = derivative of (density at atom j due to atom i) + // rhojp = derivative of (density at atom i due to atom j) + // phi = pair potential energy + // phip = phi' + // z2 = phi * r + // z2p = (phi * r)' = (phi' r) + phi + // psip needs both fp[i] and fp[j] terms since r_ij appears in two + // terms of embed eng: Fi(sum rho_ij) and Fj(sum rho_ji) + // hence embed' = Fi(sum rho_ij) rhojp + Fj(sum rho_ji) rhoip + + const int d_type2rhor_ij = d_type2rhor(itype,jtype); + const F_FLOAT rhoip = (d_rhor_spline(d_type2rhor_ij,m,0)*p + d_rhor_spline(d_type2rhor_ij,m,1))*p + + d_rhor_spline(d_type2rhor_ij,m,2); + const int d_type2rhor_ji = d_type2rhor(jtype,itype); + const F_FLOAT rhojp = (d_rhor_spline(d_type2rhor_ji,m,0)*p + d_rhor_spline(d_type2rhor_ji,m,1))*p + + d_rhor_spline(d_type2rhor_ji,m,2); + const int d_type2z2r_ij = d_type2z2r(itype,jtype); + + const auto have_cache = (d_z2r_spline_cached == 1) && (0 == d_type2z2r_ij); + const auto z2r_spline_3 = (have_cache) ? A(m,3) : d_z2r_spline(d_type2z2r_ij,m,3); + const auto z2r_spline_4 = (have_cache) ? A(m,4) : d_z2r_spline(d_type2z2r_ij,m,4); + const auto z2r_spline_5 = (have_cache) ? A(m,5) : d_z2r_spline(d_type2z2r_ij,m,5); + const auto z2r_spline_6 = (have_cache) ? A(m,6) : d_z2r_spline(d_type2z2r_ij,m,6); + + const F_FLOAT z2p = (3.0*rdr*z2r_spline_3*p + 2.0*rdr*z2r_spline_4)*p + + rdr*z2r_spline_5; // the rdr and the factors of 3.0 and 2.0 come out of the interpolate function + const F_FLOAT z2 = ((z2r_spline_3*p + z2r_spline_4)*p + + z2r_spline_5)*p + z2r_spline_6; + + const F_FLOAT recip = 1.0/r; + const F_FLOAT phi = z2*recip; + const F_FLOAT phip = z2p*recip - phi*recip; + const F_FLOAT psip = d_fp[i]*rhojp + d_fp[j]*rhoip + phip; + const F_FLOAT fpair = -psip*recip; + + fxtmp += delx*fpair; + fytmp += dely*fpair; + fztmp += delz*fpair; + + if ((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD) && (NEWTON_PAIR || j < nlocal)) { + a_f(j,0) -= delx*fpair; + a_f(j,1) -= dely*fpair; + a_f(j,2) -= delz*fpair; + } + + if (EVFLAG) { + if (eflag) { + ev.evdwl += (((NEIGHFLAG==HALF || NEIGHFLAG==HALFTHREAD)&&(NEWTON_PAIR||(jtemplate ev_tally(ev,i,j,phi,fpair,delx,dely,delz); + } + + } + } + + a_f(i,0) += fxtmp; + a_f(i,1) += fytmp; + a_f(i,2) += fztmp; + } +} + +template +template +KOKKOS_INLINE_FUNCTION +void PairEAMFSKokkos::operator()(TagPairEAMFSKernelC, + /*const int &ii*/ + const typename Kokkos::TeamPolicy::member_type& team_member) const { + EV_FLOAT ev; + this->template operator()(TagPairEAMFSKernelC(), team_member, ev); +} + +/* ---------------------------------------------------------------------- */ + template template KOKKOS_INLINE_FUNCTION @@ -1230,6 +1489,30 @@ void PairEAMFSKokkos::file2array_fs() /* ---------------------------------------------------------------------- */ +template +template +auto PairEAMFSKokkos::policyInstance(int inum) { + #ifdef KOKKOS_ENABLE_HIP + if (execution_space != Host) { + static_assert(t_ffloat_2d_n7::static_extent(2) == 7, + "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); + + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) + .set_scratch_size(0, + Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); + return policy; + } else { + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + } + #else + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + #endif +} + +/* ---------------------------------------------------------------------- */ + namespace LAMMPS_NS { template class PairEAMFSKokkos; #ifdef LMP_KOKKOS_GPU diff --git a/src/KOKKOS/pair_eam_fs_kokkos.h b/src/KOKKOS/pair_eam_fs_kokkos.h index 06a395cba7..f7513b3008 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.h +++ b/src/KOKKOS/pair_eam_fs_kokkos.h @@ -61,7 +61,6 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { ~PairEAMFSKokkos() override; void compute(int, int) override; void init_style() override; - void *extract(const char *, int &) override { return nullptr; } void coeff(int, char **) override; KOKKOS_INLINE_FUNCTION @@ -93,6 +92,14 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMFSKernelAB, const int&) const; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMFSKernelAB, const typename Kokkos::TeamPolicy::member_type&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMFSKernelAB, const typename Kokkos::TeamPolicy::member_type&) const; + template KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMFSKernelC, const int&, EV_FLOAT&) const; @@ -101,6 +108,14 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMFSKernelC, const int&) const; + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMFSKernelC, const typename Kokkos::TeamPolicy::member_type&, EV_FLOAT&) const; + + template + KOKKOS_INLINE_FUNCTION + void operator()(TagPairEAMFSKernelC, const typename Kokkos::TeamPolicy::member_type&) const; + template KOKKOS_INLINE_FUNCTION void ev_tally(EV_FLOAT &ev, const int &i, const int &j, @@ -125,7 +140,7 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; - int need_dup; + int need_dup,inum; using KKDeviceType = typename KKDevice::value; @@ -139,7 +154,6 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { DupScatterView dup_f; DupScatterView dup_eatom; DupScatterView dup_vatom; - NonDupScatterView ndup_rho; NonDupScatterView ndup_f; NonDupScatterView ndup_eatom; @@ -163,13 +177,15 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { t_ffloat_2d_n7 d_frho_spline; t_ffloat_2d_n7 d_rhor_spline; t_ffloat_2d_n7 d_z2r_spline; - + void interpolate(int, double, double *, t_host_ffloat_2d_n7, int); void file2array() override; void file2array_fs(); void array2spline() override; - void interpolate(int, double, double *, t_host_ffloat_2d_n7, int); void read_file(char *) override; + template + auto policyInstance(int inum); + typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d d_ilist; typename AT::t_int_1d d_numneigh; @@ -186,7 +202,6 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { }; } - #endif #endif diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 2317f2d367..5e2ea4357f 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -148,15 +148,15 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else { - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } } @@ -174,9 +174,9 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) // compute kernel B if (eflag) - Kokkos::parallel_reduce(Kokkos::RangePolicy >(0,inum),*this,ev); + Kokkos::parallel_reduce(Kokkos::RangePolicy>(0,inum),*this,ev); else - Kokkos::parallel_for(Kokkos::RangePolicy >(0,inum),*this); + Kokkos::parallel_for(Kokkos::RangePolicy>(0,inum),*this); } else if (neighflag == FULL) { @@ -184,12 +184,12 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (eflag) Kokkos::parallel_reduce( - Kokkos::RangePolicy>(0,inum), - *this,ev); + Kokkos::RangePolicy>(0,inum), + *this,ev); else Kokkos::parallel_for( - policyInstance>(inum), - *this); + policyInstance>(inum), + *this); } if (eflag) { @@ -209,64 +209,64 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_reduce( - Kokkos::RangePolicy>(0,inum), - *this,ev); + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { Kokkos::parallel_reduce( - Kokkos::RangePolicy>(0,inum), - *this,ev); + Kokkos::RangePolicy>(0,inum), + *this,ev); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_reduce( - Kokkos::RangePolicy>(0,inum), - *this,ev); + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { Kokkos::parallel_reduce( Kokkos::RangePolicy>(0,inum), - *this,ev); + *this,ev); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_reduce( - Kokkos::RangePolicy>(0,inum), - *this,ev); + Kokkos::RangePolicy>(0,inum), + *this,ev); } else { Kokkos::parallel_reduce( - Kokkos::RangePolicy>(0,inum), - *this,ev); + Kokkos::RangePolicy>(0,inum), + *this,ev); } } } else { if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), - *this); + policyInstance>(inum), + *this); } else { Kokkos::parallel_for( - policyInstance>(inum), - *this); + policyInstance>(inum), + *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), - *this); + policyInstance>(inum), + *this); } else { Kokkos::parallel_for( - policyInstance>(inum), - *this); + policyInstance>(inum), + *this); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), - *this); + policyInstance>(inum), + *this); } else { Kokkos::parallel_for( - policyInstance>(inum), - *this); + policyInstance>(inum), + *this); } } } @@ -612,6 +612,7 @@ template template KOKKOS_INLINE_FUNCTION void PairEAMKokkos::operator()(TagPairEAMKernelB, const int &ii, EV_FLOAT& ev) const { + // fp = derivative of embedding energy at each atom // phi = embedding energy at each atom // if rho > rhomax (e.g. due to close approach of two atoms), @@ -643,7 +644,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelB, const int & EV_FLOAT ev; this->template operator()(TagPairEAMKernelB(), ii, ev); } -/* ---------------------------------------------------------------------- */ + /* ---------------------------------------------------------------------- */ ////Specialisation for Neighborlist types Half, HalfThread, Full @@ -828,6 +829,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelCtemplate operator()(TagPairEAMKernelC(), ii, ev); } + /* ---------------------------------------------------------------------- */ ////Specialisation for Neighborlist types Half, HalfThread, Full @@ -835,8 +837,8 @@ template template KOKKOS_INLINE_FUNCTION void PairEAMKokkos::operator()(TagPairEAMKernelAB, - const typename Kokkos::TeamPolicy::member_type& team_member, - EV_FLOAT& ev) const { + const typename Kokkos::TeamPolicy::member_type& team_member, + EV_FLOAT& ev) const { int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); // rho = density at each atom // loop over neighbors of my atoms @@ -844,7 +846,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, const int j_max = t_ffloat_2d_n7::static_extent(2); const int d_rhor_spline_cached = (m_max > MAX_CACHE_ROWS) ? 0 : 1; Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + Kokkos::MemoryTraits> A(team_member.team_scratch(0), MAX_CACHE_ROWS); if (d_rhor_spline_cached) { for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { @@ -884,7 +886,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelAB, const int d_type2rhor_ji = d_type2rhor(jtype,itype); if (d_type2rhor_ji == 0 && d_rhor_spline_cached == 1) { rhotmp += ((A(m,3)*p + A(m,4))*p + - A(m,5))*p + A(m,6); + A(m,5))*p + A(m,6); } else rhotmp += ((d_rhor_spline(d_type2rhor_ji,m,3)*p + d_rhor_spline(d_type2rhor_ji,m,4))*p + d_rhor_spline(d_type2rhor_ji,m,5))*p + d_rhor_spline(d_type2rhor_ji,m,6); @@ -919,7 +921,7 @@ template template KOKKOS_INLINE_FUNCTION void PairEAMKokkos::operator()(TagPairEAMKernelAB, - const typename Kokkos::TeamPolicy::member_type& team_member) const { + const typename Kokkos::TeamPolicy::member_type& team_member) const { EV_FLOAT ev; this->template operator()(TagPairEAMKernelAB(), team_member, ev); } @@ -931,7 +933,7 @@ template template KOKKOS_INLINE_FUNCTION void PairEAMKokkos::operator()(TagPairEAMKernelC, - const typename Kokkos::TeamPolicy::member_type& team_member, + const typename Kokkos::TeamPolicy::member_type& team_member, EV_FLOAT& ev) const { int ii = team_member.league_rank()*team_member.team_size() + team_member.team_rank(); @@ -945,7 +947,7 @@ void PairEAMKokkos::operator()(TagPairEAMKernelC MAX_CACHE_ROWS) ? 0 : 1; Kokkos::View> A(team_member.team_scratch(0), MAX_CACHE_ROWS); + Kokkos::MemoryTraits> A(team_member.team_scratch(0), MAX_CACHE_ROWS); if (d_z2r_spline_cached) { for(int i = team_member.team_rank(); i < m_max*j_max; i+= team_member.team_size()) { @@ -1051,8 +1053,8 @@ template template KOKKOS_INLINE_FUNCTION void PairEAMKokkos::operator()(TagPairEAMKernelC, - /*const int &ii*/ - const typename Kokkos::TeamPolicy::member_type& team_member) const { + /*const int &ii*/ + const typename Kokkos::TeamPolicy::member_type& team_member) const { EV_FLOAT ev; this->template operator()(TagPairEAMKernelC(), team_member, ev); } @@ -1163,11 +1165,11 @@ auto PairEAMKokkos::policyInstance(int inum) { #ifdef KOKKOS_ENABLE_HIP if (execution_space != Host) { static_assert(t_ffloat_2d_n7::static_extent(2) == 7, - "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); + "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) - .set_scratch_size(0, - Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); + .set_scratch_size(0, + Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); return policy; } else { auto policy = Kokkos::RangePolicy(0,inum); diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index 7f4ec67f6f..41e02e68cc 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -138,9 +138,8 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { typename AT::t_efloat_1d d_eatom; typename AT::t_virial_array d_vatom; - int need_dup; - int inum; - + int need_dup,inum; + using KKDeviceType = typename KKDevice::value; template From 4d78d987c6d512b6d379b70ce9ef9c386f41b418 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 24 Feb 2023 07:34:58 -0500 Subject: [PATCH 007/448] add unmap_inv function --- src/domain.cpp | 23 +++++++++++++++++++++++ src/domain.h | 1 + 2 files changed, 24 insertions(+) diff --git a/src/domain.cpp b/src/domain.cpp index e1a508ac51..dcad723b9f 100644 --- a/src/domain.cpp +++ b/src/domain.cpp @@ -1500,6 +1500,29 @@ void Domain::remap_near(double *xnew, double *xold) if (triclinic) lamda2x(coordnew,xnew); } +/* ---------------------------------------------------------------------- + remap the point to specific image flags + x overwritten with result, reset image flag + for triclinic, use h[] to add in tilt factors in other dims as needed +------------------------------------------------------------------------- */ + +void Domain::unmap_inv(double *x, imageint image) +{ + int xbox = (image & IMGMASK) - IMGMAX; + int ybox = (image >> IMGBITS & IMGMASK) - IMGMAX; + int zbox = (image >> IMG2BITS) - IMGMAX; + + if (triclinic == 0) { + x[0] -= xbox*xprd; + x[1] -= ybox*yprd; + x[2] -= zbox*zprd; + } else { + x[0] -= h[0]*xbox + h[5]*ybox + h[4]*zbox; + x[1] -= h[1]*ybox + h[3]*zbox; + x[2] -= h[2]*zbox; + } +} + /* ---------------------------------------------------------------------- unmap the point via image flags x overwritten with result, don't reset image flag diff --git a/src/domain.h b/src/domain.h index 1e9e9caae1..738dc8a2a3 100644 --- a/src/domain.h +++ b/src/domain.h @@ -126,6 +126,7 @@ class Domain : protected Pointers { void remap(double *, imageint &); void remap(double *); void remap_near(double *, double *); + void unmap_inv(double *x, imageint); void unmap(double *, imageint); void unmap(const double *, imageint, double *); void image_flip(int, int, int); From b0b14bd1d166c78d7357e76a733c56ca8d73970d Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 24 Feb 2023 07:48:34 -0500 Subject: [PATCH 008/448] add fix pimd/langevin --- src/REPLICA/fix_pimd_langevin.cpp | 1751 +++++++++++++++++++++++++++++ src/REPLICA/fix_pimd_langevin.h | 198 ++++ 2 files changed, 1949 insertions(+) create mode 100644 src/REPLICA/fix_pimd_langevin.cpp create mode 100644 src/REPLICA/fix_pimd_langevin.h diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp new file mode 100644 index 0000000000..9ac8fc3b17 --- /dev/null +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -0,0 +1,1751 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Package FixPIMDLangevin + Purpose Quantum Path Integral Algorithm for Quantum Chemistry + Copyright Voth Group @ University of Chicago + Authors Chris Knight & Yuxing Peng (yuxing at uchicago.edu) + + Updated Oct-01-2011 + Version 1.0 + + Updated Jun-07-2022 + Yifan Li @ Princeton University (yifanl0716@gmail.com) + Added components: + - Multi-processor parallelism for each bead + - White-noise Langevin thermostat + - Bussi-Zykova-Parrinello barostat (isotropic and anisotropic) + - Several quantum estimators + Futher plans: + - Triclinic barostat +------------------------------------------------------------------------- */ + +#include "fix_pimd_langevin.h" + +#include "atom.h" +#include "comm.h" +#include "compute.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "math_const.h" +#include "memory.h" +#include "modify.h" +#include "random_mars.h" +#include "universe.h" +#include "utils.h" +#include "update.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace FixConst; +using namespace MathConst; + +enum { PIMD, NMPIMD, CMD }; +enum { physical, normal }; +enum { baoab, obabo }; +enum { ISO, ANISO, TRICLINIC }; +enum { PILE_L }; +enum { MTTK, BZP }; +// char* Barostats[] = {"MTTK", "BZP"}; +std::map Barostats {{MTTK, "MTTK"}, {BZP, "BZP"}}; +enum { nve, nvt, nph, npt }; +enum{SINGLE_PROC, MULTI_PROC}; + +/* ---------------------------------------------------------------------- */ + +FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) { + time_integrate = 1; + tagsend = tagrecv = nullptr; + bufsend = bufrecv = nullptr; + bufsendall = bufrecvall = nullptr; + bufsorted = bufsortedall = nullptr; + outsorted = buftransall = nullptr; + + ntotal = 0; + maxlocal = maxunwrap = maxxc = 0; + bufbeads = nullptr; + x_unwrap = xc = nullptr; + xcall = nullptr; + // x_unwrap = x_unwrapsort = x_unwrapall = nullptr; + // tag_init = tag_initall = nullptr; + counts = nullptr; + + sizeplan = 0; + plansend = planrecv = nullptr; + + M_x2xp = M_xp2x = M_f2fp = M_fp2f = nullptr; + lam = nullptr; + modeindex = nullptr; + + mass = nullptr; + + method = PIMD; + ensemble = nvt; + integrator = obabo; + thermostat = PILE_L; + barostat = BZP; + fmass = 1.0; + sp = 1.0; + temp = 298.15; + Lan_temp = 298.15; + tau = 1.0; + tau_p = 1.0; + Pext = 1.0; + tstat_flag = 1; + pstat_flag = 0; + mapflag = 1; + removecomflag = 1; + fmmode = physical; + pstyle = ISO; + for (int i=0; i<6; i++) p_flag[i] = 0; + + for (int i = 3; i < narg - 1; i += 2) { + if (strcmp(arg[i], "method") == 0) { + if (strcmp(arg[i + 1], "pimd") == 0) + method = PIMD; + else if (strcmp(arg[i + 1], "nmpimd") == 0) + method = NMPIMD; + else if (strcmp(arg[i + 1], "cmd") == 0) + method = CMD; + else + error->universe_all(FLERR, "Unknown method parameter for fix pimd"); + } + else if(strcmp(arg[i], "integrator")==0) + + { + if(strcmp(arg[i+1], "obabo")==0) integrator=obabo; + else if(strcmp(arg[i+1], "baoab")==0) integrator=baoab; + else error->universe_all(FLERR, "Unknown integrator parameter for fix pimd. Only obabo and baoab integrators are supported!"); + } + + else if(strcmp(arg[i], "ensemble")==0) + { + if(strcmp(arg[i+1], "nve")==0) { ensemble = nve; tstat_flag = 0; pstat_flag = 0; } + else if(strcmp(arg[i+1], "nvt")==0) { ensemble = nvt; tstat_flag = 1; pstat_flag = 0; } + else if(strcmp(arg[i+1], "nph")==0) { ensemble = nph; tstat_flag = 0; pstat_flag = 1; } + else if(strcmp(arg[i+1], "npt")==0) { ensemble = npt; tstat_flag = 1; pstat_flag = 1; } + else error->universe_all(FLERR, "Unknown ensemble parameter for fix pimd. Only nve and nvt ensembles are supported!"); + } + + else if (strcmp(arg[i], "fmass") == 0) { + fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); + if (fmass < 0.0 || fmass > 1.0) + error->universe_all(FLERR, "Invalid fmass value for fix pimd"); + } + + else if(strcmp(arg[i], "fmmode")==0) + { + if(strcmp(arg[i+1], "physical")==0) fmmode=physical; + else if(strcmp(arg[i+1], "normal")==0) fmmode=normal; + else error->universe_all(FLERR, "Unknown fictitious mass mode for fix pimd. Only physical mass and normal mode mass are supported!"); + } + + else if(strcmp(arg[i],"scale")==0) + { + pilescale = atof(arg[i+1]); + if(pilescale<0.0) error->universe_all(FLERR,"Invalid pile scale value for fix pimd"); + } + + else if (strcmp(arg[i], "temp") == 0) { + temp = utils::numeric(FLERR, arg[i + 1], false, lmp); + if (temp < 0.0) error->universe_all(FLERR, "Invalid temp value for fix pimd"); + } + + else if (strcmp(arg[i], "lj") == 0) { + lj_epsilon = utils::numeric(FLERR, arg[i+1], false, lmp); + lj_sigma = utils::numeric(FLERR, arg[i+2], false, lmp); + lj_mass = utils::numeric(FLERR, arg[i+3], false, lmp); + other_planck = utils::numeric(FLERR, arg[i+4], false, lmp); + i++; + i++; + i++; + } + + else if(strcmp(arg[i], "thermostat")==0) + { + if(strcmp(arg[i+1],"PILE_L")==0) + { + thermostat = PILE_L; + seed = atoi(arg[i+2]); + i++; + } + } + + else if(strcmp(arg[i], "tau")==0) + { + tau = atof(arg[i+1]); + } + + else if(strcmp(arg[i], "press")==0) + { + Pext = atof(arg[i+1]); + if(Pext<0.0) error->universe_all(FLERR,"Invalid press value for fix pimd"); + } + + else if(strcmp(arg[i], "barostat")==0) + { + if(strcmp(arg[i+1],"MTTK")==0) + { + barostat = MTTK; + } + else if(strcmp(arg[i+1],"BZP")==0) + { + barostat = BZP; + } + else error->universe_all(FLERR,"Unknown barostat parameter for fix pimd"); + } + + else if(strcmp(arg[i], "iso")==0) + { + pstyle = ISO; + i--; + } + + else if(strcmp(arg[i], "aniso")==0) + { + pstyle = ANISO; + i--; + } + + else if(strcmp(arg[i], "taup")==0) + { + tau_p = atof(arg[i+1]); + if(tau_p<=0.0) error->universe_all(FLERR, "Invalid tau_p value for fix pimd"); + } + else if(strcmp(arg[i], "fixcom")==0) + { + if(strcmp(arg[i+1], "yes")==0) removecomflag = 1; + else if(strcmp(arg[i+1], "no")==0) removecomflag = 0; + } + + else if(strcmp(arg[i], "map")==0) + { + if(strcmp(arg[i+1], "yes")==0) mapflag = 1; + else if(strcmp(arg[i+1], "no")==0) mapflag = 0; + } + + else error->universe_all(FLERR, fmt::format("Unknown keyword {} for fix pimd", arg[i])); + } + + /* Initiation */ + + int nlocal = atom->nlocal; + // xc = new double[nlocal*3]; + // x_unwrap = new double[nlocal*3]; + + global_freq = 1; + vector_flag = 1; + size_vector = 11; + // if(pstyle==ISO) {size_vector = 15;} + // else if(pstyle==ANISO) {size_vector = 23;} + extvector = 1; + // comm_forward = 1; + + // some initilizations + + id_pe = new char[8]; + strcpy(id_pe, "pimd_pe"); + char **newarg = new char*[3]; + newarg[0] = id_pe; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "pe"; + modify->add_compute(3,newarg); + delete [] newarg; + + + id_press = new char[12]; + strcpy(id_press, "pimd_press"); + newarg = new char*[5]; + newarg[0] = id_press; + newarg[1] = (char*) "all"; + newarg[2] = (char*) "pressure"; + newarg[3] = (char*) "thermo_temp"; + newarg[4] = (char*) "virial"; + modify->add_compute(5, newarg); + delete [] newarg; + + vol0 = domain->xprd * domain->yprd * domain->zprd; + + fixedpoint[0] = 0.5*(domain->boxlo[0]+domain->boxhi[0]); + fixedpoint[1] = 0.5*(domain->boxlo[1]+domain->boxhi[1]); + fixedpoint[2] = 0.5*(domain->boxlo[2]+domain->boxhi[2]); + + // initialize Marsaglia RNG with processor-unique seed + + if(integrator==baoab || integrator==obabo) + { + Lan_temp = temp; + random = new RanMars(lmp, seed + universe->me); + } + + me = comm->me; + nprocs = comm->nprocs; + if(nprocs == 1) cmode = SINGLE_PROC; + else cmode = MULTI_PROC; + + nprocs_universe = universe->nprocs; + nreplica = universe->nworlds; + ireplica = universe->iworld; + + int *iroots = new int[nreplica]; + MPI_Group uworldgroup,rootgroup; + + for (int i=0; iroot_proc[i]; + MPI_Comm_group(universe->uworld, &uworldgroup); + MPI_Group_incl(uworldgroup, nreplica, iroots, &rootgroup); + MPI_Comm_create(universe->uworld, rootgroup, &rootworld); + if (rootgroup != MPI_GROUP_NULL) MPI_Group_free(&rootgroup); + if (uworldgroup != MPI_GROUP_NULL) MPI_Group_free(&uworldgroup); + delete [] iroots; + + ntotal = atom->natoms; + if(atom->nmax > maxlocal) reallocate(); + if(atom->nmax > maxunwrap) reallocate_x_unwrap(); + if(atom->nmax > maxxc) reallocate_xc(); + memory->create(xcall, ntotal*3, "FixPIMDLangevin:xcall"); + // init_x_unwrap(); + + if (cmode == SINGLE_PROC) + { + memory->create(bufsorted, ntotal, 3, "FixPIMDLangevin:bufsorted"); + memory->create(outsorted, ntotal, 3, "FixPIMDLangevin:outsorted"); + memory->create(bufsortedall, nreplica*ntotal, 3, "FixPIMDLangevin:bufsortedall"); + memory->create(buftransall, nreplica*ntotal, 3, "FixPIMDLangevin:buftransall"); + memory->create(counts, nreplica, "FixPIMDLangevin:counts"); + memory->create(displacements, nreplica, "FixPIMDLangevin:displacements"); + } + + if ((cmode == MULTI_PROC) && (counts == nullptr)) { + // printf("me = %d, creating bufrecvall\n", universe->me); + memory->create(bufsendall,ntotal,3,"FixPIMDLangevin:bufsendall"); + memory->create(bufrecvall,ntotal,3,"FixPIMDLangevin:bufrecvall"); + // printf("me = %d, bufrecvall[0][0] = %.4f\n", universe->me, bufrecvall[0][0]); + memory->create(tagsendall,ntotal,"FixPIMDLangevin:tagsendall"); + memory->create(tagrecvall,ntotal,"FixPIMDLangevin:tagrecvall"); + // printf("me = %d, tagrecvall[0] = %d\n", universe->me, tagrecvall[0]); + memory->create(counts,nprocs,"FixPIMDLangevin:counts"); + memory->create(displacements,nprocs,"FixPIMDLangevin:displacements"); + // memory->create(x_unwrapall, ntotal, 3, "FixPIMDLangevin:x_unwrapall"); + // memory->create(tag_initall, ntotal, "FixPIMDLangevin:tag_initall"); + // printf("me = %d, tag_initall[0] = %d\n", universe->me, tag_initall[0]); + } + + // printf("me = %d constructing finished\n", universe->me); +} + +/* ---------------------------------------------------------------------- */ + +FixPIMDLangevin::~FixPIMDLangevin() +{ + +} + +/* ---------------------------------------------------------------------- */ + +int FixPIMDLangevin::setmask() +{ + int mask = 0; + mask |= POST_FORCE; + mask |= INITIAL_INTEGRATE; + // mask |= POST_NEIGHBOR; + mask |= FINAL_INTEGRATE; + mask |= END_OF_STEP; + return mask; +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::init() +{ + if (atom->map_style == Atom::MAP_NONE) + error->all(FLERR, "Fix pimd requires an atom map, see atom_modify"); + + if (universe->me == 0 && universe->uscreen) + fprintf(universe->uscreen, "Fix pimd initializing Path-Integral ...\n"); + + // prepare the constants + + masstotal = group->mass(igroup); + np = universe->nworlds; + inverse_np = 1.0 / np; + + const double Boltzmann = force->boltz; + if (strcmp(update->unit_style,"lj") == 0) { + double planck_star = sqrt(lj_epsilon)*sqrt(atom->mass[0])*lj_sigma; + planck = other_planck / planck_star; + } + else planck = force->hplanck; + const double Planck = planck; + printf("planck = %.6e\n", planck); + + // if(force->boltz == 1.0) { hbar = Planck; } + // else { hbar = Planck / (2.0 * MY_PI); } + hbar = Planck / (2.0 * MY_PI); + // hbar = Planck; + kBT = force->boltz * temp; + double beta = 1.0 / (Boltzmann * temp); + double _fbond = 1.0 * np * np / (beta * beta * hbar * hbar); + + omega_np = np / (hbar * beta) * sqrt(force->mvv2e); + beta_np = 1.0 / force->boltz / temp / np; + fbond = _fbond * force->mvv2e; + // printf("_fbond = %.16e\nfbond = %.16e\n", _fbond, fbond); + + if (universe->me == 0) + printf("Fix pimd -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); + + if(integrator==obabo) + { + dtf = 0.5 * update->dt * force->ftm2v; + dtv = 0.5 * update->dt; + dtv2 = dtv * dtv; + dtv3 = 1./3 * dtv2 * dtv * force->ftm2v; + } + else if(integrator==baoab) + { + dtf = 0.5 * update->dt * force->ftm2v; + dtv = 0.5 * update->dt; + dtv2 = dtv * dtv; + dtv3 = 1./3 * dtv2 * dtv * force->ftm2v; + } + else + { + error->universe_all(FLERR,"Unknown integrator parameter for fix pimd"); + } + + comm_init(); + + mass = new double[atom->ntypes + 1]; + + nmpimd_init(); + + Langevin_init(); + if (pstat_flag) baro_init(); + + int ipe = modify->find_compute(id_pe); + c_pe = modify->compute[ipe]; + + int ipress = modify->find_compute(id_press); + c_press = modify->compute[ipress]; + + t_prim = t_vir = t_cv = p_prim = p_vir = p_cv = p_md = 0.0; + + if(universe->me==0) fprintf(screen, "Fix pimd successfully initialized!\n"); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::setup(int vflag) +{ + if(universe->me==0) printf("Setting up Path-Integral ...\n"); + int nlocal = atom->nlocal; + tagint *tag = atom->tag; + double **x = atom->x; + double **v = atom->v; + imageint *image = atom->image; + // nlocal_init = nlocal; + if(mapflag){ + for(int i=0; iunmap(x[i], image[i]); + } + } + // printf("me = %d after unmapping x_unwrap\n", universe->me); + + // printf("setup already here\n"); + if(method==NMPIMD) + { + inter_replica_comm(x); + // printf("me = %d after inter\n", universe->me); + // printf("%.4f %.4f %.4f\n", bufbeads[0][0], bufbeads[0][1], bufbeads[0][2]); + if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); + else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); + } + collect_xc(); + // printf("me = %d setup x2xp done\n", universe->me); + compute_spring_energy(); + if(method==NMPIMD) + { + inter_replica_comm(x); + if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); + else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); + // nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); + } + // printf("me = %d setup xp2x done\n", universe->me); + if(mapflag){ + for(int i=0; iunmap_inv(x[i], image[i]); + } + } + + if(method==NMPIMD) + { + inter_replica_comm(v); + if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, v, M_x2xp[universe->iworld]); + else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, v, M_x2xp[universe->iworld]); + // nmpimd_transform(bufbeads, atom->v, M_x2xp[universe->iworld]); + } + // printf("me = %d setup v2vp done\n", universe->me); + // compute_xc(); + // update_x_unwrap(); + // printf("setting up %d\n", vflag); + if(universe->me==0 && screen) fprintf(screen,"Setting up Path-Integral ...\n"); + if(universe->me==0) printf("Setting up Path-Integral ...\n"); + // printf("setting up, m = %.4e\n", mass[1]); + post_force(vflag); + // int idx = atom->map(1); + // printf("irplica = %d, x[1] = %.6f %.6f %.6f xu[1] = %.6f %.6f %.6f xc[1] = %.6f %.6f %.6f\n", ireplica, x[idx][0], x[idx][1], x[idx][2], x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xc[idx][0], xc[idx][1], xc[idx][2]); + // printf("after post_force, m = %.4e\n", mass[1]); + // printf("me = %d after post_force\n", universe->me); + compute_totke(); + // compute_pote(); + // if(pstyle==ANISO) compute_stress_tensor(); + end_of_step(); + c_pe->addstep(update->ntimestep+1); + c_press->addstep(update->ntimestep+1); + // printf("setup ending: \ncell = %.16e %.16e %.16e\nvol = %.16e\n", domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); + // printf("me = %d, setup finished\n", universe->me); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::initial_integrate(int /*vflag*/) +{ + // printf("step = %d start initial_integrate\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); + // printf("me = %d, step %d initial_integrate starts!\n", universe->me, update->ntimestep); + // printf("me = %d, step %d if starts!\n", universe->me, update->ntimestep); + int nlocal = atom->nlocal; + tagint *tag = atom->tag; + double **x = atom->x; + imageint *image = atom->image; + if(mapflag){ + for(int i=0; iunmap(x[i], image[i]); + } + } + if(integrator==obabo) + { + // printf("me = %d, step %d obabo starts!\n", universe->me, update->ntimestep); + if(tstat_flag) + { + o_step(); + // if(removecomflag) remove_com_motion(); + if(pstat_flag) press_o_step(); + } + if(pstat_flag) + { + compute_totke(); + // printf("me = %d, step %d after totke!\n", universe->me, update->ntimestep); + compute_p_cv(); + press_v_step(); + } + /* + if(pstat_flag) + { + } + */ + // printf("me = %d, step %d before b_step 1!\n", universe->me, update->ntimestep); + b_step(); + // printf("me = %d, step %d after b_step 1!\n", universe->me, update->ntimestep); + // if(removecomflag) remove_com_motion(); + if(method==NMPIMD) + { + inter_replica_comm(x); + if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); + else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); + // nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); + } + qc_step(); + a_step(); + qc_step(); + a_step(); + // printf("me = %d, step %d after 2 a_step's!\n", universe->me, update->ntimestep); + } + else if(integrator==baoab) + { + if(pstat_flag) + { + compute_totke(); + compute_p_cv(); + press_v_step(); + } + b_step(); + // if(removecomflag) remove_com_motion(); + if(method==NMPIMD) + { + inter_replica_comm(x); + if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); + else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); + // nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); + } + qc_step(); + a_step(); + if(tstat_flag) + { + o_step(); + // if(removecomflag) remove_com_motion(); + if(pstat_flag) press_o_step(); + } + qc_step(); + a_step(); + } + else + { + error->universe_all(FLERR,"Unknown integrator parameter for fix pimd"); + } + collect_xc(); + compute_spring_energy(); + + if(method==NMPIMD) + { + inter_replica_comm(x); + if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); + else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); + // nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); + } + + + if(mapflag){ + for(int i=0; iunmap_inv(x[i], image[i]); + } + } + // printf("step = %d\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); + // printf("me = %d, step %d initial_integrate ends!\n", universe->me, update->ntimestep); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::final_integrate() +{ + if(pstat_flag) + { + compute_totke(); + compute_p_cv(); + press_v_step(); + } + b_step(); + // if(removecomflag) remove_com_motion(); + if(integrator==obabo) + { + if(tstat_flag) + { + o_step(); + // if(removecomflag) remove_com_motion(); + if(pstat_flag) press_o_step(); + } + } + else if(integrator==baoab) + { + + } + else + { + error->universe_all(FLERR,"Unknown integrator parameter for fix pimd"); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::post_force(int /*flag*/) +{ + // printf("step = %d\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); + if(atom->nmax > maxunwrap) reallocate_x_unwrap(); + if(atom->nmax > maxxc) reallocate_xc(); + // printf("me = %d, step %d post_force starts!\n", universe->me, update->ntimestep); + int nlocal = atom->nlocal; + double **x = atom->x; + double **f = atom->f; + imageint *image = atom->image; + tagint *tag = atom->tag; + for(int i=0; iunmap(x_unwrap[i], image[i]); + } + } + for(int i=0; imap(1); + // printf("in post_force, x_unwrap: %.6f %.6f %.6f xcall: %.6f %.6f %.6f xc: %.6f %.6f %.6f\n", x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xcall[0], xcall[1], xcall[2], xc[idx][0], xc[idx][1], xc[idx][2]); + // MPI_Barrier(universe->uworld); + // update_x_unwrap(); + // MPI_Barrier(universe->uworld); + // compute_xc(); + // MPI_Barrier(universe->uworld); + // if(mapflag) + // { + // for(int i=0; iunmap_inv(x[i], image[i]); + // } + // } + compute_vir(); + compute_vir_(); + // compute_t_prim(); + // compute_t_vir(); + compute_pote(); + if(method==NMPIMD) + { + inter_replica_comm(f); + if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, f, M_x2xp[universe->iworld]); + else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); + // nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); + } + c_pe->addstep(update->ntimestep+1); + c_press->addstep(update->ntimestep+1); + // printf("me = %d, step %d post_force ends!\n", universe->me, update->ntimestep); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::end_of_step() +{ + compute_totke(); + // inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); + // compute_p_prim(); + compute_p_cv(); + compute_tote(); + if(pstat_flag) compute_totenthalpy(); + + if(update->ntimestep % 10000 == 0) + { + if(universe->me==0) printf("This is the end of step %ld.\n", update->ntimestep); + } + // if(universe->me==0) printf("me = %d This is the end of step %ld.\n", universe->me, update->ntimestep); + // printf("me = %d This is the end of step %ld.\n\n", universe->me, update->ntimestep); +} + +void FixPIMDLangevin::collect_xc() +{ + int nlocal = atom->nlocal; + double **x = atom->x; + tagint *tag = atom->tag; + if(ireplica == 0) + { + if(cmode == SINGLE_PROC) + { + for(int i=0; imap(1); + // printf("in init_int, x: %.6f %.6f %.6f xcall: %.6f %.6f %.6f\n", x[idx][0], x[idx][1], x[idx][2], xcall[0], xcall[1], xcall[2]); + + if(cmode == MULTI_PROC) + { + // printf("trying to add\n"); + // MPI_Reduce(MPI_IN_PLACE, xcall, ntotal*3, MPI_DOUBLE, MPI_SUM, 0, world); + MPI_Allreduce(MPI_IN_PLACE, xcall, ntotal*3, MPI_DOUBLE, MPI_SUM, world); + // printf("added\n"); + } + } + MPI_Bcast(xcall, ntotal*3, MPI_DOUBLE, 0, universe->uworld); +} + +/* ---------------------------------------------------------------------- */ +/* +void FixPIMDLangevin::update_x_unwrap() +{ + // MPI_Barrier(universe->uworld); + // printf("me = %d, starting update_xu\n", universe->me); + int nlocal = atom->nlocal; + double **x = atom->x; + // delete x_unwrap; + // memory->sfree(x_unwrap); + // printf("me = %d, before deleting xu\n", universe->me); + delete [] x_unwrap; + x_unwrap = nullptr; + x_unwrap = (double*) memory->srealloc(x_unwrap, sizeof(double)*(nlocal+200)*3, "FixDPPimd::x_unwrap"); + // printf("me = %d, before newing xu\n", universe->me); + // x_unwrap = new double[nlocal*3]; + // printf("me = %d, doing xu\n", universe->me); + for(int i=0; ime); + // MPI_Barrier(universe->uworld); +} +*/ +/* ---------------------------------------------------------------------- */ +/* +void FixPIMDLangevin::compute_xc() +{ + int natoms = atom->natoms; + MPI_Barrier(universe->uworld); + comm_exec(atom->x); + MPI_Barrier(universe->uworld); + int nlocal = atom->nlocal; + delete [] xc; + xc = nullptr; + xc = (double*) memory->srealloc(xc, sizeof(double) * nlocal * 3, "FixDPPimd:xc"); + for(int i=0; inlocal; + int *type = atom->type; + double **v = atom->v; + double **f = atom->f; + + for(int i=0; inlocal; + double **x = atom->x; + double **v = atom->v; + tagint *tag = atom->tag; + double oldlo, oldhi; + if(!pstat_flag) { + if(universe->iworld == 0) + { + for(int i=0; intimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); + if(universe->iworld == 0) + { + double expp[3], expq[3]; + // printf("pstyle = %d vw[0] = %.8e\n", pstyle, vw[0]); + if(pstyle == ISO) {vw[1] = vw[0]; vw[2] = vw[0];} + for(int j=0; j<3; j++) + { + expq[j] = exp(dtv * vw[j]); + expp[j] = exp(-dtv * vw[j]); + } + if(barostat == BZP) + { + for(int i=0; iboxlo[0]; + oldhi = domain->boxhi[0]; + + domain->boxlo[0] = (oldlo-fixedpoint[0])*expq[0] + fixedpoint[0]; + domain->boxhi[0] = (oldhi-fixedpoint[0])*expq[0] + fixedpoint[0]; + + oldlo = domain->boxlo[1]; + oldhi = domain->boxhi[1]; + domain->boxlo[1] = (oldlo-fixedpoint[1])*expq[1] + fixedpoint[1]; + domain->boxhi[1] = (oldhi-fixedpoint[1])*expq[1] + fixedpoint[1]; + + oldlo = domain->boxlo[2]; + oldhi = domain->boxhi[2]; + domain->boxlo[2] = (oldlo-fixedpoint[2])*expq[2] + fixedpoint[2]; + domain->boxhi[2] = (oldhi-fixedpoint[2])*expq[2] + fixedpoint[2]; + } + } + MPI_Barrier(universe->uworld); + MPI_Bcast(&domain->boxlo[0], 3, MPI_DOUBLE, 0, universe->uworld); + MPI_Bcast(&domain->boxhi[0], 3, MPI_DOUBLE, 0, universe->uworld); + domain->set_global_box(); + domain->set_local_box(); + } + volume = domain->xprd * domain->yprd * domain->zprd; + // printf("step = %d end qc_step\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::a_step(){ + int n = atom->nlocal; + double **x = atom->x; + double **v = atom->v; + double x0, x1, x2, v0, v1, v2; // three components of x[i] and v[i] + + if(universe->iworld != 0) + { + // printf("iworld = %d c = %.4e s = %.4e w = %.4e\n", universe->iworld, Lan_c[universe->iworld], Lan_s[universe->iworld], _omega_k[universe->iworld]); + for(int i=0; iiworld] * x0 + 1./_omega_k[universe->iworld] * Lan_s[universe->iworld] * v0; + x[i][1] = Lan_c[universe->iworld] * x1 + 1./_omega_k[universe->iworld] * Lan_s[universe->iworld] * v1; + x[i][2] = Lan_c[universe->iworld] * x2 + 1./_omega_k[universe->iworld] * Lan_s[universe->iworld] * v2; + v[i][0] = -1.*_omega_k[universe->iworld] * Lan_s[universe->iworld] * x0 + Lan_c[universe->iworld] * v0; + v[i][1] = -1.*_omega_k[universe->iworld] * Lan_s[universe->iworld] * x1 + Lan_c[universe->iworld] * v1; + v[i][2] = -1.*_omega_k[universe->iworld] * Lan_s[universe->iworld] * x2 + Lan_c[universe->iworld] * v2; + } + } +} + +/* ---------------------------------------------------------------------- */ +/* +void FixPIMDLangevin::remove_com_motion(){ + if(universe->iworld == 0) + { + // double **x = atom->x; + double **v = atom->v; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (dynamic) masstotal = group->mass(igroup); + double vcm[3]; + group->vcm(igroup,masstotal,vcm); + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + v[i][0] -= vcm[0]; + v[i][1] -= vcm[1]; + v[i][2] -= vcm[2]; + } + } + } +} +*/ +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::baro_init() +{ + vw[0] = vw[1] = vw[2] = vw[3] = vw[4] = vw[5] = 0.0; + if(pstyle == ISO) {W = 3 * (atom->natoms) * tau_p * tau_p * np * kBT;} // consistent with the definition in i-Pi + // printf("tau_p = %.6e np = %.6e kBT = %.6e W = %.6e\n", tau_p, np, kBT, W);} + else if(pstyle == ANISO) {W = atom->natoms * tau_p * tau_p * np * kBT;} + Vcoeff = 1.0; + std::string out = fmt::format("\nInitializing PIMD {:s} barostat...\n", Barostats[barostat]); + out += fmt::format("The barostat mass is W = {:.16e}\n", W); + utils::logmesg(lmp, out); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::press_v_step() +{ + int nlocal = atom->nlocal; + double **f = atom->f; + double **v = atom->v; + int *type = atom->type; + volume = domain->xprd * domain->yprd * domain->zprd; + + if(pstyle == ISO) + { + if(barostat == BZP) + { + // printf("me = %d step = %d start press_v_step, baro.p = %.30e p_cv = %.30e\n", universe->me, update->ntimestep, W*vw[0], np*p_cv); + vw[0] += dtv * 3 * (volume * np * (p_cv - Pext) / force->nktv2p + Vcoeff / beta_np) / W; + // printf("me = %d step = %d add p-Pext, baro.p = %.30e\n", universe->me, update->ntimestep, W*vw[0]); + if(universe->iworld==0) + { + double dvw_proc = 0.0, dvw = 0.0; + for(int i = 0; i < nlocal; i++) + { + for(int j = 0; j < 3; j++) + { + dvw_proc += dtv2 * f[i][j] * v[i][j] / W + dtv3 * f[i][j] * f[i][j] / mass[type[i]] / W; + } + } + MPI_Allreduce(&dvw_proc, &dvw, 1, MPI_DOUBLE, MPI_SUM, world); + vw[0] += dvw; + } + MPI_Barrier(universe->uworld); + MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); + // printf("me = %d step = %d end press_v_step, baro.p = %.30e\n\n", universe->me, update->ntimestep, W*vw[0]); + } + else if(barostat == MTTK) + { + mtk_term1 = 2. / atom->natoms * totke / 3; + f_omega = (volume * np * (p_md - Pext) + mtk_term1) / W; + vw[0] += 0.5 * dtv * f_omega; + } + } + else if(pstyle == ANISO) + { + compute_stress_tensor(); + for(int ii=0; ii<3; ii++) + { + vw[ii] += dtv * (volume * np * (stress_tensor[ii] - Pext) / force->nktv2p + Vcoeff / beta_np) / W; + if(universe->iworld==0) + { + double dvw_proc = 0.0, dvw = 0.0; + for(int i = 0; i < nlocal; i++) + { + dvw_proc += dtv2 * f[i][ii] * v[i][ii] / W + dtv3 * f[i][ii] * f[i][ii] / mass[type[i]] / W; + } + MPI_Allreduce(&dvw_proc, &dvw, 1, MPI_DOUBLE, MPI_SUM, world); + vw[ii] += dvw; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::press_o_step() +{ + if(pstyle==ISO) + { + if(universe->me==0) + { + r1 = random->gaussian(); + vw[0] = c1 * vw[0] + c2 * sqrt(1. / W / beta_np) * r1; + } + MPI_Barrier(universe->uworld); + MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); + } + else if(pstyle==ANISO) + { + if(universe->me==0) + { + r1 = random->gaussian(); + r2 = random->gaussian(); + r3 = random->gaussian(); + vw[0] = c1 * vw[0] + c2 * sqrt(1. / W / beta_np) * r1; + vw[1] = c1 * vw[1] + c2 * sqrt(1. / W / beta_np) * r2; + vw[2] = c1 * vw[2] + c2 * sqrt(1. / W / beta_np) * r3; + } + MPI_Barrier(universe->uworld); + MPI_Bcast(&vw, 3, MPI_DOUBLE, 0, universe->uworld); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::Langevin_init() +{ + // printf("in Langevin_init\n"); + double beta = 1.0 / kBT; + _omega_np = np / beta / hbar; + double _omega_np_dt_half = _omega_np * update->dt * 0.5; + // printf("omega_np = %.4e wdt = %.4e\n", _omega_np, _omega_np_dt_half); + + _omega_k = new double[np]; + Lan_c = new double[np]; + Lan_s = new double[np]; + if(fmmode==physical){ + for (int i=0; i 0) gamma = 1.0 / tau; + else gamma = np / beta / hbar; + + if(integrator==obabo) c1 = exp(-gamma * 0.5 * update->dt); // tau is the damping time of the centroid mode. + else if(integrator==baoab) c1 = exp(-gamma * update->dt); + else error->universe_all(FLERR, "Unknown integrator parameter for fix pimd. Only obabo and baoab integrators is supported!"); + + c2 = sqrt(1.0 - c1 * c1); // note that c1 and c2 here only works for the centroid mode. + + if( thermostat == PILE_L ) + { + std::string out = "\nInitializing PI Langevin equation thermostat...\n"; + out += "Bead ID | omega | tau | c1 | c2\n"; + tau_k = new double[np]; + c1_k = new double[np]; + c2_k = new double[np]; + tau_k[0] = tau; c1_k[0] = c1; c2_k[0] = c2; + for(int i=1; idt / tau_k[i]); + else if(integrator==baoab) c1_k[i] = exp(-1.0 * update->dt / tau_k[i]); + else error->universe_all(FLERR, "Unknown integrator parameter for fix pimd. Only obabo and baoab integrators is supported!"); + c2_k[i] = sqrt(1.0 - c1_k[i] * c1_k[i]); + } + for(int i=0; inlocal; + int *type = atom->type; + double beta_np = 1.0 / force->boltz / Lan_temp / np * force->mvv2e; + if(thermostat == PILE_L) + { + for(int i=0; igaussian(); + r2 = random->gaussian(); + r3 = random->gaussian(); + atom->v[i][0] = c1_k[universe->iworld] * atom->v[i][0] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r1; + atom->v[i][1] = c1_k[universe->iworld] * atom->v[i][1] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r2; + atom->v[i][2] = c1_k[universe->iworld] * atom->v[i][2] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r3; + } + } +} + +/* ---------------------------------------------------------------------- + Normal Mode PIMD +------------------------------------------------------------------------- */ + +void FixPIMDLangevin::nmpimd_init() +{ + memory->create(M_x2xp, np, np, "fix_feynman:M_x2xp"); + memory->create(M_xp2x, np, np, "fix_feynman:M_xp2x"); + + lam = (double*) memory->smalloc(sizeof(double)*np, "FixPIMDLangevin::lam"); + + // Set up eigenvalues + for(int i=0; iiworld; + for(int i=1; i<=atom->ntypes; i++) + { + mass[i] = atom->mass[i]; + if(iworld) + { + if(fmmode==physical) { mass[i] *= 1.0; } + else if(fmmode==normal) { mass[i] *= lam[iworld]; } + mass[i] *= fmass; + } + } +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::nmpimd_transform(double **src, double **des, double *vector) +{ + if(cmode == SINGLE_PROC) + { + for(int i=0; itag[i]; + for(int d=0; d<3; d++) + { + des[i][d] = bufsorted[tagtmp-1][d]; + } + } + } + else if(cmode == MULTI_PROC) + { + int n = atom->nlocal; + int m = 0; + + for (int i = 0; i < n; i++) + for (int d = 0; d < 3; d++) { + des[i][d] = 0.0; + for (int j = 0; j < np; j++) { des[i][d] += (src[j][m] * vector[j]); } + m++; + } + } +} + +/* ---------------------------------------------------------------------- + Comm operations +------------------------------------------------------------------------- */ + +void FixPIMDLangevin::comm_init() +{ + // if(me == 0){ + if (sizeplan) { + delete [] plansend; + delete [] planrecv; + } + + sizeplan = np - 1; + plansend = new int[sizeplan]; + planrecv = new int[sizeplan]; + modeindex = new int[sizeplan]; + for (int i = 0; i < sizeplan; i++) { + int isend, irecv; + isend = ireplica + i + 1; + if (isend >= nreplica) isend -= nreplica; + irecv = ireplica - (i + 1); + if (irecv < 0) irecv += nreplica; + plansend[i] = universe->root_proc[isend]; + planrecv[i] = universe->root_proc[irecv]; + modeindex[i] = irecv; + } + // } +} + +/* ---------------------------------------------------------------------- */ +/* +void FixPIMDLangevin::init_x_unwrap() +{ + maxunwrap = atom->nmax; + memory->destroy(x_unwrap); + memory->destroy(tag_init); + memory->destroy(image_init); + memory->destroy(x_unwrapsort); + memory->create(x_unwrap, maxunwrap, 3, "FixPIMDLangevin:x_unwrap"); + memory->create(tag_init, maxunwrap, "FixPIMDLangevin:tag_init"); + memory->create(image_init, maxunwrap, "FixPIMDLangevin:image_init"); + memory->create(x_unwrapsort, ntotal, 3, "FixPIMDLangevin:x_unwrapsort"); +} +*/ +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::reallocate_xc() +{ + maxxc = atom->nmax; + memory->destroy(xc); + memory->create(xc, maxxc, 3, "FixPIMDLangevin:xc"); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::reallocate_x_unwrap() +{ + maxunwrap = atom->nmax; + memory->destroy(x_unwrap); + memory->create(x_unwrap, maxunwrap, 3, "FixPIMDLangevin:x_unwrap"); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::reallocate() +{ + maxlocal = atom->nmax; + memory->destroy(bufsend); + memory->destroy(bufrecv); + memory->destroy(tagsend); + memory->destroy(tagrecv); + memory->destroy(bufbeads); + memory->create(bufsend, maxlocal, 3, "FixPIMDLangevin:bufsend"); + memory->create(bufrecv, maxlocal, 3, "FixPIMDLangevin:bufrecv"); + memory->create(tagsend, maxlocal, "FixPIMDLangevin:tagsend"); + memory->create(tagrecv, maxlocal, "FixPIMDLangevin:tagrecv"); + memory->create(bufbeads, nreplica, maxlocal*3, "FixPIMDLangevin:bufrecv"); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::inter_replica_comm(double **ptr) +{ + MPI_Request requests[2]; + MPI_Status statuses[2]; + if (atom->nmax > maxlocal) reallocate(); + int nlocal = atom->nlocal; + // printf("me = %d starting inter_comm, nlocal = %d ntotal = %d\n", universe->me, nlocal, ntotal); + tagint *tag = atom->tag; + int i, m; + + // copy local values + for(i=0; itag[i]; + bufsorted[tagtmp-1][0] = ptr[i][0]; + bufsorted[tagtmp-1][1] = ptr[i][1]; + bufsorted[tagtmp-1][2] = ptr[i][2]; + m++; + } + MPI_Allgather(&m, 1, MPI_INT, counts, 1, MPI_INT, universe->uworld); + for (i = 0; i < nreplica; i++) { counts[i] *= 3; } + displacements[0] = 0; + for (i = 0; i < nreplica-1; i++) { displacements[i+1] = displacements[i] + counts[i]; } + MPI_Allgatherv(bufsorted[0], 3*m, MPI_DOUBLE, bufsortedall[0], counts, displacements, MPI_DOUBLE, universe->uworld); + // printf("me = %d bufsortedall[0] = %.8f %.8f %.8f bufsortedall[ntotal] = %.8f %.8f %.8f\n", universe->iworld, bufsortedall[0][0], bufsortedall[0][1], bufsortedall[0][2], bufsortedall[ntotal][0], bufsortedall[ntotal][1], bufsortedall[ntotal][2]); + /* + m = 0; + for(i=0; ime, nlocal, ntotal, m, sizeplan); + for(int iplan=0; iplanuworld, &requests[0]); + MPI_Irecv(tagrecv, ntotal, MPI_LMP_TAGINT, planrecv[iplan], 0, universe->uworld, &requests[1]); + // printf("me = %d iplan = %d irecv finished, plansend = %d, planrecv = %d, modeindex = %d\n", universe->me, iplan, plansend[iplan], planrecv[iplan], modeindex[iplan]); + // printf("bufsend[0]: %.4f %.4f %.4f\ntagsend[0]: %d\n", bufsend[0][0], bufsend[0][1], bufsend[0][2], tagsend[0]); + // printf("bufsend[255]: %.4f %.4f %.4f\ntagsend[255]: %d\n", bufsend[255][0], bufsend[255][1], bufsend[255][2], tagsend[255]); + MPI_Send(bufsend[0], 3*ntotal, MPI_DOUBLE, plansend[iplan], 0, universe->uworld); + MPI_Send(tagsend, ntotal, MPI_LMP_TAGINT, plansend[iplan], 0, universe->uworld); + // printf("me = %d MPI_Send done\n", universe->me); + MPI_Waitall(2, requests, statuses); + // printf("me = %d iplan = %d send recv finished\n", iplan, universe->me); + for(i=0; imap(tagrecv[i]); + bufbeads[modeindex[iplan]][3*m+0] = bufrecv[i][0]; + bufbeads[modeindex[iplan]][3*m+1] = bufrecv[i][1]; + bufbeads[modeindex[iplan]][3*m+2] = bufrecv[i][2]; + } + } + */ + // printf("me = %d finishing inter_comm\n", universe->me); + } + else if(cmode == MULTI_PROC) + { + m = 0; + // printf("me = %d trying to copy bufsend\n", universe->me); + for(i=0; ime, m); + // if(me==0) {for(i=0; ime, i, counts[i]);}} + // printf("me = %d") + MPI_Gather(&m, 1, MPI_INT, counts, 1, MPI_INT, 0, world); + // printf("me = %d counts gathered\n", universe->me); + // if(me==0) {for(i=0; ime, i, counts[i]);}} + displacements[0] = 0; + // printf("me = %d displacements[0] = %d\n", universe->me, displacements[0]); + for (i = 0; i < nprocs-1; i++) { displacements[i+1] = displacements[i] + counts[i]; } + // printf("me = %d displacements done\n", universe->me); + // if(me==0) {for(i=0; ime, i, displacements[i]);}} + MPI_Gatherv(tagsend, m, MPI_LMP_TAGINT, tagsendall, counts, displacements, MPI_LMP_TAGINT, 0, world); + // printf("me = %d tags gathered\n", universe->me); + for (i = 0; i < nprocs; i++) { counts[i] *= 3; } + for (i = 0; i < nprocs-1; i++) { displacements[i+1] = displacements[i] + counts[i]; } + MPI_Gatherv(bufsend[0], 3*m, MPI_DOUBLE, bufsendall[0], counts, displacements, MPI_DOUBLE, 0, world); + // printf("me = %d bufsend gathered\n", universe->me); + // printf("me = %d, tagrecvall[0] = %d bufrecvall[0][0] = %.4f\n", universe->me, tagrecvall[0], bufrecvall[0][0]); + + // printf("universe->me = %d comm->me = %d sizeplan = %d\n", universe->me, comm->me, sizeplan); + for(int iplan=0; iplanuworld, &requests[0]); + MPI_Irecv(tagrecvall, ntotal, MPI_LMP_TAGINT, planrecv[iplan], 0, universe->uworld, &requests[1]); + MPI_Send(bufsendall[0], 3*ntotal, MPI_DOUBLE, plansend[iplan], 0, universe->uworld); + MPI_Send(tagsendall, ntotal, MPI_LMP_TAGINT, plansend[iplan], 0, universe->uworld); + MPI_Waitall(2,requests,statuses); + } + // else{ + // printf("me = %d not sendrecceving\n", universe->me); + // } + + // printf("me = %d sendrecv finished\n", universe->me); + // printf("me = %d to be bcasted: tag[0] = %d bufrecvall[0][0] = %.4f\n", universe->me, tagrecvall[0], bufrecvall[0][0]); + MPI_Bcast(tagrecvall, ntotal, MPI_LMP_TAGINT, 0, world); + MPI_Bcast(bufrecvall[0], 3*ntotal, MPI_DOUBLE, 0, world); + // printf("me = %d broadcasted\n", universe->me); + for(i=0; imap(tagrecvall[i]); + if (m < 0 || m >= nlocal) continue; + bufbeads[modeindex[iplan]][3*m+0] = bufrecvall[i][0]; + bufbeads[modeindex[iplan]][3*m+1] = bufrecvall[i][1]; + bufbeads[modeindex[iplan]][3*m+2] = bufrecvall[i][2]; + } + } + // printf("me = %d, tag[0] = %d bufrecvall[0][0] = %.4f bufbeads[0][0] = %.4f bufbeads[1][0] = %.4f bufbeads done\n", universe->me, tag[0], bufrecvall[0][0], bufbeads[0][0], bufbeads[1][0]); + } +} + +/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_vir_() +{ + int nlocal = atom->nlocal; + xf = vir_ = xcf = centroid_vir = 0.0; + int idx = atom->map(1); + // printf("in post_force, x_unwrap: %.6f %.6f %.6f xcall: %.6f %.6f %.6f\n", x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xcall[0], xcall[1], xcall[2]); + // printf("in compute_vir, xu = %.6f %.6f %.6f xc = %.6f %.6f %.6f\n", x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xc[idx][0], xc[idx][1], xc[idx][2]); + for(int i=0; if[i][j]; + xcf += (x_unwrap[i][j] - xc[i][j]) * atom->f[i][j]; + } + // int idx = atom->map(i+1); + // printf("me = %d step = %d tag = %d idx = %d xu = %.6f %.6f %.6f xc = %.6f %.6f %.6f f = %.6f %.6f %.6f\n", universe->me, update->ntimestep, i+1, idx, x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xc[idx][0], xc[idx][1], xc[idx][2], atom->f[idx][0], atom->f[idx][1], atom->f[idx][2]); + } + MPI_Allreduce(&xf, &vir_, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + MPI_Allreduce(&xcf, ¢roid_vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + if(pstyle == ANISO){ + for(int i=0; i<6; i++) c_vir_tensor[i] = 0.0; + for(int i=0; if[i][0]; + c_vir_tensor[1] += (x_unwrap[i][1] - xc[i][1]) * atom->f[i][1]; + c_vir_tensor[2] += (x_unwrap[i][2] - xc[i][2]) * atom->f[i][2]; + c_vir_tensor[3] += (x_unwrap[i][0] - xc[i][0]) * atom->f[i][1]; + c_vir_tensor[4] += (x_unwrap[i][0] - xc[i][0]) * atom->f[i][2]; + c_vir_tensor[5] += (x_unwrap[i][1] - xc[i][1]) * atom->f[i][2]; + } + MPI_Allreduce(MPI_IN_PLACE, &c_vir_tensor, 6, MPI_DOUBLE, MPI_SUM, universe->uworld); + } +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_vir() +{ + volume = domain->xprd * domain->yprd * domain->zprd; + c_press->compute_vector(); + virial[0] = c_press->vector[0]*volume; + virial[1] = c_press->vector[1]*volume; + virial[2] = c_press->vector[2]*volume; + virial[3] = c_press->vector[3]*volume; + virial[4] = c_press->vector[4]*volume; + virial[5] = c_press->vector[5]*volume; + for(int i=0; i<6; i++) virial[i] /= universe->procs_per_world[universe->iworld]; + double vir_bead=(virial[0]+virial[1]+virial[2]); + MPI_Allreduce(&vir_bead, &vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + MPI_Allreduce(MPI_IN_PLACE, &virial[0], 6, MPI_DOUBLE, MPI_SUM, universe->uworld); + // printf("me = %d step = %d vir = %.30e\n", universe->me, update->ntimestep, vir); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_stress_tensor() +{ + int nlocal = atom->nlocal; + int *type = atom->type; + if(universe->iworld == 0){ + inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); + for(int i=0; i<6; i++) ke_tensor[i] = 0.0; + for(int i=0; iv[i][0] * atom->v[i][0] * force->mvv2e; + ke_tensor[1] += 0.5 * mass[type[i]] * atom->v[i][1] * atom->v[i][1] * force->mvv2e; + ke_tensor[2] += 0.5 * mass[type[i]] * atom->v[i][2] * atom->v[i][2] * force->mvv2e; + ke_tensor[3] += 0.5 * mass[type[i]] * atom->v[i][0] * atom->v[i][1] * force->mvv2e; + ke_tensor[4] += 0.5 * mass[type[i]] * atom->v[i][0] * atom->v[i][2] * force->mvv2e; + ke_tensor[5] += 0.5 * mass[type[i]] * atom->v[i][1] * atom->v[i][2] * force->mvv2e; + } + // MPI_Allreduce(&ke_tensor, &ke_tensor, 6, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(MPI_IN_PLACE, &ke_tensor, 6, MPI_DOUBLE, MPI_SUM, world); + for(int i=0; i<6; i++) + { + stress_tensor[i] = inv_volume * ((2*ke_tensor[i] - c_vir_tensor[i]) * force->nktv2p + virial[i]) / np; + // printf("i = %d, c_vir = %.6f, virial = %.6f stress = %.6f\n", i, c_vir_tensor[i], virial[i], stress_tensor[i]); + } + } + MPI_Bcast(&stress_tensor, 6, MPI_DOUBLE, 0, universe->uworld); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_totke() +{ + kine = 0.0; + totke = ke_bead = 0.0; + int nlocal = atom->nlocal; + int *type = atom->type; + for(int i=0; iv[i][j] * atom->v[i][j]; + } + } + kine *= force->mvv2e; + // printf("me = %d, kine = %.6e\n", universe->me, kine); + MPI_Allreduce(&kine, &ke_bead, 1, MPI_DOUBLE, MPI_SUM, world); + // MPI_Allreduce(&kine, &totke, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + // totke *= force->mvv2e / np; + + // c_press->compute_scalar(); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_spring_energy() +{ + spring_energy = 0.0; + total_spring_energy = se_bead = 0.0; + + double **x = atom->x; + double* _mass = atom->mass; + int* type = atom->type; + int nlocal = atom->nlocal; + // printf("iworld = %d, fbond = %.4e lam = %.4e\n", universe->iworld, fbond, lam[universe->iworld]); + + for(int i=0; iiworld] * (x[i][0]*x[i][0] + x[i][1]*x[i][1] + x[i][2]*x[i][2]); + } + MPI_Allreduce(&spring_energy, &se_bead, 1, MPI_DOUBLE, MPI_SUM, world); + // MPI_Allreduce(&spring_energy, &total_spring_energy, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + // total_spring_energy /= np; +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_pote() +{ + pe_bead = 0.0; + pot_energy_partition = 0.0; + pote = 0.0; + c_pe->compute_scalar(); + pe_bead = c_pe->scalar; + pot_energy_partition = pe_bead / universe->procs_per_world[universe->iworld]; + // MPI_Allreduce(&pot_energy_partition, &pote, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + // pote /= np; +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_tote() +{ + tote = totke + pote + total_spring_energy; +} + +/* ---------------------------------------------------------------------- */ +/* +void FixPIMDLangevin::compute_t_prim() +{ + t_prim = 1.5 * atom->natoms * np * force->boltz * temp - total_spring_energy; +} +*/ +/* ---------------------------------------------------------------------- */ +/* +void FixPIMDLangevin::compute_t_vir() +{ + t_vir = -0.5 / np * vir_; + t_cv = 1.5 * atom->natoms * force->boltz * temp - 0.5 / np * centroid_vir; +} +*/ +/* ---------------------------------------------------------------------- */ +/* +void FixPIMDLangevin::compute_p_prim() +{ + p_prim = atom->natoms * np * force->boltz * temp * inv_volume - 1.0 / 1.5 * inv_volume * total_spring_energy; + p_prim *= force->nktv2p; +} +*/ +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_p_cv() +{ + inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); + // p_md = 2. / 3 * inv_volume * ((totke - total_spring_energy) * force->nktv2p + 0.5 * vir / np) ; + // printf("inv_V = %.30e ke = %.30e cv = %.30e vir = %.30e\n", inv_volume, ke_bead, centroid_vir, vir); + if(universe->iworld == 0) + { + p_cv = 1. / 3. * inv_volume * ((2. * ke_bead - 1. * centroid_vir) * force->nktv2p + 1. * vir) / np; + } + MPI_Bcast(&p_cv, 1, MPI_DOUBLE, 0, universe->uworld); +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::compute_totenthalpy() +{ + volume = domain->xprd * domain->yprd * domain->zprd; + if(barostat == BZP) + { + if(pstyle == ISO) + { + totenthalpy = tote + 0.5*W*vw[0]*vw[0]/np + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); + } + else if(pstyle == ANISO) + { + totenthalpy = tote + 0.5*W*vw[0]*vw[0]/np + 0.5*W*vw[1]*vw[1]/np + 0.5*W*vw[2]*vw[2]/np + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); + } + } + else if(barostat == MTTK) totenthalpy = tote + 1.5*W*vw[0]*vw[0]/np + Pext * (volume - vol0); +} + +/* ---------------------------------------------------------------------- */ + +double FixPIMDLangevin::compute_vector(int n) +{ + if(n==0) { return ke_bead; } + if(n==1) { return se_bead; } + if(n==2) { return pe_bead; } + if(n==3) { return tote; } + // if(n==3) { return W*vw[0]; } + if(!pstat_flag) + { + if(n==4) { return t_prim; } + if(n==5) { return t_vir; } + if(n==6) { return t_cv; } + } + else if(pstat_flag) + { + if(pstyle == ISO) + { + if(barostat == BZP) + { + if(n==4) { return 0.5*W*vw[0]*vw[0]; } + } + else if(barostat == MTTK) + { + if(n==4) { return 1.5*W*vw[0]*vw[0]; } + } + if(n==5) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } + if(n==6) { volume = domain->xprd * domain->yprd * domain->zprd; return - Vcoeff * np * kBT * log(volume); } + if(n==7) { return totenthalpy; } + if(n==8) { return p_cv; } + if(n==9) { return total_spring_energy; } + } + else if(pstyle == ANISO) + { + + } + } + /* + + if(n==7) { return p_prim; } + if(n==8) { return p_md; } + if(n==9) { return p_cv; } + if(n==10) {return totenthalpy; + if(pstyle == ISO){ + if(n==11) { return vw[0]; } + if(n==12) { + if(barostat == BZP) { return 0.5*W*vw[0]*vw[0]; } + else if(barostat == MTTK) { return 1.5*W*vw[0]*vw[0]; } + } + if(n==13) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } + if(n==14) { volume = domain->xprd * domain->yprd * domain->zprd; + // printf("Vcoeff = %.6e np = %d kBT = %.6e logV = %.6e\n", Vcoeff, np, kBT, log(volume)); + return - Vcoeff * np * kBT * log(volume); } + } + else if(pstyle==ANISO){ + if(n>10 && n<=13) return vw[n-11]; + if(n==14) return 0.5*W*vw[0]*vw[0]+0.5*W*vw[1]*vw[1]+0.5*W*vw[2]*vw[2]; + if(n>14 && n<21) return stress_tensor[n-15]; + if(n==21) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } + if(n==22) { volume = domain->xprd * domain->yprd * domain->zprd; return - Vcoeff * np * kBT * log(volume); } + } + return 0.0; + */ +} diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h new file mode 100644 index 0000000000..02e78935aa --- /dev/null +++ b/src/REPLICA/fix_pimd_langevin.h @@ -0,0 +1,198 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef FIX_CLASS +// clang-format off +FixStyle(pimd/langevin,FixPIMDLangevin); +// clang-format on +#else + +#ifndef FIX_PIMD_LANGEVIN_H +#define FIX_PIMD_LANGEVIN_H + +#include "fix.h" + +namespace LAMMPS_NS { + +class FixPIMDLangevin : public Fix { + public: + FixPIMDLangevin(class LAMMPS *, int, char **); + ~FixPIMDLangevin() override; + + int setmask() override; + + void init() override; + void setup(int) override; +// void post_neighbor() override; + void post_force(int) override; + void initial_integrate(int) override; + void final_integrate() override; + void end_of_step() override; + + double compute_vector(int) override; + + /* System setting variables */ + int method; // PIMD or NMPIMD or CMD + int fmmode; // physical or normal + int np; // number of beads + double inverse_np; // 1.0/np + double temp; // temperature + double planck, hbar; // Planck's constant + double lj_epsilon, lj_sigma, lj_mass; // LJ unit energy, length, and mass scales + double other_planck; + double kBT; // k_B * temp + double beta, beta_np; // beta = 1./kBT beta_np = 1./kBT/np + int thermostat; // NHC or PILE_L + int barostat; // BZP + int integrator; // obabo or baoab + int ensemble; // nve or nvt or nph or npt + int mapflag; // should be 1 if number of beads > 1 + int removecomflag; + double masstotal; + + // void remove_com_motion(); + + double fixedpoint[3]; // location of dilation fixed-point + /* ring-polymer model */ + + double omega_np, fbond, spring_energy, sp; + + /* fictitious mass */ + + double fmass, *mass; + + /* inter-partition communication */ + + MPI_Comm rootworld; + int me, nprocs, ireplica, nreplica, nprocs_universe; + int ntotal, maxlocal; + + int cmode; + int sizeplan; + int *plansend, *planrecv; + + tagint *tagsend, *tagrecv; + double **bufsend, **bufrecv, **bufbeads; + double **bufsorted, **bufsortedall; + double **outsorted, **buftransall; + + tagint *tagsendall, *tagrecvall; + double **bufsendall, **bufrecvall; + + int *counts, *displacements; + + void comm_init(); + void inter_replica_comm(double **ptr); + + /* normal-mode operations */ + + double *lam, **M_x2xp, **M_xp2x, **M_f2fp, **M_fp2f; + int *modeindex; + + void reallocate(); + void nmpimd_init(); + void nmpimd_transform(double **src, double **des, double **mat); + void nmpimd_transform(double **, double **, double *); + + /* Langevin integration */ + + double dtv, dtf, dtv2, dtv3; + double gamma, c1, c2, tau; + double *tau_k, *c1_k, *c2_k; + double pilescale=1.0; + double Lan_temp; + double r1, r2, r3; + double _omega_np, *_omega_k, *Lan_s, *Lan_c; // sin(omega_k*dt*0.5), cos(omega_k*dt*0.5) + + class RanMars *random; + int seed=975481; + FILE *frand; + + int tstat_flag; // tstat_flat = 1 if thermostat if used + void Langevin_init(); + void b_step(); // integrate for dt/2 according to B part (v <- v + f * dt/2) + void a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) + void qc_step(); // integrate for dt/2 for the centroid mode (x <- x + v * dt/2) + void o_step(); // integrate for dt according to O part (O-U process, for thermostating) + + /* Bussi-Zykova-Parrinello barostat */ + + double f_omega, mtk_term1; + int pstat_flag; // pstat_flag = 1 if barostat is used + int pstyle; // pstyle = ISO or ANISO (will support TRICLINIC in the future) + double W, tau_p, Pext, totenthalpy = 0.0, Vcoeff; + int p_flag[6]; + double vw[6]; // barostat velocity + double ke_tensor[6]; // kinetic energy tensor + double c_vir_tensor[6]; // centroid-virial tensor + double stress_tensor[6]; // path integral centroid-virial stress tensor + + void baro_init(); + void press_v_step(); + void press_o_step(); + + /* centroid-virial estimator computation */ + double vol0 = 0.0; + double inv_volume = 0.0; + // double inv_volume = 0.0, vol_ = 0.0, vol0 = 0.0; + double volume = 0.0; + double **xc, *xcall; + int maxxc; + // int n_unwrap; + int maxunwrap; + // int maxunwrap, nlocal_init; +// tagint *tag_init, *tag_initall; +// imageint *image_init, *image_initall; + double **x_unwrap; +// double **x_unwrap, **x_unwrapsort; +// double **x_unwrapall; +// void init_x_unwrap(); + void reallocate_x_unwrap(); + void reallocate_xc(); + void collect_xc(); + // void compute_xc(); + // void compute_fc(); + double xf, vir, vir_, xcf, centroid_vir; + double t_vir, t_cv, p_prim, p_vir, p_cv, p_cv_, p_md; + // double vir_, xcf, vir2; + + /* Computes */ + double kine, pote, tote, totke; + double ke_bead, se_bead, pe_bead, pot_energy_partition; + double total_spring_energy; + double t_prim; + // double p_prim; + char *id_pe; + char *id_press; + class Compute *c_pe; + class Compute *c_press; + + void compute_totke(); // 1: kinetic energy + void compute_spring_energy(); // 2: spring elastic energy + void compute_pote(); // 3: potential energy + void compute_tote(); // 4: total energy: 1+2+3 for all the beads + // void compute_t_prim(); // 5: primitive kinetic energy estimator + // void compute_p_prim(); // primitive pressure estimator + void compute_stress_tensor(); + // void compute_t_vir(); // centroid-virial kinetic energy estimator + void compute_p_cv(); // centroid-virial pressure estimator + // void compute_p_vir(); // centroid-virial pressure estimator + void compute_vir(); + void compute_vir_(); + void compute_totenthalpy(); +}; + +} // namespace LAMMPS_NS + +#endif +#endif From c351b63919f8646cb7943742e6cffed32aa52d79 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 24 Feb 2023 11:48:28 -0500 Subject: [PATCH 009/448] fix pimd/langevin put properties and functions below protected --- src/REPLICA/fix_pimd_langevin.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 02e78935aa..4f0390c700 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -41,6 +41,7 @@ class FixPIMDLangevin : public Fix { double compute_vector(int) override; + protected: /* System setting variables */ int method; // PIMD or NMPIMD or CMD int fmmode; // physical or normal From 3737b5f774b99ed5d8a34b10de6057817afbb875 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 25 Feb 2023 16:22:27 -0500 Subject: [PATCH 010/448] whitespace fixes and clang-format on the header --- src/REPLICA/fix_pimd_langevin.cpp | 90 +++++++++++++++---------------- src/REPLICA/fix_pimd_langevin.h | 86 ++++++++++++++--------------- 2 files changed, 86 insertions(+), 90 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 9ac8fc3b17..1b2e734922 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -146,7 +146,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); if (fmass < 0.0 || fmass > 1.0) error->universe_all(FLERR, "Invalid fmass value for fix pimd"); - } + } else if(strcmp(arg[i], "fmmode")==0) { @@ -164,7 +164,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n else if (strcmp(arg[i], "temp") == 0) { temp = utils::numeric(FLERR, arg[i + 1], false, lmp); if (temp < 0.0) error->universe_all(FLERR, "Invalid temp value for fix pimd"); - } + } else if (strcmp(arg[i], "lj") == 0) { lj_epsilon = utils::numeric(FLERR, arg[i+1], false, lmp); @@ -178,7 +178,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n else if(strcmp(arg[i], "thermostat")==0) { - if(strcmp(arg[i+1],"PILE_L")==0) + if(strcmp(arg[i+1],"PILE_L")==0) { thermostat = PILE_L; seed = atoi(arg[i+2]); @@ -190,7 +190,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n { tau = atof(arg[i+1]); } - + else if(strcmp(arg[i], "press")==0) { Pext = atof(arg[i+1]); @@ -199,7 +199,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n else if(strcmp(arg[i], "barostat")==0) { - if(strcmp(arg[i+1],"MTTK")==0) + if(strcmp(arg[i+1],"MTTK")==0) { barostat = MTTK; } @@ -292,7 +292,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n Lan_temp = temp; random = new RanMars(lmp, seed + universe->me); } - + me = comm->me; nprocs = comm->nprocs; if(nprocs == 1) cmode = SINGLE_PROC; @@ -385,7 +385,7 @@ void FixPIMDLangevin::init() inverse_np = 1.0 / np; const double Boltzmann = force->boltz; - if (strcmp(update->unit_style,"lj") == 0) { + if (strcmp(update->unit_style,"lj") == 0) { double planck_star = sqrt(lj_epsilon)*sqrt(atom->mass[0])*lj_sigma; planck = other_planck / planck_star; } @@ -517,10 +517,10 @@ void FixPIMDLangevin::setup(int vflag) // compute_pote(); // if(pstyle==ANISO) compute_stress_tensor(); end_of_step(); - c_pe->addstep(update->ntimestep+1); + c_pe->addstep(update->ntimestep+1); c_press->addstep(update->ntimestep+1); // printf("setup ending: \ncell = %.16e %.16e %.16e\nvol = %.16e\n", domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); - // printf("me = %d, setup finished\n", universe->me); + // printf("me = %d, setup finished\n", universe->me); } /* ---------------------------------------------------------------------- */ @@ -557,7 +557,7 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) press_v_step(); } /* - if(pstat_flag) + if(pstat_flag) { } */ @@ -580,7 +580,7 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) } else if(integrator==baoab) { - if(pstat_flag) + if(pstat_flag) { compute_totke(); compute_p_cv(); @@ -604,7 +604,7 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) if(pstat_flag) press_o_step(); } qc_step(); - a_step(); + a_step(); } else { @@ -612,7 +612,7 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) } collect_xc(); compute_spring_energy(); - + if(method==NMPIMD) { inter_replica_comm(x); @@ -636,7 +636,7 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) void FixPIMDLangevin::final_integrate() { - if(pstat_flag) + if(pstat_flag) { compute_totke(); compute_p_cv(); @@ -655,7 +655,7 @@ void FixPIMDLangevin::final_integrate() } else if(integrator==baoab) { - + } else { @@ -720,8 +720,8 @@ void FixPIMDLangevin::post_force(int /*flag*/) else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); // nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); } - c_pe->addstep(update->ntimestep+1); - c_press->addstep(update->ntimestep+1); + c_pe->addstep(update->ntimestep+1); + c_press->addstep(update->ntimestep+1); // printf("me = %d, step %d post_force ends!\n", universe->me, update->ntimestep); } @@ -804,7 +804,7 @@ void FixPIMDLangevin::update_x_unwrap() // x_unwrap = new double[nlocal*3]; // printf("me = %d, doing xu\n", universe->me); for(int i=0; iboxlo[0]; oldhi = domain->boxhi[0]; - + domain->boxlo[0] = (oldlo-fixedpoint[0])*expq[0] + fixedpoint[0]; domain->boxhi[0] = (oldhi-fixedpoint[0])*expq[0] + fixedpoint[0]; @@ -912,13 +912,13 @@ void FixPIMDLangevin::qc_step(){ oldhi = domain->boxhi[1]; domain->boxlo[1] = (oldlo-fixedpoint[1])*expq[1] + fixedpoint[1]; domain->boxhi[1] = (oldhi-fixedpoint[1])*expq[1] + fixedpoint[1]; - + oldlo = domain->boxlo[2]; oldhi = domain->boxhi[2]; domain->boxlo[2] = (oldlo-fixedpoint[2])*expq[2] + fixedpoint[2]; domain->boxhi[2] = (oldhi-fixedpoint[2])*expq[2] + fixedpoint[2]; } - } + } MPI_Barrier(universe->uworld); MPI_Bcast(&domain->boxlo[0], 3, MPI_DOUBLE, 0, universe->uworld); MPI_Bcast(&domain->boxhi[0], 3, MPI_DOUBLE, 0, universe->uworld); @@ -942,8 +942,8 @@ void FixPIMDLangevin::a_step(){ // printf("iworld = %d c = %.4e s = %.4e w = %.4e\n", universe->iworld, Lan_c[universe->iworld], Lan_s[universe->iworld], _omega_k[universe->iworld]); for(int i=0; iiworld] * x0 + 1./_omega_k[universe->iworld] * Lan_s[universe->iworld] * v0; @@ -967,7 +967,7 @@ void FixPIMDLangevin::remove_com_motion(){ int nlocal = atom->nlocal; if (dynamic) masstotal = group->mass(igroup); double vcm[3]; - group->vcm(igroup,masstotal,vcm); + group->vcm(igroup,masstotal,vcm); for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { v[i][0] -= vcm[0]; @@ -999,7 +999,7 @@ void FixPIMDLangevin::press_v_step() int nlocal = atom->nlocal; double **f = atom->f; double **v = atom->v; - int *type = atom->type; + int *type = atom->type; volume = domain->xprd * domain->yprd * domain->zprd; if(pstyle == ISO) @@ -1079,7 +1079,7 @@ void FixPIMDLangevin::press_o_step() vw[2] = c1 * vw[2] + c2 * sqrt(1. / W / beta_np) * r3; } MPI_Barrier(universe->uworld); - MPI_Bcast(&vw, 3, MPI_DOUBLE, 0, universe->uworld); + MPI_Bcast(&vw, 3, MPI_DOUBLE, 0, universe->uworld); } } @@ -1099,7 +1099,7 @@ void FixPIMDLangevin::Langevin_init() if(fmmode==physical){ for (int i=0; i 0) gamma = 1.0 / tau; else gamma = np / beta / hbar; - + if(integrator==obabo) c1 = exp(-gamma * 0.5 * update->dt); // tau is the damping time of the centroid mode. - else if(integrator==baoab) c1 = exp(-gamma * update->dt); + else if(integrator==baoab) c1 = exp(-gamma * update->dt); else error->universe_all(FLERR, "Unknown integrator parameter for fix pimd. Only obabo and baoab integrators is supported!"); c2 = sqrt(1.0 - c1 * c1); // note that c1 and c2 here only works for the centroid mode. @@ -1125,7 +1125,7 @@ void FixPIMDLangevin::Langevin_init() if( thermostat == PILE_L ) { std::string out = "\nInitializing PI Langevin equation thermostat...\n"; - out += "Bead ID | omega | tau | c1 | c2\n"; + out += "Bead ID | omega | tau | c1 | c2\n"; tau_k = new double[np]; c1_k = new double[np]; c2_k = new double[np]; @@ -1162,7 +1162,7 @@ void FixPIMDLangevin::o_step() r1 = random->gaussian(); r2 = random->gaussian(); r3 = random->gaussian(); - atom->v[i][0] = c1_k[universe->iworld] * atom->v[i][0] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r1; + atom->v[i][0] = c1_k[universe->iworld] * atom->v[i][0] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r1; atom->v[i][1] = c1_k[universe->iworld] * atom->v[i][1] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r2; atom->v[i][2] = c1_k[universe->iworld] * atom->v[i][2] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r3; } @@ -1188,7 +1188,7 @@ void FixPIMDLangevin::nmpimd_init() // Set up eigenvectors for degenerated modes for(int j=0; jdestroy(tag_init); memory->destroy(image_init); memory->destroy(x_unwrapsort); - memory->create(x_unwrap, maxunwrap, 3, "FixPIMDLangevin:x_unwrap"); + memory->create(x_unwrap, maxunwrap, 3, "FixPIMDLangevin:x_unwrap"); memory->create(tag_init, maxunwrap, "FixPIMDLangevin:tag_init"); memory->create(image_init, maxunwrap, "FixPIMDLangevin:image_init"); memory->create(x_unwrapsort, ntotal, 3, "FixPIMDLangevin:x_unwrapsort"); @@ -1552,7 +1552,7 @@ void FixPIMDLangevin::compute_stress_tensor() } // MPI_Allreduce(&ke_tensor, &ke_tensor, 6, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(MPI_IN_PLACE, &ke_tensor, 6, MPI_DOUBLE, MPI_SUM, world); - for(int i=0; i<6; i++) + for(int i=0; i<6; i++) { stress_tensor[i] = inv_volume * ((2*ke_tensor[i] - c_vir_tensor[i]) * force->nktv2p + virial[i]) / np; // printf("i = %d, c_vir = %.6f, virial = %.6f stress = %.6f\n", i, c_vir_tensor[i], virial[i], stress_tensor[i]); @@ -1600,7 +1600,7 @@ void FixPIMDLangevin::compute_spring_energy() for(int i=0; iiworld] * (x[i][0]*x[i][0] + x[i][1]*x[i][1] + x[i][2]*x[i][2]); + spring_energy += 0.5 * _mass[type[i]] * fbond * lam[universe->iworld] * (x[i][0]*x[i][0] + x[i][1]*x[i][1] + x[i][2]*x[i][2]); } MPI_Allreduce(&spring_energy, &se_bead, 1, MPI_DOUBLE, MPI_SUM, world); // MPI_Allreduce(&spring_energy, &total_spring_energy, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); @@ -1660,7 +1660,7 @@ void FixPIMDLangevin::compute_p_cv() // printf("inv_V = %.30e ke = %.30e cv = %.30e vir = %.30e\n", inv_volume, ke_bead, centroid_vir, vir); if(universe->iworld == 0) { - p_cv = 1. / 3. * inv_volume * ((2. * ke_bead - 1. * centroid_vir) * force->nktv2p + 1. * vir) / np; + p_cv = 1. / 3. * inv_volume * ((2. * ke_bead - 1. * centroid_vir) * force->nktv2p + 1. * vir) / np; } MPI_Bcast(&p_cv, 1, MPI_DOUBLE, 0, universe->uworld); } @@ -1670,7 +1670,7 @@ void FixPIMDLangevin::compute_p_cv() void FixPIMDLangevin::compute_totenthalpy() { volume = domain->xprd * domain->yprd * domain->zprd; - if(barostat == BZP) + if(barostat == BZP) { if(pstyle == ISO) { @@ -1719,23 +1719,23 @@ double FixPIMDLangevin::compute_vector(int n) } else if(pstyle == ANISO) { - + } } /* - + if(n==7) { return p_prim; } if(n==8) { return p_md; } if(n==9) { return p_cv; } if(n==10) {return totenthalpy; if(pstyle == ISO){ if(n==11) { return vw[0]; } - if(n==12) { + if(n==12) { if(barostat == BZP) { return 0.5*W*vw[0]*vw[0]; } else if(barostat == MTTK) { return 1.5*W*vw[0]*vw[0]; } } if(n==13) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } - if(n==14) { volume = domain->xprd * domain->yprd * domain->zprd; + if(n==14) { volume = domain->xprd * domain->yprd * domain->zprd; // printf("Vcoeff = %.6e np = %d kBT = %.6e logV = %.6e\n", Vcoeff, np, kBT, log(volume)); return - Vcoeff * np * kBT * log(volume); } } diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 4f0390c700..cf2d63b91c 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -33,7 +33,6 @@ class FixPIMDLangevin : public Fix { void init() override; void setup(int) override; -// void post_neighbor() override; void post_force(int) override; void initial_integrate(int) override; void final_integrate() override; @@ -43,26 +42,24 @@ class FixPIMDLangevin : public Fix { protected: /* System setting variables */ - int method; // PIMD or NMPIMD or CMD - int fmmode; // physical or normal - int np; // number of beads - double inverse_np; // 1.0/np - double temp; // temperature - double planck, hbar; // Planck's constant - double lj_epsilon, lj_sigma, lj_mass; // LJ unit energy, length, and mass scales + int method; // PIMD or NMPIMD or CMD + int fmmode; // physical or normal + int np; // number of beads + double inverse_np; // 1.0/np + double temp; // temperature + double planck, hbar; // Planck's constant + double lj_epsilon, lj_sigma, lj_mass; // LJ unit energy, length, and mass scales double other_planck; - double kBT; // k_B * temp - double beta, beta_np; // beta = 1./kBT beta_np = 1./kBT/np - int thermostat; // NHC or PILE_L - int barostat; // BZP - int integrator; // obabo or baoab - int ensemble; // nve or nvt or nph or npt - int mapflag; // should be 1 if number of beads > 1 + double kBT; // k_B * temp + double beta, beta_np; // beta = 1./kBT beta_np = 1./kBT/np + int thermostat; // NHC or PILE_L + int barostat; // BZP + int integrator; // obabo or baoab + int ensemble; // nve or nvt or nph or npt + int mapflag; // should be 1 if number of beads > 1 int removecomflag; double masstotal; - // void remove_com_motion(); - double fixedpoint[3]; // location of dilation fixed-point /* ring-polymer model */ @@ -82,7 +79,7 @@ class FixPIMDLangevin : public Fix { int sizeplan; int *plansend, *planrecv; - tagint *tagsend, *tagrecv; + tagint *tagsend, *tagrecv; double **bufsend, **bufrecv, **bufbeads; double **bufsorted, **bufsortedall; double **outsorted, **buftransall; @@ -110,33 +107,34 @@ class FixPIMDLangevin : public Fix { double dtv, dtf, dtv2, dtv3; double gamma, c1, c2, tau; double *tau_k, *c1_k, *c2_k; - double pilescale=1.0; + double pilescale = 1.0; double Lan_temp; double r1, r2, r3; - double _omega_np, *_omega_k, *Lan_s, *Lan_c; // sin(omega_k*dt*0.5), cos(omega_k*dt*0.5) + double _omega_np, *_omega_k, *Lan_s, *Lan_c; // sin(omega_k*dt*0.5), cos(omega_k*dt*0.5) class RanMars *random; - int seed=975481; + int seed = 975481; FILE *frand; - int tstat_flag; // tstat_flat = 1 if thermostat if used + int tstat_flag; // tstat_flat = 1 if thermostat if used void Langevin_init(); - void b_step(); // integrate for dt/2 according to B part (v <- v + f * dt/2) - void a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) - void qc_step(); // integrate for dt/2 for the centroid mode (x <- x + v * dt/2) - void o_step(); // integrate for dt according to O part (O-U process, for thermostating) - + void b_step(); // integrate for dt/2 according to B part (v <- v + f * dt/2) + void + a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) + void qc_step(); // integrate for dt/2 for the centroid mode (x <- x + v * dt/2) + void o_step(); // integrate for dt according to O part (O-U process, for thermostating) + /* Bussi-Zykova-Parrinello barostat */ double f_omega, mtk_term1; - int pstat_flag; // pstat_flag = 1 if barostat is used - int pstyle; // pstyle = ISO or ANISO (will support TRICLINIC in the future) + int pstat_flag; // pstat_flag = 1 if barostat is used + int pstyle; // pstyle = ISO or ANISO (will support TRICLINIC in the future) double W, tau_p, Pext, totenthalpy = 0.0, Vcoeff; int p_flag[6]; - double vw[6]; // barostat velocity - double ke_tensor[6]; // kinetic energy tensor - double c_vir_tensor[6]; // centroid-virial tensor - double stress_tensor[6]; // path integral centroid-virial stress tensor + double vw[6]; // barostat velocity + double ke_tensor[6]; // kinetic energy tensor + double c_vir_tensor[6]; // centroid-virial tensor + double stress_tensor[6]; // path integral centroid-virial stress tensor void baro_init(); void press_v_step(); @@ -152,12 +150,12 @@ class FixPIMDLangevin : public Fix { // int n_unwrap; int maxunwrap; // int maxunwrap, nlocal_init; -// tagint *tag_init, *tag_initall; -// imageint *image_init, *image_initall; + // tagint *tag_init, *tag_initall; + // imageint *image_init, *image_initall; double **x_unwrap; -// double **x_unwrap, **x_unwrapsort; -// double **x_unwrapall; -// void init_x_unwrap(); + // double **x_unwrap, **x_unwrapsort; + // double **x_unwrapall; + // void init_x_unwrap(); void reallocate_x_unwrap(); void reallocate_xc(); void collect_xc(); @@ -178,22 +176,20 @@ class FixPIMDLangevin : public Fix { class Compute *c_pe; class Compute *c_press; - void compute_totke(); // 1: kinetic energy - void compute_spring_energy(); // 2: spring elastic energy - void compute_pote(); // 3: potential energy - void compute_tote(); // 4: total energy: 1+2+3 for all the beads + void compute_totke(); // 1: kinetic energy + void compute_spring_energy(); // 2: spring elastic energy + void compute_pote(); // 3: potential energy + void compute_tote(); // 4: total energy: 1+2+3 for all the beads // void compute_t_prim(); // 5: primitive kinetic energy estimator // void compute_p_prim(); // primitive pressure estimator void compute_stress_tensor(); // void compute_t_vir(); // centroid-virial kinetic energy estimator - void compute_p_cv(); // centroid-virial pressure estimator + void compute_p_cv(); // centroid-virial pressure estimator // void compute_p_vir(); // centroid-virial pressure estimator void compute_vir(); void compute_vir_(); void compute_totenthalpy(); }; - } // namespace LAMMPS_NS - #endif #endif From 0911565660831d554272900e6d140c5a3f46c170 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 25 Feb 2023 16:36:01 -0500 Subject: [PATCH 011/448] prepare for inclusion of fix pimd/langevin --- doc/src/Commands_fix.rst | 1 + doc/src/fix.rst | 3 +- doc/src/fix_pimd.rst | 70 ++++++++++++++++++++++------------------ src/.gitignore | 2 ++ 4 files changed, 44 insertions(+), 32 deletions(-) diff --git a/doc/src/Commands_fix.rst b/doc/src/Commands_fix.rst index d275b33eba..9c5b0d4a0f 100644 --- a/doc/src/Commands_fix.rst +++ b/doc/src/Commands_fix.rst @@ -168,6 +168,7 @@ OPT. * :doc:`pafi ` * :doc:`pair ` * :doc:`phonon ` + * :doc:`pimd/langevin ` * :doc:`pimd/nvt ` * :doc:`planeforce ` * :doc:`plumed ` diff --git a/doc/src/fix.rst b/doc/src/fix.rst index 2dfe97a3ec..6f9f29db25 100644 --- a/doc/src/fix.rst +++ b/doc/src/fix.rst @@ -320,7 +320,8 @@ accelerated styles exist. * :doc:`pafi ` - constrained force averages on hyper-planes to compute free energies (PAFI) * :doc:`pair ` - access per-atom info from pair styles * :doc:`phonon ` - calculate dynamical matrix from MD simulations -* :doc:`pimd/nvt ` - Feynman path integral molecular dynamics with Nose-Hoover thermostat +* :doc:`pimd/langevin ` - Feynman path-integral molecular dynamics with stochastic thermostat +* :doc:`pimd/nvt ` - Feynman path-integral molecular dynamics with Nose-Hoover thermostat * :doc:`planeforce ` - constrain atoms to move in a plane * :doc:`plumed ` - wrapper on PLUMED free energy library * :doc:`poems ` - constrain clusters of atoms to move as coupled rigid bodies diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 0a4f9a38fb..342530e6a9 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -1,17 +1,21 @@ +.. index:: fix pimd/langevin .. index:: fix pimd/nvt +fix pimd/langevin command +========================= + fix pimd/nvt command -================ +==================== Syntax """""" .. parsed-literal:: - fix ID group-ID pimd/nvt keyword value ... + fix ID group-ID style keyword value ... * ID, group-ID are documented in :doc:`fix ` command -* pimd/nvt = style name of this fix command +* style = *pimd/langevin* or *pimd/nvt* = style name of this fix command * zero or more keyword/value pairs may be appended * keyword = *method* or *fmass* or *sp* or *temp* or *nhc* @@ -35,14 +39,15 @@ Description .. versionchanged:: TBD -Fix pimd was renamed to fix pimd/nvt. +Fix pimd was renamed to fix *pimd/nvt* and fix *pimd/langevin* was added. -This command performs quantum molecular dynamics simulations based on -the Feynman path integral to include effects of tunneling and +These fix commands perform quantum molecular dynamics simulations based +on the Feynman path-integral to include effects of tunneling and zero-point motion. In this formalism, the isomorphism of a quantum partition function for the original system to a classical partition function for a ring-polymer system is exploited, to efficiently sample configurations from the canonical ensemble :ref:`(Feynman) `. + The classical partition function and its components are given by the following equations: @@ -53,27 +58,28 @@ by the following equations: V_{eff} = & \sum_{i=1}^P \bigg[ \frac{mP}{2\beta^2 \hbar^2} (q_i - q_{i+1})^2 + \frac{1}{P} V(q_i)\bigg] The interested user is referred to any of the numerous references on -this methodology, but briefly, each quantum particle in a path -integral simulation is represented by a ring-polymer of P quasi-beads, -labeled from 1 to P. During the simulation, each quasi-bead interacts -with beads on the other ring-polymers with the same imaginary time -index (the second term in the effective potential above). The -quasi-beads also interact with the two neighboring quasi-beads through -the spring potential in imaginary-time space (first term in effective -potential). To sample the canonical ensemble, a Nose-Hoover massive -chain thermostat is applied :ref:`(Tuckerman) `. With the -massive chain algorithm, a chain of NH thermostats is coupled to each -degree of freedom for each quasi-bead. The keyword *temp* sets the -target temperature for the system and the keyword *nhc* sets the -number *Nc* of thermostats in each chain. For example, for a -simulation of N particles with P beads in each ring-polymer, the total -number of NH thermostats would be 3 x N x P x Nc. +this methodology, but briefly, each quantum particle in a path integral +simulation is represented by a ring-polymer of P quasi-beads, labeled +from 1 to P. During the simulation, each quasi-bead interacts with +beads on the other ring-polymers with the same imaginary time index (the +second term in the effective potential above). The quasi-beads also +interact with the two neighboring quasi-beads through the spring +potential in imaginary-time space (first term in effective potential). +To sample the canonical ensemble, a Nose-Hoover massive chain thermostat +is applied :ref:`(Tuckerman) `. With the massive chain +algorithm, a chain of NH thermostats is coupled to each degree of +freedom for each quasi-bead. The keyword *temp* sets the target +temperature for the system and the keyword *nhc* sets the number *Nc* of +thermostats in each chain. For example, for a simulation of N particles +with P beads in each ring-polymer, the total number of NH thermostats +would be 3 x N x P x Nc. .. note:: - Fix pimd/nvt implements a complete velocity-verlet integrator + Fix *pimd/nvt* implements a complete velocity-verlet integrator combined with NH massive chain thermostat, so no other time integration fix should be used. + Similarly fix *pimd/langeving* implements ... The *method* keyword determines what style of PIMD is performed. A value of *pimd* is standard PIMD. A value of *nmpimd* is for @@ -158,16 +164,18 @@ related tasks for each of the partitions, e.g. Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" -Fix pimd/nvt writes the state of the Nose/Hoover thermostat over all +Fix *pimd/nvt* writes the state of the Nose/Hoover thermostat over all quasi-beads to :doc:`binary restart files `. See the :doc:`read_restart ` command for info on how to re-specify a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion. +Fix *pimd/langevin* ... + None of the :doc:`fix_modify ` options are relevant to fix pimd/nvt. -Fix pimd/nvt computes a global 3-vector, which can be accessed by +Fix *pimd/nvt* computes a global 3-vector, which can be accessed by various :doc:`output commands `. The three quantities in the global vector are: @@ -176,21 +184,21 @@ the global vector are: #. the current value of the scalar virial estimator for the kinetic energy of the quantum system :ref:`(Herman) `. -The vector values calculated by fix pimd/nvt are "extensive", except for the +The vector values calculated by fix *pimd/nvt* are "extensive", except for the temperature, which is "intensive". -No parameter of fix pimd/nvt can be used with the *start/stop* keywords -of the :doc:`run ` command. Fix pimd/nvt is not invoked during +No parameter of fix *pimd/nvt* can be used with the *start/stop* keywords +of the :doc:`run ` command. Fix *pimd/nvt* is not invoked during :doc:`energy minimization `. Restrictions """""""""""" -This fix is part of the REPLICA package. It is only enabled if LAMMPS -was built with that package. See the :doc:`Build package +These fixes are part of the REPLICA package. They are only enabled if +LAMMPS was built with that package. See the :doc:`Build package ` page for more info. -Fix pimd/nvt cannot be used with :doc:`lj units `. +Fix *pimd/nvt* cannot be used with :doc:`lj units `. A PIMD simulation can be initialized with a single data file read via the :doc:`read_data ` command. However, this means all @@ -207,7 +215,7 @@ variable, e.g. Default """"""" -The keyword defaults for fix pimd/nvt are method = pimd, fmass = 1.0, sp +The keyword defaults for fix *pimd/nvt* are method = pimd, fmass = 1.0, sp = 1.0, temp = 300.0, and nhc = 2. ---------- diff --git a/src/.gitignore b/src/.gitignore index 8f0f577a45..cbe9e76216 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1533,6 +1533,8 @@ /fix_mol_swap.h /fix_pimd.cpp /fix_pimd.h +/fix_pimd_langevin.cpp +/fix_pimd_langevin.h /fix_pimd_nvt.cpp /fix_pimd_nvt.h /fix_qbmsst.cpp From 00a5930d4c93bafe8f2cd8978ab5c5ddfc290ef2 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Sat, 25 Feb 2023 18:58:56 -0500 Subject: [PATCH 012/448] delete default seed --- src/REPLICA/fix_pimd_langevin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index cf2d63b91c..3af036caf9 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -113,7 +113,7 @@ class FixPIMDLangevin : public Fix { double _omega_np, *_omega_k, *Lan_s, *Lan_c; // sin(omega_k*dt*0.5), cos(omega_k*dt*0.5) class RanMars *random; - int seed = 975481; + int seed; FILE *frand; int tstat_flag; // tstat_flat = 1 if thermostat if used From c950df2ede6bc519ed5f63691bac9579855af715 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Sat, 25 Feb 2023 19:53:19 -0500 Subject: [PATCH 013/448] delete commented-out code --- src/REPLICA/fix_pimd_langevin.cpp | 271 ------------------------------ 1 file changed, 271 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 1b2e734922..d4e8648504 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -81,8 +81,6 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n bufbeads = nullptr; x_unwrap = xc = nullptr; xcall = nullptr; - // x_unwrap = x_unwrapsort = x_unwrapall = nullptr; - // tag_init = tag_initall = nullptr; counts = nullptr; sizeplan = 0; @@ -245,16 +243,11 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n /* Initiation */ int nlocal = atom->nlocal; - // xc = new double[nlocal*3]; - // x_unwrap = new double[nlocal*3]; global_freq = 1; vector_flag = 1; size_vector = 11; - // if(pstyle==ISO) {size_vector = 15;} - // else if(pstyle==ANISO) {size_vector = 23;} extvector = 1; - // comm_forward = 1; // some initilizations @@ -318,7 +311,6 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n if(atom->nmax > maxunwrap) reallocate_x_unwrap(); if(atom->nmax > maxxc) reallocate_xc(); memory->create(xcall, ntotal*3, "FixPIMDLangevin:xcall"); - // init_x_unwrap(); if (cmode == SINGLE_PROC) { @@ -331,21 +323,14 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n } if ((cmode == MULTI_PROC) && (counts == nullptr)) { - // printf("me = %d, creating bufrecvall\n", universe->me); memory->create(bufsendall,ntotal,3,"FixPIMDLangevin:bufsendall"); memory->create(bufrecvall,ntotal,3,"FixPIMDLangevin:bufrecvall"); - // printf("me = %d, bufrecvall[0][0] = %.4f\n", universe->me, bufrecvall[0][0]); memory->create(tagsendall,ntotal,"FixPIMDLangevin:tagsendall"); memory->create(tagrecvall,ntotal,"FixPIMDLangevin:tagrecvall"); - // printf("me = %d, tagrecvall[0] = %d\n", universe->me, tagrecvall[0]); memory->create(counts,nprocs,"FixPIMDLangevin:counts"); memory->create(displacements,nprocs,"FixPIMDLangevin:displacements"); - // memory->create(x_unwrapall, ntotal, 3, "FixPIMDLangevin:x_unwrapall"); - // memory->create(tag_initall, ntotal, "FixPIMDLangevin:tag_initall"); - // printf("me = %d, tag_initall[0] = %d\n", universe->me, tag_initall[0]); } - // printf("me = %d constructing finished\n", universe->me); } /* ---------------------------------------------------------------------- */ @@ -391,12 +376,8 @@ void FixPIMDLangevin::init() } else planck = force->hplanck; const double Planck = planck; - printf("planck = %.6e\n", planck); - // if(force->boltz == 1.0) { hbar = Planck; } - // else { hbar = Planck / (2.0 * MY_PI); } hbar = Planck / (2.0 * MY_PI); - // hbar = Planck; kBT = force->boltz * temp; double beta = 1.0 / (Boltzmann * temp); double _fbond = 1.0 * np * np / (beta * beta * hbar * hbar); @@ -404,7 +385,6 @@ void FixPIMDLangevin::init() omega_np = np / (hbar * beta) * sqrt(force->mvv2e); beta_np = 1.0 / force->boltz / temp / np; fbond = _fbond * force->mvv2e; - // printf("_fbond = %.16e\nfbond = %.16e\n", _fbond, fbond); if (universe->me == 0) printf("Fix pimd -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); @@ -458,35 +438,27 @@ void FixPIMDLangevin::setup(int vflag) double **x = atom->x; double **v = atom->v; imageint *image = atom->image; - // nlocal_init = nlocal; if(mapflag){ for(int i=0; iunmap(x[i], image[i]); } } - // printf("me = %d after unmapping x_unwrap\n", universe->me); - // printf("setup already here\n"); if(method==NMPIMD) { inter_replica_comm(x); - // printf("me = %d after inter\n", universe->me); - // printf("%.4f %.4f %.4f\n", bufbeads[0][0], bufbeads[0][1], bufbeads[0][2]); if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); } collect_xc(); - // printf("me = %d setup x2xp done\n", universe->me); compute_spring_energy(); if(method==NMPIMD) { inter_replica_comm(x); if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); - // nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); } - // printf("me = %d setup xp2x done\n", universe->me); if(mapflag){ for(int i=0; iiworld]); else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, v, M_x2xp[universe->iworld]); - // nmpimd_transform(bufbeads, atom->v, M_x2xp[universe->iworld]); } - // printf("me = %d setup v2vp done\n", universe->me); - // compute_xc(); - // update_x_unwrap(); - // printf("setting up %d\n", vflag); if(universe->me==0 && screen) fprintf(screen,"Setting up Path-Integral ...\n"); if(universe->me==0) printf("Setting up Path-Integral ...\n"); - // printf("setting up, m = %.4e\n", mass[1]); post_force(vflag); - // int idx = atom->map(1); - // printf("irplica = %d, x[1] = %.6f %.6f %.6f xu[1] = %.6f %.6f %.6f xc[1] = %.6f %.6f %.6f\n", ireplica, x[idx][0], x[idx][1], x[idx][2], x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xc[idx][0], xc[idx][1], xc[idx][2]); - // printf("after post_force, m = %.4e\n", mass[1]); - // printf("me = %d after post_force\n", universe->me); compute_totke(); - // compute_pote(); - // if(pstyle==ANISO) compute_stress_tensor(); end_of_step(); c_pe->addstep(update->ntimestep+1); c_press->addstep(update->ntimestep+1); - // printf("setup ending: \ncell = %.16e %.16e %.16e\nvol = %.16e\n", domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); - // printf("me = %d, setup finished\n", universe->me); } /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::initial_integrate(int /*vflag*/) { - // printf("step = %d start initial_integrate\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); - // printf("me = %d, step %d initial_integrate starts!\n", universe->me, update->ntimestep); - // printf("me = %d, step %d if starts!\n", universe->me, update->ntimestep); int nlocal = atom->nlocal; tagint *tag = atom->tag; double **x = atom->x; @@ -542,41 +497,28 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) } if(integrator==obabo) { - // printf("me = %d, step %d obabo starts!\n", universe->me, update->ntimestep); if(tstat_flag) { o_step(); - // if(removecomflag) remove_com_motion(); if(pstat_flag) press_o_step(); } if(pstat_flag) { compute_totke(); - // printf("me = %d, step %d after totke!\n", universe->me, update->ntimestep); compute_p_cv(); press_v_step(); } - /* - if(pstat_flag) - { - } - */ - // printf("me = %d, step %d before b_step 1!\n", universe->me, update->ntimestep); b_step(); - // printf("me = %d, step %d after b_step 1!\n", universe->me, update->ntimestep); - // if(removecomflag) remove_com_motion(); if(method==NMPIMD) { inter_replica_comm(x); if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); - // nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); } qc_step(); a_step(); qc_step(); a_step(); - // printf("me = %d, step %d after 2 a_step's!\n", universe->me, update->ntimestep); } else if(integrator==baoab) { @@ -587,20 +529,17 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) press_v_step(); } b_step(); - // if(removecomflag) remove_com_motion(); if(method==NMPIMD) { inter_replica_comm(x); if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); - // nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); } qc_step(); a_step(); if(tstat_flag) { o_step(); - // if(removecomflag) remove_com_motion(); if(pstat_flag) press_o_step(); } qc_step(); @@ -618,7 +557,6 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) inter_replica_comm(x); if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); - // nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); } @@ -628,8 +566,6 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) domain->unmap_inv(x[i], image[i]); } } - // printf("step = %d\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); - // printf("me = %d, step %d initial_integrate ends!\n", universe->me, update->ntimestep); } /* ---------------------------------------------------------------------- */ @@ -643,13 +579,11 @@ void FixPIMDLangevin::final_integrate() press_v_step(); } b_step(); - // if(removecomflag) remove_com_motion(); if(integrator==obabo) { if(tstat_flag) { o_step(); - // if(removecomflag) remove_com_motion(); if(pstat_flag) press_o_step(); } } @@ -667,10 +601,8 @@ void FixPIMDLangevin::final_integrate() void FixPIMDLangevin::post_force(int /*flag*/) { - // printf("step = %d\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); if(atom->nmax > maxunwrap) reallocate_x_unwrap(); if(atom->nmax > maxxc) reallocate_xc(); - // printf("me = %d, step %d post_force starts!\n", universe->me, update->ntimestep); int nlocal = atom->nlocal; double **x = atom->x; double **f = atom->f; @@ -695,34 +627,17 @@ void FixPIMDLangevin::post_force(int /*flag*/) xc[i][2] = xcall[3*(tag[i]-1)+2]; } int idx = atom->map(1); - // printf("in post_force, x_unwrap: %.6f %.6f %.6f xcall: %.6f %.6f %.6f xc: %.6f %.6f %.6f\n", x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xcall[0], xcall[1], xcall[2], xc[idx][0], xc[idx][1], xc[idx][2]); - // MPI_Barrier(universe->uworld); - // update_x_unwrap(); - // MPI_Barrier(universe->uworld); - // compute_xc(); - // MPI_Barrier(universe->uworld); - // if(mapflag) - // { - // for(int i=0; iunmap_inv(x[i], image[i]); - // } - // } compute_vir(); compute_vir_(); - // compute_t_prim(); - // compute_t_vir(); compute_pote(); if(method==NMPIMD) { inter_replica_comm(f); if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, f, M_x2xp[universe->iworld]); else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); - // nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); } c_pe->addstep(update->ntimestep+1); c_press->addstep(update->ntimestep+1); - // printf("me = %d, step %d post_force ends!\n", universe->me, update->ntimestep); } /* ---------------------------------------------------------------------- */ @@ -730,8 +645,6 @@ void FixPIMDLangevin::post_force(int /*flag*/) void FixPIMDLangevin::end_of_step() { compute_totke(); - // inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); - // compute_p_prim(); compute_p_cv(); compute_tote(); if(pstat_flag) compute_totenthalpy(); @@ -740,8 +653,6 @@ void FixPIMDLangevin::end_of_step() { if(universe->me==0) printf("This is the end of step %ld.\n", update->ntimestep); } - // if(universe->me==0) printf("me = %d This is the end of step %ld.\n", universe->me, update->ntimestep); - // printf("me = %d This is the end of step %ld.\n\n", universe->me, update->ntimestep); } void FixPIMDLangevin::collect_xc() @@ -773,74 +684,15 @@ void FixPIMDLangevin::collect_xc() xcall[3*(tag[i]-1)+2] = x[i][2] / sqrt(np); } int idx = atom->map(1); - // printf("in init_int, x: %.6f %.6f %.6f xcall: %.6f %.6f %.6f\n", x[idx][0], x[idx][1], x[idx][2], xcall[0], xcall[1], xcall[2]); if(cmode == MULTI_PROC) { - // printf("trying to add\n"); - // MPI_Reduce(MPI_IN_PLACE, xcall, ntotal*3, MPI_DOUBLE, MPI_SUM, 0, world); MPI_Allreduce(MPI_IN_PLACE, xcall, ntotal*3, MPI_DOUBLE, MPI_SUM, world); - // printf("added\n"); } } MPI_Bcast(xcall, ntotal*3, MPI_DOUBLE, 0, universe->uworld); } -/* ---------------------------------------------------------------------- */ -/* -void FixPIMDLangevin::update_x_unwrap() -{ - // MPI_Barrier(universe->uworld); - // printf("me = %d, starting update_xu\n", universe->me); - int nlocal = atom->nlocal; - double **x = atom->x; - // delete x_unwrap; - // memory->sfree(x_unwrap); - // printf("me = %d, before deleting xu\n", universe->me); - delete [] x_unwrap; - x_unwrap = nullptr; - x_unwrap = (double*) memory->srealloc(x_unwrap, sizeof(double)*(nlocal+200)*3, "FixDPPimd::x_unwrap"); - // printf("me = %d, before newing xu\n", universe->me); - // x_unwrap = new double[nlocal*3]; - // printf("me = %d, doing xu\n", universe->me); - for(int i=0; ime); - // MPI_Barrier(universe->uworld); -} -*/ -/* ---------------------------------------------------------------------- */ -/* -void FixPIMDLangevin::compute_xc() -{ - int natoms = atom->natoms; - MPI_Barrier(universe->uworld); - comm_exec(atom->x); - MPI_Barrier(universe->uworld); - int nlocal = atom->nlocal; - delete [] xc; - xc = nullptr; - xc = (double*) memory->srealloc(xc, sizeof(double) * nlocal * 3, "FixDPPimd:xc"); - for(int i=0; intimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); if(universe->iworld == 0) { double expp[3], expq[3]; - // printf("pstyle = %d vw[0] = %.8e\n", pstyle, vw[0]); if(pstyle == ISO) {vw[1] = vw[0]; vw[2] = vw[0];} for(int j=0; j<3; j++) { @@ -926,7 +776,6 @@ void FixPIMDLangevin::qc_step(){ domain->set_local_box(); } volume = domain->xprd * domain->yprd * domain->zprd; - // printf("step = %d end qc_step\ncell = %.16e %.16e %.16e\nvol = %.16e\n", update->ntimestep, domain->xprd, domain->yprd, domain->zprd, domain->xprd * domain->yprd * domain->zprd); } /* ---------------------------------------------------------------------- */ @@ -939,7 +788,6 @@ void FixPIMDLangevin::a_step(){ if(universe->iworld != 0) { - // printf("iworld = %d c = %.4e s = %.4e w = %.4e\n", universe->iworld, Lan_c[universe->iworld], Lan_s[universe->iworld], _omega_k[universe->iworld]); for(int i=0; iiworld == 0) - { - // double **x = atom->x; - double **v = atom->v; - int *mask = atom->mask; - int nlocal = atom->nlocal; - if (dynamic) masstotal = group->mass(igroup); - double vcm[3]; - group->vcm(igroup,masstotal,vcm); - for (int i = 0; i < nlocal; i++) { - if (mask[i] & groupbit) { - v[i][0] -= vcm[0]; - v[i][1] -= vcm[1]; - v[i][2] -= vcm[2]; - } - } - } -} -*/ /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::baro_init() { vw[0] = vw[1] = vw[2] = vw[3] = vw[4] = vw[5] = 0.0; if(pstyle == ISO) {W = 3 * (atom->natoms) * tau_p * tau_p * np * kBT;} // consistent with the definition in i-Pi - // printf("tau_p = %.6e np = %.6e kBT = %.6e W = %.6e\n", tau_p, np, kBT, W);} else if(pstyle == ANISO) {W = atom->natoms * tau_p * tau_p * np * kBT;} Vcoeff = 1.0; std::string out = fmt::format("\nInitializing PIMD {:s} barostat...\n", Barostats[barostat]); @@ -1006,9 +831,7 @@ void FixPIMDLangevin::press_v_step() { if(barostat == BZP) { - // printf("me = %d step = %d start press_v_step, baro.p = %.30e p_cv = %.30e\n", universe->me, update->ntimestep, W*vw[0], np*p_cv); vw[0] += dtv * 3 * (volume * np * (p_cv - Pext) / force->nktv2p + Vcoeff / beta_np) / W; - // printf("me = %d step = %d add p-Pext, baro.p = %.30e\n", universe->me, update->ntimestep, W*vw[0]); if(universe->iworld==0) { double dvw_proc = 0.0, dvw = 0.0; @@ -1024,7 +847,6 @@ void FixPIMDLangevin::press_v_step() } MPI_Barrier(universe->uworld); MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); - // printf("me = %d step = %d end press_v_step, baro.p = %.30e\n\n", universe->me, update->ntimestep, W*vw[0]); } else if(barostat == MTTK) { @@ -1087,11 +909,9 @@ void FixPIMDLangevin::press_o_step() void FixPIMDLangevin::Langevin_init() { - // printf("in Langevin_init\n"); double beta = 1.0 / kBT; _omega_np = np / beta / hbar; double _omega_np_dt_half = _omega_np * update->dt * 0.5; - // printf("omega_np = %.4e wdt = %.4e\n", _omega_np, _omega_np_dt_half); _omega_k = new double[np]; Lan_c = new double[np]; @@ -1102,7 +922,6 @@ void FixPIMDLangevin::Langevin_init() _omega_k[i] = _omega_np * sqrt(lam[i]); Lan_c[i] = cos(sqrt(lam[i])*_omega_np_dt_half); Lan_s[i] = sin(sqrt(lam[i])*_omega_np_dt_half); - // printf("lam = %.4e s = %.4e c = %.4e w = %.4e\n", lam[i], Lan_s[i], Lan_c[i], _omega_k[i]); } } else if(fmmode==normal){ @@ -1292,24 +1111,8 @@ void FixPIMDLangevin::comm_init() planrecv[i] = universe->root_proc[irecv]; modeindex[i] = irecv; } - // } } -/* ---------------------------------------------------------------------- */ -/* -void FixPIMDLangevin::init_x_unwrap() -{ - maxunwrap = atom->nmax; - memory->destroy(x_unwrap); - memory->destroy(tag_init); - memory->destroy(image_init); - memory->destroy(x_unwrapsort); - memory->create(x_unwrap, maxunwrap, 3, "FixPIMDLangevin:x_unwrap"); - memory->create(tag_init, maxunwrap, "FixPIMDLangevin:tag_init"); - memory->create(image_init, maxunwrap, "FixPIMDLangevin:image_init"); - memory->create(x_unwrapsort, ntotal, 3, "FixPIMDLangevin:x_unwrapsort"); -} -*/ /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::reallocate_xc() @@ -1353,7 +1156,6 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) MPI_Status statuses[2]; if (atom->nmax > maxlocal) reallocate(); int nlocal = atom->nlocal; - // printf("me = %d starting inter_comm, nlocal = %d ntotal = %d\n", universe->me, nlocal, ntotal); tagint *tag = atom->tag; int i, m; @@ -1382,43 +1184,10 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) displacements[0] = 0; for (i = 0; i < nreplica-1; i++) { displacements[i+1] = displacements[i] + counts[i]; } MPI_Allgatherv(bufsorted[0], 3*m, MPI_DOUBLE, bufsortedall[0], counts, displacements, MPI_DOUBLE, universe->uworld); - // printf("me = %d bufsortedall[0] = %.8f %.8f %.8f bufsortedall[ntotal] = %.8f %.8f %.8f\n", universe->iworld, bufsortedall[0][0], bufsortedall[0][1], bufsortedall[0][2], bufsortedall[ntotal][0], bufsortedall[ntotal][1], bufsortedall[ntotal][2]); - /* - m = 0; - for(i=0; ime, nlocal, ntotal, m, sizeplan); - for(int iplan=0; iplanuworld, &requests[0]); - MPI_Irecv(tagrecv, ntotal, MPI_LMP_TAGINT, planrecv[iplan], 0, universe->uworld, &requests[1]); - // printf("me = %d iplan = %d irecv finished, plansend = %d, planrecv = %d, modeindex = %d\n", universe->me, iplan, plansend[iplan], planrecv[iplan], modeindex[iplan]); - // printf("bufsend[0]: %.4f %.4f %.4f\ntagsend[0]: %d\n", bufsend[0][0], bufsend[0][1], bufsend[0][2], tagsend[0]); - // printf("bufsend[255]: %.4f %.4f %.4f\ntagsend[255]: %d\n", bufsend[255][0], bufsend[255][1], bufsend[255][2], tagsend[255]); - MPI_Send(bufsend[0], 3*ntotal, MPI_DOUBLE, plansend[iplan], 0, universe->uworld); - MPI_Send(tagsend, ntotal, MPI_LMP_TAGINT, plansend[iplan], 0, universe->uworld); - // printf("me = %d MPI_Send done\n", universe->me); - MPI_Waitall(2, requests, statuses); - // printf("me = %d iplan = %d send recv finished\n", iplan, universe->me); - for(i=0; imap(tagrecv[i]); - bufbeads[modeindex[iplan]][3*m+0] = bufrecv[i][0]; - bufbeads[modeindex[iplan]][3*m+1] = bufrecv[i][1]; - bufbeads[modeindex[iplan]][3*m+2] = bufrecv[i][2]; - } - } - */ - // printf("me = %d finishing inter_comm\n", universe->me); } else if(cmode == MULTI_PROC) { m = 0; - // printf("me = %d trying to copy bufsend\n", universe->me); for(i=0; ime, m); - // if(me==0) {for(i=0; ime, i, counts[i]);}} - // printf("me = %d") MPI_Gather(&m, 1, MPI_INT, counts, 1, MPI_INT, 0, world); - // printf("me = %d counts gathered\n", universe->me); - // if(me==0) {for(i=0; ime, i, counts[i]);}} displacements[0] = 0; - // printf("me = %d displacements[0] = %d\n", universe->me, displacements[0]); for (i = 0; i < nprocs-1; i++) { displacements[i+1] = displacements[i] + counts[i]; } - // printf("me = %d displacements done\n", universe->me); - // if(me==0) {for(i=0; ime, i, displacements[i]);}} MPI_Gatherv(tagsend, m, MPI_LMP_TAGINT, tagsendall, counts, displacements, MPI_LMP_TAGINT, 0, world); - // printf("me = %d tags gathered\n", universe->me); for (i = 0; i < nprocs; i++) { counts[i] *= 3; } for (i = 0; i < nprocs-1; i++) { displacements[i+1] = displacements[i] + counts[i]; } MPI_Gatherv(bufsend[0], 3*m, MPI_DOUBLE, bufsendall[0], counts, displacements, MPI_DOUBLE, 0, world); - // printf("me = %d bufsend gathered\n", universe->me); - // printf("me = %d, tagrecvall[0] = %d bufrecvall[0][0] = %.4f\n", universe->me, tagrecvall[0], bufrecvall[0][0]); - - // printf("universe->me = %d comm->me = %d sizeplan = %d\n", universe->me, comm->me, sizeplan); for(int iplan=0; iplanuworld); MPI_Waitall(2,requests,statuses); } - // else{ - // printf("me = %d not sendrecceving\n", universe->me); - // } - - // printf("me = %d sendrecv finished\n", universe->me); - // printf("me = %d to be bcasted: tag[0] = %d bufrecvall[0][0] = %.4f\n", universe->me, tagrecvall[0], bufrecvall[0][0]); MPI_Bcast(tagrecvall, ntotal, MPI_LMP_TAGINT, 0, world); MPI_Bcast(bufrecvall[0], 3*ntotal, MPI_DOUBLE, 0, world); - // printf("me = %d broadcasted\n", universe->me); for(i=0; imap(tagrecvall[i]); @@ -1474,7 +1223,6 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) bufbeads[modeindex[iplan]][3*m+2] = bufrecvall[i][2]; } } - // printf("me = %d, tag[0] = %d bufrecvall[0][0] = %.4f bufbeads[0][0] = %.4f bufbeads[1][0] = %.4f bufbeads done\n", universe->me, tag[0], bufrecvall[0][0], bufbeads[0][0], bufbeads[1][0]); } } @@ -1486,8 +1234,6 @@ void FixPIMDLangevin::compute_vir_() int nlocal = atom->nlocal; xf = vir_ = xcf = centroid_vir = 0.0; int idx = atom->map(1); - // printf("in post_force, x_unwrap: %.6f %.6f %.6f xcall: %.6f %.6f %.6f\n", x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xcall[0], xcall[1], xcall[2]); - // printf("in compute_vir, xu = %.6f %.6f %.6f xc = %.6f %.6f %.6f\n", x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xc[idx][0], xc[idx][1], xc[idx][2]); for(int i=0; if[i][j]; xcf += (x_unwrap[i][j] - xc[i][j]) * atom->f[i][j]; } - // int idx = atom->map(i+1); - // printf("me = %d step = %d tag = %d idx = %d xu = %.6f %.6f %.6f xc = %.6f %.6f %.6f f = %.6f %.6f %.6f\n", universe->me, update->ntimestep, i+1, idx, x_unwrap[idx][0], x_unwrap[idx][1], x_unwrap[idx][2], xc[idx][0], xc[idx][1], xc[idx][2], atom->f[idx][0], atom->f[idx][1], atom->f[idx][2]); } MPI_Allreduce(&xf, &vir_, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); MPI_Allreduce(&xcf, ¢roid_vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); @@ -1530,7 +1274,6 @@ void FixPIMDLangevin::compute_vir() double vir_bead=(virial[0]+virial[1]+virial[2]); MPI_Allreduce(&vir_bead, &vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); MPI_Allreduce(MPI_IN_PLACE, &virial[0], 6, MPI_DOUBLE, MPI_SUM, universe->uworld); - // printf("me = %d step = %d vir = %.30e\n", universe->me, update->ntimestep, vir); } /* ---------------------------------------------------------------------- */ @@ -1550,12 +1293,10 @@ void FixPIMDLangevin::compute_stress_tensor() ke_tensor[4] += 0.5 * mass[type[i]] * atom->v[i][0] * atom->v[i][2] * force->mvv2e; ke_tensor[5] += 0.5 * mass[type[i]] * atom->v[i][1] * atom->v[i][2] * force->mvv2e; } - // MPI_Allreduce(&ke_tensor, &ke_tensor, 6, MPI_DOUBLE, MPI_SUM, world); MPI_Allreduce(MPI_IN_PLACE, &ke_tensor, 6, MPI_DOUBLE, MPI_SUM, world); for(int i=0; i<6; i++) { stress_tensor[i] = inv_volume * ((2*ke_tensor[i] - c_vir_tensor[i]) * force->nktv2p + virial[i]) / np; - // printf("i = %d, c_vir = %.6f, virial = %.6f stress = %.6f\n", i, c_vir_tensor[i], virial[i], stress_tensor[i]); } } MPI_Bcast(&stress_tensor, 6, MPI_DOUBLE, 0, universe->uworld); @@ -1577,12 +1318,7 @@ void FixPIMDLangevin::compute_totke() } } kine *= force->mvv2e; - // printf("me = %d, kine = %.6e\n", universe->me, kine); MPI_Allreduce(&kine, &ke_bead, 1, MPI_DOUBLE, MPI_SUM, world); - // MPI_Allreduce(&kine, &totke, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); - // totke *= force->mvv2e / np; - - // c_press->compute_scalar(); } /* ---------------------------------------------------------------------- */ @@ -1596,15 +1332,12 @@ void FixPIMDLangevin::compute_spring_energy() double* _mass = atom->mass; int* type = atom->type; int nlocal = atom->nlocal; - // printf("iworld = %d, fbond = %.4e lam = %.4e\n", universe->iworld, fbond, lam[universe->iworld]); for(int i=0; iiworld] * (x[i][0]*x[i][0] + x[i][1]*x[i][1] + x[i][2]*x[i][2]); } MPI_Allreduce(&spring_energy, &se_bead, 1, MPI_DOUBLE, MPI_SUM, world); - // MPI_Allreduce(&spring_energy, &total_spring_energy, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); - // total_spring_energy /= np; } /* ---------------------------------------------------------------------- */ @@ -1617,8 +1350,6 @@ void FixPIMDLangevin::compute_pote() c_pe->compute_scalar(); pe_bead = c_pe->scalar; pot_energy_partition = pe_bead / universe->procs_per_world[universe->iworld]; - // MPI_Allreduce(&pot_energy_partition, &pote, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); - // pote /= np; } /* ---------------------------------------------------------------------- */ @@ -1656,8 +1387,6 @@ void FixPIMDLangevin::compute_p_prim() void FixPIMDLangevin::compute_p_cv() { inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); - // p_md = 2. / 3 * inv_volume * ((totke - total_spring_energy) * force->nktv2p + 0.5 * vir / np) ; - // printf("inv_V = %.30e ke = %.30e cv = %.30e vir = %.30e\n", inv_volume, ke_bead, centroid_vir, vir); if(universe->iworld == 0) { p_cv = 1. / 3. * inv_volume * ((2. * ke_bead - 1. * centroid_vir) * force->nktv2p + 1. * vir) / np; From f84765f29e5f3f5236db7b583532fb1a5f4ac916 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Sat, 25 Feb 2023 20:34:10 -0500 Subject: [PATCH 014/448] update document for fix pimd/langevin --- doc/src/fix_pimd.rst | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 342530e6a9..4d08497928 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -17,16 +17,29 @@ Syntax * ID, group-ID are documented in :doc:`fix ` command * style = *pimd/langevin* or *pimd/nvt* = style name of this fix command * zero or more keyword/value pairs may be appended -* keyword = *method* or *fmass* or *sp* or *temp* or *nhc* +* keywords for style *pimd/nvt* .. parsed-literal:: - + *keywords* = *method* or *fmass* or *sp* or *temp* or *nhc* *method* value = *pimd* or *nmpimd* or *cmd* *fmass* value = scaling factor on mass *sp* value = scaling factor on Planck constant *temp* value = temperature (temperarate units) *nhc* value = Nc = number of chains in Nose-Hoover thermostat +* keywords for style *pimd/langevin* + + .. parsed-literal:: + *keywords* = *method* or *integrator* or *ensemble* or *fmass* or *fmmode* or *scale* or *lj* or *temp* or *thermostat* or *tau* or *press* or *barostat* or *taup* or *iso* or *aniso* + *method* value = *nmpimd* + *fmass* value = scaling factor on mass + *sp* value = scaling factor on Planck constant + *temp* value = target temperature (temperarate units) + *thermostat* values = PILE_L *seed* + *seed* = random number seed + *tau* value = thermostat damping parameter (time unit) + *press* value = target pressure (pressure units) + Examples """""""" From 25a1996ece081752364cfca146ac0a74d8b9a699 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 25 Feb 2023 22:40:30 -0500 Subject: [PATCH 015/448] some formatting and programming style updates --- src/REPLICA/fix_pimd_langevin.cpp | 1209 ++++++++++++++--------------- src/REPLICA/fix_pimd_langevin.h | 5 +- 2 files changed, 569 insertions(+), 645 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index d4e8648504..22bed54c3b 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -14,13 +14,7 @@ /* ---------------------------------------------------------------------- Package FixPIMDLangevin Purpose Quantum Path Integral Algorithm for Quantum Chemistry - Copyright Voth Group @ University of Chicago - Authors Chris Knight & Yuxing Peng (yuxing at uchicago.edu) - Updated Oct-01-2011 - Version 1.0 - - Updated Jun-07-2022 Yifan Li @ Princeton University (yifanl0716@gmail.com) Added components: - Multi-processor parallelism for each bead @@ -45,8 +39,8 @@ #include "modify.h" #include "random_mars.h" #include "universe.h" -#include "utils.h" #include "update.h" +#include "utils.h" #include #include @@ -56,19 +50,22 @@ using namespace FixConst; using namespace MathConst; enum { PIMD, NMPIMD, CMD }; -enum { physical, normal }; -enum { baoab, obabo }; +enum { PHYSICAL, NORMAL }; +enum { BAOAB, OBABO }; enum { ISO, ANISO, TRICLINIC }; enum { PILE_L }; enum { MTTK, BZP }; // char* Barostats[] = {"MTTK", "BZP"}; -std::map Barostats {{MTTK, "MTTK"}, {BZP, "BZP"}}; -enum { nve, nvt, nph, npt }; -enum{SINGLE_PROC, MULTI_PROC}; + +static std::map Barostats{{MTTK, "MTTK"}, {BZP, "BZP"}}; +enum { NVE, NVT, NPH, NPT }; +enum { SINGLE_PROC, MULTI_PROC }; /* ---------------------------------------------------------------------- */ -FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) { +FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : + Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) +{ time_integrate = 1; tagsend = tagrecv = nullptr; bufsend = bufrecv = nullptr; @@ -93,24 +90,24 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n mass = nullptr; method = PIMD; - ensemble = nvt; - integrator = obabo; + ensemble = NVT; + integrator = OBABO; thermostat = PILE_L; barostat = BZP; fmass = 1.0; sp = 1.0; - temp = 298.15; - Lan_temp = 298.15; - tau = 1.0; - tau_p = 1.0; - Pext = 1.0; - tstat_flag = 1; - pstat_flag = 0; - mapflag = 1; + temp = 298.15; + Lan_temp = 298.15; + tau = 1.0; + tau_p = 1.0; + Pext = 1.0; + tstat_flag = 1; + pstat_flag = 0; + mapflag = 1; removecomflag = 1; - fmmode = physical; - pstyle = ISO; - for (int i=0; i<6; i++) p_flag[i] = 0; + fmmode = PHYSICAL; + pstyle = ISO; + for (int i = 0; i < 6; i++) p_flag[i] = 0; for (int i = 3; i < narg - 1; i += 2) { if (strcmp(arg[i], "method") == 0) { @@ -121,129 +118,138 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n else if (strcmp(arg[i + 1], "cmd") == 0) method = CMD; else - error->universe_all(FLERR, "Unknown method parameter for fix pimd"); - } - else if(strcmp(arg[i], "integrator")==0) + error->universe_all(FLERR, "Unknown method parameter for fix pimd/langevin"); + } else if (strcmp(arg[i], "integrator") == 0) { - if(strcmp(arg[i+1], "obabo")==0) integrator=obabo; - else if(strcmp(arg[i+1], "baoab")==0) integrator=baoab; - else error->universe_all(FLERR, "Unknown integrator parameter for fix pimd. Only obabo and baoab integrators are supported!"); + if (strcmp(arg[i + 1], "obabo") == 0) + integrator = OBABO; + else if (strcmp(arg[i + 1], "baoab") == 0) + integrator = BAOAB; + else + error->universe_all(FLERR, + "Unknown integrator parameter for fix pimd/langevin. Only obabo and baoab " + "integrators are supported!"); } - else if(strcmp(arg[i], "ensemble")==0) - { - if(strcmp(arg[i+1], "nve")==0) { ensemble = nve; tstat_flag = 0; pstat_flag = 0; } - else if(strcmp(arg[i+1], "nvt")==0) { ensemble = nvt; tstat_flag = 1; pstat_flag = 0; } - else if(strcmp(arg[i+1], "nph")==0) { ensemble = nph; tstat_flag = 0; pstat_flag = 1; } - else if(strcmp(arg[i+1], "npt")==0) { ensemble = npt; tstat_flag = 1; pstat_flag = 1; } - else error->universe_all(FLERR, "Unknown ensemble parameter for fix pimd. Only nve and nvt ensembles are supported!"); + else if (strcmp(arg[i], "ensemble") == 0) { + if (strcmp(arg[i + 1], "nve") == 0) { + ensemble = NVE; + tstat_flag = 0; + pstat_flag = 0; + } else if (strcmp(arg[i + 1], "nvt") == 0) { + ensemble = NVT; + tstat_flag = 1; + pstat_flag = 0; + } else if (strcmp(arg[i + 1], "nph") == 0) { + ensemble = NPH; + tstat_flag = 0; + pstat_flag = 1; + } else if (strcmp(arg[i + 1], "npt") == 0) { + ensemble = NPT; + tstat_flag = 1; + pstat_flag = 1; + } else + error->universe_all( + FLERR, + "Unknown ensemble parameter for fix pimd/langevin. Only nve and nvt ensembles are supported!"); } - else if (strcmp(arg[i], "fmass") == 0) { + else if (strcmp(arg[i], "fmass") == 0) { fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); if (fmass < 0.0 || fmass > 1.0) - error->universe_all(FLERR, "Invalid fmass value for fix pimd"); + error->universe_all(FLERR, "Invalid fmass value for fix pimd/langevin"); } - else if(strcmp(arg[i], "fmmode")==0) - { - if(strcmp(arg[i+1], "physical")==0) fmmode=physical; - else if(strcmp(arg[i+1], "normal")==0) fmmode=normal; - else error->universe_all(FLERR, "Unknown fictitious mass mode for fix pimd. Only physical mass and normal mode mass are supported!"); + else if (strcmp(arg[i], "fmmode") == 0) { + if (strcmp(arg[i + 1], "physical") == 0) + fmmode = PHYSICAL; + else if (strcmp(arg[i + 1], "normal") == 0) + fmmode = NORMAL; + else + error->universe_all(FLERR, + "Unknown fictitious mass mode for fix pimd/langevin. Only physical mass and " + "normal mode mass are supported!"); } - else if(strcmp(arg[i],"scale")==0) - { - pilescale = atof(arg[i+1]); - if(pilescale<0.0) error->universe_all(FLERR,"Invalid pile scale value for fix pimd"); + else if (strcmp(arg[i], "scale") == 0) { + pilescale = atof(arg[i + 1]); + if (pilescale < 0.0) error->universe_all(FLERR, "Invalid pile scale value for fix pimd/langevin"); } else if (strcmp(arg[i], "temp") == 0) { temp = utils::numeric(FLERR, arg[i + 1], false, lmp); - if (temp < 0.0) error->universe_all(FLERR, "Invalid temp value for fix pimd"); + if (temp < 0.0) error->universe_all(FLERR, "Invalid temp value for fix pimd/langevin"); } else if (strcmp(arg[i], "lj") == 0) { - lj_epsilon = utils::numeric(FLERR, arg[i+1], false, lmp); - lj_sigma = utils::numeric(FLERR, arg[i+2], false, lmp); - lj_mass = utils::numeric(FLERR, arg[i+3], false, lmp); - other_planck = utils::numeric(FLERR, arg[i+4], false, lmp); + lj_epsilon = utils::numeric(FLERR, arg[i + 1], false, lmp); + lj_sigma = utils::numeric(FLERR, arg[i + 2], false, lmp); + lj_mass = utils::numeric(FLERR, arg[i + 3], false, lmp); + other_planck = utils::numeric(FLERR, arg[i + 4], false, lmp); i++; i++; i++; } - else if(strcmp(arg[i], "thermostat")==0) - { - if(strcmp(arg[i+1],"PILE_L")==0) - { + else if (strcmp(arg[i], "thermostat") == 0) { + if (strcmp(arg[i + 1], "PILE_L") == 0) { thermostat = PILE_L; - seed = atoi(arg[i+2]); + seed = atoi(arg[i + 2]); i++; } } - else if(strcmp(arg[i], "tau")==0) - { - tau = atof(arg[i+1]); + else if (strcmp(arg[i], "tau") == 0) { + tau = atof(arg[i + 1]); } - else if(strcmp(arg[i], "press")==0) - { - Pext = atof(arg[i+1]); - if(Pext<0.0) error->universe_all(FLERR,"Invalid press value for fix pimd"); + else if (strcmp(arg[i], "press") == 0) { + Pext = atof(arg[i + 1]); + if (Pext < 0.0) error->universe_all(FLERR, "Invalid press value for fix pimd/langevin"); } - else if(strcmp(arg[i], "barostat")==0) - { - if(strcmp(arg[i+1],"MTTK")==0) - { + else if (strcmp(arg[i], "barostat") == 0) { + if (strcmp(arg[i + 1], "MTTK") == 0) { barostat = MTTK; - } - else if(strcmp(arg[i+1],"BZP")==0) - { + } else if (strcmp(arg[i + 1], "BZP") == 0) { barostat = BZP; - } - else error->universe_all(FLERR,"Unknown barostat parameter for fix pimd"); + } else + error->universe_all(FLERR, "Unknown barostat parameter for fix pimd/langevin"); } - else if(strcmp(arg[i], "iso")==0) - { + else if (strcmp(arg[i], "iso") == 0) { pstyle = ISO; i--; } - else if(strcmp(arg[i], "aniso")==0) - { + else if (strcmp(arg[i], "aniso") == 0) { pstyle = ANISO; i--; } - else if(strcmp(arg[i], "taup")==0) - { - tau_p = atof(arg[i+1]); - if(tau_p<=0.0) error->universe_all(FLERR, "Invalid tau_p value for fix pimd"); - } - else if(strcmp(arg[i], "fixcom")==0) - { - if(strcmp(arg[i+1], "yes")==0) removecomflag = 1; - else if(strcmp(arg[i+1], "no")==0) removecomflag = 0; + else if (strcmp(arg[i], "taup") == 0) { + tau_p = atof(arg[i + 1]); + if (tau_p <= 0.0) error->universe_all(FLERR, "Invalid tau_p value for fix pimd/langevin"); + } else if (strcmp(arg[i], "fixcom") == 0) { + if (strcmp(arg[i + 1], "yes") == 0) + removecomflag = 1; + else if (strcmp(arg[i + 1], "no") == 0) + removecomflag = 0; } - else if(strcmp(arg[i], "map")==0) - { - if(strcmp(arg[i+1], "yes")==0) mapflag = 1; - else if(strcmp(arg[i+1], "no")==0) mapflag = 0; + else if (strcmp(arg[i], "map") == 0) { + if (strcmp(arg[i + 1], "yes") == 0) + mapflag = 1; + else if (strcmp(arg[i + 1], "no") == 0) + mapflag = 0; + } else { + error->universe_all(FLERR, fmt::format("Unknown keyword {} for fix {}", arg[i], style)); } - - else error->universe_all(FLERR, fmt::format("Unknown keyword {} for fix pimd", arg[i])); } /* Initiation */ - int nlocal = atom->nlocal; - global_freq = 1; vector_flag = 1; size_vector = 11; @@ -253,92 +259,87 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, n id_pe = new char[8]; strcpy(id_pe, "pimd_pe"); - char **newarg = new char*[3]; + char **newarg = new char *[3]; newarg[0] = id_pe; newarg[1] = (char *) "all"; newarg[2] = (char *) "pe"; - modify->add_compute(3,newarg); - delete [] newarg; - + modify->add_compute(3, newarg); + delete[] newarg; id_press = new char[12]; strcpy(id_press, "pimd_press"); - newarg = new char*[5]; + newarg = new char *[5]; newarg[0] = id_press; - newarg[1] = (char*) "all"; - newarg[2] = (char*) "pressure"; - newarg[3] = (char*) "thermo_temp"; - newarg[4] = (char*) "virial"; + newarg[1] = (char *) "all"; + newarg[2] = (char *) "pressure"; + newarg[3] = (char *) "thermo_temp"; + newarg[4] = (char *) "virial"; modify->add_compute(5, newarg); - delete [] newarg; + delete[] newarg; vol0 = domain->xprd * domain->yprd * domain->zprd; - fixedpoint[0] = 0.5*(domain->boxlo[0]+domain->boxhi[0]); - fixedpoint[1] = 0.5*(domain->boxlo[1]+domain->boxhi[1]); - fixedpoint[2] = 0.5*(domain->boxlo[2]+domain->boxhi[2]); + fixedpoint[0] = 0.5 * (domain->boxlo[0] + domain->boxhi[0]); + fixedpoint[1] = 0.5 * (domain->boxlo[1] + domain->boxhi[1]); + fixedpoint[2] = 0.5 * (domain->boxlo[2] + domain->boxhi[2]); // initialize Marsaglia RNG with processor-unique seed - if(integrator==baoab || integrator==obabo) - { + if (integrator == BAOAB || integrator == OBABO) { Lan_temp = temp; random = new RanMars(lmp, seed + universe->me); } me = comm->me; nprocs = comm->nprocs; - if(nprocs == 1) cmode = SINGLE_PROC; - else cmode = MULTI_PROC; + if (nprocs == 1) + cmode = SINGLE_PROC; + else + cmode = MULTI_PROC; nprocs_universe = universe->nprocs; nreplica = universe->nworlds; ireplica = universe->iworld; int *iroots = new int[nreplica]; - MPI_Group uworldgroup,rootgroup; + MPI_Group uworldgroup, rootgroup; - for (int i=0; iroot_proc[i]; + for (int i = 0; i < nreplica; i++) iroots[i] = universe->root_proc[i]; MPI_Comm_group(universe->uworld, &uworldgroup); MPI_Group_incl(uworldgroup, nreplica, iroots, &rootgroup); MPI_Comm_create(universe->uworld, rootgroup, &rootworld); if (rootgroup != MPI_GROUP_NULL) MPI_Group_free(&rootgroup); if (uworldgroup != MPI_GROUP_NULL) MPI_Group_free(&uworldgroup); - delete [] iroots; + delete[] iroots; ntotal = atom->natoms; - if(atom->nmax > maxlocal) reallocate(); - if(atom->nmax > maxunwrap) reallocate_x_unwrap(); - if(atom->nmax > maxxc) reallocate_xc(); - memory->create(xcall, ntotal*3, "FixPIMDLangevin:xcall"); + if (atom->nmax > maxlocal) reallocate(); + if (atom->nmax > maxunwrap) reallocate_x_unwrap(); + if (atom->nmax > maxxc) reallocate_xc(); + memory->create(xcall, ntotal * 3, "FixPIMDLangevin:xcall"); - if (cmode == SINGLE_PROC) - { + if (cmode == SINGLE_PROC) { memory->create(bufsorted, ntotal, 3, "FixPIMDLangevin:bufsorted"); memory->create(outsorted, ntotal, 3, "FixPIMDLangevin:outsorted"); - memory->create(bufsortedall, nreplica*ntotal, 3, "FixPIMDLangevin:bufsortedall"); - memory->create(buftransall, nreplica*ntotal, 3, "FixPIMDLangevin:buftransall"); + memory->create(bufsortedall, nreplica * ntotal, 3, "FixPIMDLangevin:bufsortedall"); + memory->create(buftransall, nreplica * ntotal, 3, "FixPIMDLangevin:buftransall"); memory->create(counts, nreplica, "FixPIMDLangevin:counts"); memory->create(displacements, nreplica, "FixPIMDLangevin:displacements"); } if ((cmode == MULTI_PROC) && (counts == nullptr)) { - memory->create(bufsendall,ntotal,3,"FixPIMDLangevin:bufsendall"); - memory->create(bufrecvall,ntotal,3,"FixPIMDLangevin:bufrecvall"); - memory->create(tagsendall,ntotal,"FixPIMDLangevin:tagsendall"); - memory->create(tagrecvall,ntotal,"FixPIMDLangevin:tagrecvall"); - memory->create(counts,nprocs,"FixPIMDLangevin:counts"); - memory->create(displacements,nprocs,"FixPIMDLangevin:displacements"); + memory->create(bufsendall, ntotal, 3, "FixPIMDLangevin:bufsendall"); + memory->create(bufrecvall, ntotal, 3, "FixPIMDLangevin:bufrecvall"); + memory->create(tagsendall, ntotal, "FixPIMDLangevin:tagsendall"); + memory->create(tagrecvall, ntotal, "FixPIMDLangevin:tagrecvall"); + memory->create(counts, nprocs, "FixPIMDLangevin:counts"); + memory->create(displacements, nprocs, "FixPIMDLangevin:displacements"); } - } /* ---------------------------------------------------------------------- */ -FixPIMDLangevin::~FixPIMDLangevin() -{ - -} +FixPIMDLangevin::~FixPIMDLangevin() {} /* ---------------------------------------------------------------------- */ @@ -358,10 +359,10 @@ int FixPIMDLangevin::setmask() void FixPIMDLangevin::init() { if (atom->map_style == Atom::MAP_NONE) - error->all(FLERR, "Fix pimd requires an atom map, see atom_modify"); + error->all(FLERR, "fix pimd/langevin requires an atom map, see atom_modify"); if (universe->me == 0 && universe->uscreen) - fprintf(universe->uscreen, "Fix pimd initializing Path-Integral ...\n"); + fprintf(universe->uscreen, "fix pimd/langevin initializing Path-Integral ...\n"); // prepare the constants @@ -369,43 +370,38 @@ void FixPIMDLangevin::init() np = universe->nworlds; inverse_np = 1.0 / np; - const double Boltzmann = force->boltz; - if (strcmp(update->unit_style,"lj") == 0) { - double planck_star = sqrt(lj_epsilon)*sqrt(atom->mass[0])*lj_sigma; + double planck; + if (strcmp(update->unit_style, "lj") == 0) { + double planck_star = sqrt(lj_epsilon) * sqrt(atom->mass[0]) * lj_sigma; planck = other_planck / planck_star; + } else { + planck = force->hplanck; } - else planck = force->hplanck; - const double Planck = planck; - hbar = Planck / (2.0 * MY_PI); + hbar = planck / (2.0 * MY_PI); kBT = force->boltz * temp; - double beta = 1.0 / (Boltzmann * temp); + double beta = 1.0 / (force->boltz * temp); double _fbond = 1.0 * np * np / (beta * beta * hbar * hbar); omega_np = np / (hbar * beta) * sqrt(force->mvv2e); - beta_np = 1.0 / force->boltz / temp / np; + beta_np = 1.0 / force->boltz / temp * inverse_np; fbond = _fbond * force->mvv2e; if (universe->me == 0) - printf("Fix pimd -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); + printf("fix pimd/langevin -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); - if(integrator==obabo) - { + if (integrator == OBABO) { dtf = 0.5 * update->dt * force->ftm2v; dtv = 0.5 * update->dt; dtv2 = dtv * dtv; - dtv3 = 1./3 * dtv2 * dtv * force->ftm2v; - } - else if(integrator==baoab) - { + dtv3 = THIRD * dtv2 * dtv * force->ftm2v; + } else if (integrator == BAOAB) { dtf = 0.5 * update->dt * force->ftm2v; dtv = 0.5 * update->dt; dtv2 = dtv * dtv; - dtv3 = 1./3 * dtv2 * dtv * force->ftm2v; - } - else - { - error->universe_all(FLERR,"Unknown integrator parameter for fix pimd"); + dtv3 = THIRD * dtv2 * dtv * force->ftm2v; + } else { + error->universe_all(FLERR, "Unknown integrator parameter for fix pimd/langevin"); } comm_init(); @@ -425,60 +421,56 @@ void FixPIMDLangevin::init() t_prim = t_vir = t_cv = p_prim = p_vir = p_cv = p_md = 0.0; - if(universe->me==0) fprintf(screen, "Fix pimd successfully initialized!\n"); + if (universe->me == 0) fprintf(screen, "fix pimd/langevin successfully initialized!\n"); } /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::setup(int vflag) { - if(universe->me==0) printf("Setting up Path-Integral ...\n"); + if (universe->me == 0) printf("Setting up Path-Integral ...\n"); int nlocal = atom->nlocal; - tagint *tag = atom->tag; double **x = atom->x; double **v = atom->v; imageint *image = atom->image; - if(mapflag){ - for(int i=0; iunmap(x[i], image[i]); - } + if (mapflag) { + for (int i = 0; i < nlocal; i++) domain->unmap(x[i], image[i]); } - if(method==NMPIMD) - { + if (method == NMPIMD) { inter_replica_comm(x); - if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); - else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); + if (cmode == SINGLE_PROC) + nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); + else if (cmode == MULTI_PROC) + nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); } collect_xc(); compute_spring_energy(); - if(method==NMPIMD) - { + if (method == NMPIMD) { inter_replica_comm(x); - if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); - else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); + if (cmode == SINGLE_PROC) + nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); + else if (cmode == MULTI_PROC) + nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); } - if(mapflag){ - for(int i=0; iunmap_inv(x[i], image[i]); - } + if (mapflag) { + for (int i = 0; i < nlocal; i++) domain->unmap_inv(x[i], image[i]); } - if(method==NMPIMD) - { + if (method == NMPIMD) { inter_replica_comm(v); - if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, v, M_x2xp[universe->iworld]); - else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, v, M_x2xp[universe->iworld]); + if (cmode == SINGLE_PROC) + nmpimd_transform(bufsortedall, v, M_x2xp[universe->iworld]); + else if (cmode == MULTI_PROC) + nmpimd_transform(bufbeads, v, M_x2xp[universe->iworld]); } - if(universe->me==0 && screen) fprintf(screen,"Setting up Path-Integral ...\n"); - if(universe->me==0) printf("Setting up Path-Integral ...\n"); + if (universe->me == 0 && screen) fprintf(screen, "Setting up Path-Integral ...\n"); + if (universe->me == 0) printf("Setting up Path-Integral ...\n"); post_force(vflag); compute_totke(); end_of_step(); - c_pe->addstep(update->ntimestep+1); - c_press->addstep(update->ntimestep+1); + c_pe->addstep(update->ntimestep + 1); + c_press->addstep(update->ntimestep + 1); } /* ---------------------------------------------------------------------- */ @@ -486,158 +478,133 @@ void FixPIMDLangevin::setup(int vflag) void FixPIMDLangevin::initial_integrate(int /*vflag*/) { int nlocal = atom->nlocal; - tagint *tag = atom->tag; double **x = atom->x; imageint *image = atom->image; - if(mapflag){ - for(int i=0; iunmap(x[i], image[i]); - } + if (mapflag) { + for (int i = 0; i < nlocal; i++) domain->unmap(x[i], image[i]); } - if(integrator==obabo) - { - if(tstat_flag) - { + if (integrator == OBABO) { + if (tstat_flag) { o_step(); - if(pstat_flag) press_o_step(); + if (pstat_flag) press_o_step(); } - if(pstat_flag) - { + if (pstat_flag) { compute_totke(); compute_p_cv(); press_v_step(); } - b_step(); - if(method==NMPIMD) - { + b_step(); + if (method == NMPIMD) { inter_replica_comm(x); - if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); - else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); + if (cmode == SINGLE_PROC) + nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); + else if (cmode == MULTI_PROC) + nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); } - qc_step(); - a_step(); - qc_step(); - a_step(); + qc_step(); + a_step(); + qc_step(); + a_step(); + } else if (integrator == BAOAB) { + if (pstat_flag) { + compute_totke(); + compute_p_cv(); + press_v_step(); } - else if(integrator==baoab) - { - if(pstat_flag) - { - compute_totke(); - compute_p_cv(); - press_v_step(); - } - b_step(); - if(method==NMPIMD) - { - inter_replica_comm(x); - if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); - else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); - } - qc_step(); - a_step(); - if(tstat_flag) - { - o_step(); - if(pstat_flag) press_o_step(); - } - qc_step(); - a_step(); - } - else - { - error->universe_all(FLERR,"Unknown integrator parameter for fix pimd"); - } - collect_xc(); - compute_spring_energy(); - - if(method==NMPIMD) - { + b_step(); + if (method == NMPIMD) { inter_replica_comm(x); - if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); - else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); + if (cmode == SINGLE_PROC) + nmpimd_transform(bufsortedall, x, M_x2xp[universe->iworld]); + else if (cmode == MULTI_PROC) + nmpimd_transform(bufbeads, x, M_x2xp[universe->iworld]); } - - - if(mapflag){ - for(int i=0; iunmap_inv(x[i], image[i]); - } + qc_step(); + a_step(); + if (tstat_flag) { + o_step(); + if (pstat_flag) press_o_step(); } + qc_step(); + a_step(); + } else { + error->universe_all(FLERR, "Unknown integrator parameter for fix pimd/langevin"); + } + collect_xc(); + compute_spring_energy(); + + if (method == NMPIMD) { + inter_replica_comm(x); + if (cmode == SINGLE_PROC) + nmpimd_transform(bufsortedall, x, M_xp2x[universe->iworld]); + else if (cmode == MULTI_PROC) + nmpimd_transform(bufbeads, x, M_xp2x[universe->iworld]); + } + + if (mapflag) { + for (int i = 0; i < nlocal; i++) { domain->unmap_inv(x[i], image[i]); } + } } /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::final_integrate() { - if(pstat_flag) - { - compute_totke(); - compute_p_cv(); - press_v_step(); + if (pstat_flag) { + compute_totke(); + compute_p_cv(); + press_v_step(); + } + b_step(); + if (integrator == OBABO) { + if (tstat_flag) { + o_step(); + if (pstat_flag) press_o_step(); } - b_step(); - if(integrator==obabo) - { - if(tstat_flag) - { - o_step(); - if(pstat_flag) press_o_step(); - } - } - else if(integrator==baoab) - { + } else if (integrator == BAOAB) { - } - else - { - error->universe_all(FLERR,"Unknown integrator parameter for fix pimd"); - } + } else { + error->universe_all(FLERR, "Unknown integrator parameter for fix pimd/langevin"); + } } /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::post_force(int /*flag*/) { - if(atom->nmax > maxunwrap) reallocate_x_unwrap(); - if(atom->nmax > maxxc) reallocate_xc(); + if (atom->nmax > maxunwrap) reallocate_x_unwrap(); + if (atom->nmax > maxxc) reallocate_xc(); int nlocal = atom->nlocal; double **x = atom->x; double **f = atom->f; imageint *image = atom->image; tagint *tag = atom->tag; - for(int i=0; iunmap(x_unwrap[i], image[i]); - } + if (mapflag) { + for (int i = 0; i < nlocal; i++) { domain->unmap(x_unwrap[i], image[i]); } } - for(int i=0; imap(1); + compute_vir(); compute_vir_(); compute_pote(); - if(method==NMPIMD) - { + if (method == NMPIMD) { inter_replica_comm(f); - if(cmode == SINGLE_PROC) nmpimd_transform(bufsortedall, f, M_x2xp[universe->iworld]); - else if(cmode == MULTI_PROC) nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); + if (cmode == SINGLE_PROC) + nmpimd_transform(bufsortedall, f, M_x2xp[universe->iworld]); + else if (cmode == MULTI_PROC) + nmpimd_transform(bufbeads, f, M_x2xp[universe->iworld]); } - c_pe->addstep(update->ntimestep+1); - c_press->addstep(update->ntimestep+1); + c_pe->addstep(update->ntimestep + 1); + c_press->addstep(update->ntimestep + 1); } /* ---------------------------------------------------------------------- */ @@ -647,11 +614,10 @@ void FixPIMDLangevin::end_of_step() compute_totke(); compute_p_cv(); compute_tote(); - if(pstat_flag) compute_totenthalpy(); + if (pstat_flag) compute_totenthalpy(); - if(update->ntimestep % 10000 == 0) - { - if(universe->me==0) printf("This is the end of step %ld.\n", update->ntimestep); + if (update->ntimestep % 10000 == 0) { + if (universe->me == 0) printf("This is the end of step %ld.\n", update->ntimestep); } } @@ -660,37 +626,28 @@ void FixPIMDLangevin::collect_xc() int nlocal = atom->nlocal; double **x = atom->x; tagint *tag = atom->tag; - if(ireplica == 0) - { - if(cmode == SINGLE_PROC) - { - for(int i=0; imap(1); - if(cmode == MULTI_PROC) - { - MPI_Allreduce(MPI_IN_PLACE, xcall, ntotal*3, MPI_DOUBLE, MPI_SUM, world); + if (cmode == MULTI_PROC) { + MPI_Allreduce(MPI_IN_PLACE, xcall, ntotal * 3, MPI_DOUBLE, MPI_SUM, world); } } - MPI_Bcast(xcall, ntotal*3, MPI_DOUBLE, 0, universe->uworld); + MPI_Bcast(xcall, ntotal * 3, MPI_DOUBLE, 0, universe->uworld); } /* ---------------------------------------------------------------------- */ @@ -703,51 +660,45 @@ void FixPIMDLangevin::b_step() double **v = atom->v; double **f = atom->f; - for(int i=0; inlocal; double **x = atom->x; double **v = atom->v; - tagint *tag = atom->tag; double oldlo, oldhi; - if(!pstat_flag) { - if(universe->iworld == 0) - { - for(int i=0; iiworld == 0) { + for (int i = 0; i < nlocal; i++) { x[i][0] += dtv * v[i][0]; x[i][1] += dtv * v[i][1]; x[i][2] += dtv * v[i][2]; } } - } - else{ - if(universe->iworld == 0) - { + } else { + if (universe->iworld == 0) { double expp[3], expq[3]; - if(pstyle == ISO) {vw[1] = vw[0]; vw[2] = vw[0];} - for(int j=0; j<3; j++) - { + if (pstyle == ISO) { + vw[1] = vw[0]; + vw[2] = vw[0]; + } + for (int j = 0; j < 3; j++) { expq[j] = exp(dtv * vw[j]); expp[j] = exp(-dtv * vw[j]); } - if(barostat == BZP) - { - for(int i=0; iboxlo[0]; oldhi = domain->boxhi[0]; - domain->boxlo[0] = (oldlo-fixedpoint[0])*expq[0] + fixedpoint[0]; - domain->boxhi[0] = (oldhi-fixedpoint[0])*expq[0] + fixedpoint[0]; + domain->boxlo[0] = (oldlo - fixedpoint[0]) * expq[0] + fixedpoint[0]; + domain->boxhi[0] = (oldhi - fixedpoint[0]) * expq[0] + fixedpoint[0]; oldlo = domain->boxlo[1]; oldhi = domain->boxhi[1]; - domain->boxlo[1] = (oldlo-fixedpoint[1])*expq[1] + fixedpoint[1]; - domain->boxhi[1] = (oldhi-fixedpoint[1])*expq[1] + fixedpoint[1]; + domain->boxlo[1] = (oldlo - fixedpoint[1]) * expq[1] + fixedpoint[1]; + domain->boxhi[1] = (oldhi - fixedpoint[1]) * expq[1] + fixedpoint[1]; oldlo = domain->boxlo[2]; oldhi = domain->boxhi[2]; - domain->boxlo[2] = (oldlo-fixedpoint[2])*expq[2] + fixedpoint[2]; - domain->boxhi[2] = (oldhi-fixedpoint[2])*expq[2] + fixedpoint[2]; + domain->boxlo[2] = (oldlo - fixedpoint[2]) * expq[2] + fixedpoint[2]; + domain->boxhi[2] = (oldhi - fixedpoint[2]) * expq[2] + fixedpoint[2]; } } MPI_Barrier(universe->uworld); @@ -780,26 +731,33 @@ void FixPIMDLangevin::qc_step(){ /* ---------------------------------------------------------------------- */ -void FixPIMDLangevin::a_step(){ +void FixPIMDLangevin::a_step() +{ int n = atom->nlocal; double **x = atom->x; double **v = atom->v; - double x0, x1, x2, v0, v1, v2; // three components of x[i] and v[i] + double x0, x1, x2, v0, v1, v2; // three components of x[i] and v[i] - if(universe->iworld != 0) - { - for(int i=0; iiworld != 0) { + for (int i = 0; i < n; i++) { x0 = x[i][0]; x1 = x[i][1]; x2 = x[i][2]; - v0 = v[i][0]; v1 = v[i][1]; v2 = v[i][2]; - x[i][0] = Lan_c[universe->iworld] * x0 + 1./_omega_k[universe->iworld] * Lan_s[universe->iworld] * v0; - x[i][1] = Lan_c[universe->iworld] * x1 + 1./_omega_k[universe->iworld] * Lan_s[universe->iworld] * v1; - x[i][2] = Lan_c[universe->iworld] * x2 + 1./_omega_k[universe->iworld] * Lan_s[universe->iworld] * v2; - v[i][0] = -1.*_omega_k[universe->iworld] * Lan_s[universe->iworld] * x0 + Lan_c[universe->iworld] * v0; - v[i][1] = -1.*_omega_k[universe->iworld] * Lan_s[universe->iworld] * x1 + Lan_c[universe->iworld] * v1; - v[i][2] = -1.*_omega_k[universe->iworld] * Lan_s[universe->iworld] * x2 + Lan_c[universe->iworld] * v2; + v0 = v[i][0]; + v1 = v[i][1]; + v2 = v[i][2]; + x[i][0] = Lan_c[universe->iworld] * x0 + + 1.0 / _omega_k[universe->iworld] * Lan_s[universe->iworld] * v0; + x[i][1] = Lan_c[universe->iworld] * x1 + + 1.0 / _omega_k[universe->iworld] * Lan_s[universe->iworld] * v1; + x[i][2] = Lan_c[universe->iworld] * x2 + + 1.0 / _omega_k[universe->iworld] * Lan_s[universe->iworld] * v2; + v[i][0] = -1.0 * _omega_k[universe->iworld] * Lan_s[universe->iworld] * x0 + + Lan_c[universe->iworld] * v0; + v[i][1] = -1.0 * _omega_k[universe->iworld] * Lan_s[universe->iworld] * x1 + + Lan_c[universe->iworld] * v1; + v[i][2] = -1.0 * _omega_k[universe->iworld] * Lan_s[universe->iworld] * x2 + + Lan_c[universe->iworld] * v2; } } } @@ -809,8 +767,12 @@ void FixPIMDLangevin::a_step(){ void FixPIMDLangevin::baro_init() { vw[0] = vw[1] = vw[2] = vw[3] = vw[4] = vw[5] = 0.0; - if(pstyle == ISO) {W = 3 * (atom->natoms) * tau_p * tau_p * np * kBT;} // consistent with the definition in i-Pi - else if(pstyle == ANISO) {W = atom->natoms * tau_p * tau_p * np * kBT;} + if (pstyle == ISO) { + W = 3 * (atom->natoms) * tau_p * tau_p * np * kBT; + } // consistent with the definition in i-Pi + else if (pstyle == ANISO) { + W = atom->natoms * tau_p * tau_p * np * kBT; + } Vcoeff = 1.0; std::string out = fmt::format("\nInitializing PIMD {:s} barostat...\n", Barostats[barostat]); out += fmt::format("The barostat mass is W = {:.16e}\n", W); @@ -827,18 +789,13 @@ void FixPIMDLangevin::press_v_step() int *type = atom->type; volume = domain->xprd * domain->yprd * domain->zprd; - if(pstyle == ISO) - { - if(barostat == BZP) - { + if (pstyle == ISO) { + if (barostat == BZP) { vw[0] += dtv * 3 * (volume * np * (p_cv - Pext) / force->nktv2p + Vcoeff / beta_np) / W; - if(universe->iworld==0) - { + if (universe->iworld == 0) { double dvw_proc = 0.0, dvw = 0.0; - for(int i = 0; i < nlocal; i++) - { - for(int j = 0; j < 3; j++) - { + for (int i = 0; i < nlocal; i++) { + for (int j = 0; j < 3; j++) { dvw_proc += dtv2 * f[i][j] * v[i][j] / W + dtv3 * f[i][j] * f[i][j] / mass[type[i]] / W; } } @@ -847,26 +804,21 @@ void FixPIMDLangevin::press_v_step() } MPI_Barrier(universe->uworld); MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); + } else if (barostat == MTTK) { + mtk_term1 = 2. / atom->natoms * totke / 3; + f_omega = (volume * np * (p_md - Pext) + mtk_term1) / W; + vw[0] += 0.5 * dtv * f_omega; } - else if(barostat == MTTK) - { - mtk_term1 = 2. / atom->natoms * totke / 3; - f_omega = (volume * np * (p_md - Pext) + mtk_term1) / W; - vw[0] += 0.5 * dtv * f_omega; - } - } - else if(pstyle == ANISO) - { + } else if (pstyle == ANISO) { compute_stress_tensor(); - for(int ii=0; ii<3; ii++) - { - vw[ii] += dtv * (volume * np * (stress_tensor[ii] - Pext) / force->nktv2p + Vcoeff / beta_np) / W; - if(universe->iworld==0) - { + for (int ii = 0; ii < 3; ii++) { + vw[ii] += + dtv * (volume * np * (stress_tensor[ii] - Pext) / force->nktv2p + Vcoeff / beta_np) / W; + if (universe->iworld == 0) { double dvw_proc = 0.0, dvw = 0.0; - for(int i = 0; i < nlocal; i++) - { - dvw_proc += dtv2 * f[i][ii] * v[i][ii] / W + dtv3 * f[i][ii] * f[i][ii] / mass[type[i]] / W; + for (int i = 0; i < nlocal; i++) { + dvw_proc += + dtv2 * f[i][ii] * v[i][ii] / W + dtv3 * f[i][ii] * f[i][ii] / mass[type[i]] / W; } MPI_Allreduce(&dvw_proc, &dvw, 1, MPI_DOUBLE, MPI_SUM, world); vw[ii] += dvw; @@ -879,26 +831,21 @@ void FixPIMDLangevin::press_v_step() void FixPIMDLangevin::press_o_step() { - if(pstyle==ISO) - { - if(universe->me==0) - { + if (pstyle == ISO) { + if (universe->me == 0) { r1 = random->gaussian(); - vw[0] = c1 * vw[0] + c2 * sqrt(1. / W / beta_np) * r1; + vw[0] = c1 * vw[0] + c2 * sqrt(1.0 / W / beta_np) * r1; } MPI_Barrier(universe->uworld); MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); - } - else if(pstyle==ANISO) - { - if(universe->me==0) - { + } else if (pstyle == ANISO) { + if (universe->me == 0) { r1 = random->gaussian(); r2 = random->gaussian(); r3 = random->gaussian(); - vw[0] = c1 * vw[0] + c2 * sqrt(1. / W / beta_np) * r1; - vw[1] = c1 * vw[1] + c2 * sqrt(1. / W / beta_np) * r2; - vw[2] = c1 * vw[2] + c2 * sqrt(1. / W / beta_np) * r3; + vw[0] = c1 * vw[0] + c2 * sqrt(1.0 / W / beta_np) * r1; + vw[1] = c1 * vw[1] + c2 * sqrt(1.0 / W / beta_np) * r2; + vw[2] = c1 * vw[2] + c2 * sqrt(1.0 / W / beta_np) * r3; } MPI_Barrier(universe->uworld); MPI_Bcast(&vw, 3, MPI_DOUBLE, 0, universe->uworld); @@ -916,52 +863,61 @@ void FixPIMDLangevin::Langevin_init() _omega_k = new double[np]; Lan_c = new double[np]; Lan_s = new double[np]; - if(fmmode==physical){ - for (int i=0; i 0) gamma = 1.0 / tau; - else gamma = np / beta / hbar; + if (tau > 0) + gamma = 1.0 / tau; + else + gamma = np / beta / hbar; - if(integrator==obabo) c1 = exp(-gamma * 0.5 * update->dt); // tau is the damping time of the centroid mode. - else if(integrator==baoab) c1 = exp(-gamma * update->dt); - else error->universe_all(FLERR, "Unknown integrator parameter for fix pimd. Only obabo and baoab integrators is supported!"); + if (integrator == OBABO) + c1 = exp(-gamma * 0.5 * update->dt); // tau is the damping time of the centroid mode. + else if (integrator == BAOAB) + c1 = exp(-gamma * update->dt); + else + error->universe_all(FLERR, + "Unknown integrator parameter for fix pimd/langevin. Only obabo and " + "baoab integrators are supported!"); - c2 = sqrt(1.0 - c1 * c1); // note that c1 and c2 here only works for the centroid mode. + c2 = sqrt(1.0 - c1 * c1); // note that c1 and c2 here only works for the centroid mode. - if( thermostat == PILE_L ) - { + if (thermostat == PILE_L) { std::string out = "\nInitializing PI Langevin equation thermostat...\n"; out += "Bead ID | omega | tau | c1 | c2\n"; tau_k = new double[np]; c1_k = new double[np]; c2_k = new double[np]; - tau_k[0] = tau; c1_k[0] = c1; c2_k[0] = c2; - for(int i=1; idt / tau_k[i]); - else if(integrator==baoab) c1_k[i] = exp(-1.0 * update->dt / tau_k[i]); - else error->universe_all(FLERR, "Unknown integrator parameter for fix pimd. Only obabo and baoab integrators is supported!"); + if (integrator == OBABO) + c1_k[i] = exp(-0.5 * update->dt / tau_k[i]); + else if (integrator == BAOAB) + c1_k[i] = exp(-1.0 * update->dt / tau_k[i]); + else + error->universe_all(FLERR, + "Unknown integrator parameter for fix pimd/langevin. Only obabo and " + "baoab integrators are supported!"); c2_k[i] = sqrt(1.0 - c1_k[i] * c1_k[i]); } - for(int i=0; inlocal; int *type = atom->type; - double beta_np = 1.0 / force->boltz / Lan_temp / np * force->mvv2e; - if(thermostat == PILE_L) - { - for(int i=0; iboltz / Lan_temp * inverse_np * force->mvv2e; + if (thermostat == PILE_L) { + for (int i = 0; i < nlocal; i++) { r1 = random->gaussian(); r2 = random->gaussian(); r3 = random->gaussian(); - atom->v[i][0] = c1_k[universe->iworld] * atom->v[i][0] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r1; - atom->v[i][1] = c1_k[universe->iworld] * atom->v[i][1] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r2; - atom->v[i][2] = c1_k[universe->iworld] * atom->v[i][2] + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r3; + atom->v[i][0] = c1_k[universe->iworld] * atom->v[i][0] + + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r1; + atom->v[i][1] = c1_k[universe->iworld] * atom->v[i][1] + + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r2; + atom->v[i][2] = c1_k[universe->iworld] * atom->v[i][2] + + c2_k[universe->iworld] * sqrt(1.0 / mass[type[i]] / beta_np) * r3; } } } @@ -994,94 +951,79 @@ void FixPIMDLangevin::o_step() void FixPIMDLangevin::nmpimd_init() { - memory->create(M_x2xp, np, np, "fix_feynman:M_x2xp"); - memory->create(M_xp2x, np, np, "fix_feynman:M_xp2x"); + memory->create(M_x2xp, np, np, "fix_feynman:M_x2xp"); + memory->create(M_xp2x, np, np, "fix_feynman:M_xp2x"); - lam = (double*) memory->smalloc(sizeof(double)*np, "FixPIMDLangevin::lam"); + lam = (double *) memory->smalloc(sizeof(double) * np, "FixPIMDLangevin::lam"); - // Set up eigenvalues - for(int i=0; iiworld; - for(int i=1; i<=atom->ntypes; i++) - { - mass[i] = atom->mass[i]; - if(iworld) - { - if(fmmode==physical) { mass[i] *= 1.0; } - else if(fmmode==normal) { mass[i] *= lam[iworld]; } - mass[i] *= fmass; + // Set up Ut + for (int i = 0; i < np; i++) + for (int j = 0; j < np; j++) { M_xp2x[i][j] = M_x2xp[j][i]; } + + // Set up masses + int iworld = universe->iworld; + for (int i = 1; i <= atom->ntypes; i++) { + mass[i] = atom->mass[i]; + if (iworld) { + if (fmmode == PHYSICAL) { + mass[i] *= 1.0; + } else if (fmmode == NORMAL) { + mass[i] *= lam[iworld]; } + mass[i] *= fmass; } + } } /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::nmpimd_transform(double **src, double **des, double *vector) { - if(cmode == SINGLE_PROC) - { - for(int i=0; itag[i]; - for(int d=0; d<3; d++) - { - des[i][d] = bufsorted[tagtmp-1][d]; - } + for (int d = 0; d < 3; d++) { des[i][d] = bufsorted[tagtmp - 1][d]; } } - } - else if(cmode == MULTI_PROC) - { - int n = atom->nlocal; - int m = 0; + } else if (cmode == MULTI_PROC) { + int n = atom->nlocal; + int m = 0; - for (int i = 0; i < n; i++) - for (int d = 0; d < 3; d++) { - des[i][d] = 0.0; - for (int j = 0; j < np; j++) { des[i][d] += (src[j][m] * vector[j]); } - m++; - } + for (int i = 0; i < n; i++) + for (int d = 0; d < 3; d++) { + des[i][d] = 0.0; + for (int j = 0; j < np; j++) { des[i][d] += (src[j][m] * vector[j]); } + m++; + } } } @@ -1092,25 +1034,25 @@ void FixPIMDLangevin::nmpimd_transform(double **src, double **des, double *vecto void FixPIMDLangevin::comm_init() { // if(me == 0){ - if (sizeplan) { - delete [] plansend; - delete [] planrecv; - } + if (sizeplan) { + delete[] plansend; + delete[] planrecv; + } - sizeplan = np - 1; - plansend = new int[sizeplan]; - planrecv = new int[sizeplan]; - modeindex = new int[sizeplan]; - for (int i = 0; i < sizeplan; i++) { - int isend, irecv; - isend = ireplica + i + 1; - if (isend >= nreplica) isend -= nreplica; - irecv = ireplica - (i + 1); - if (irecv < 0) irecv += nreplica; - plansend[i] = universe->root_proc[isend]; - planrecv[i] = universe->root_proc[irecv]; - modeindex[i] = irecv; - } + sizeplan = np - 1; + plansend = new int[sizeplan]; + planrecv = new int[sizeplan]; + modeindex = new int[sizeplan]; + for (int i = 0; i < sizeplan; i++) { + int isend, irecv; + isend = ireplica + i + 1; + if (isend >= nreplica) isend -= nreplica; + irecv = ireplica - (i + 1); + if (irecv < 0) irecv += nreplica; + plansend[i] = universe->root_proc[isend]; + planrecv[i] = universe->root_proc[irecv]; + modeindex[i] = irecv; + } } /* ---------------------------------------------------------------------- */ @@ -1145,7 +1087,7 @@ void FixPIMDLangevin::reallocate() memory->create(bufrecv, maxlocal, 3, "FixPIMDLangevin:bufrecv"); memory->create(tagsend, maxlocal, "FixPIMDLangevin:tagsend"); memory->create(tagrecv, maxlocal, "FixPIMDLangevin:tagrecv"); - memory->create(bufbeads, nreplica, maxlocal*3, "FixPIMDLangevin:bufrecv"); + memory->create(bufbeads, nreplica, maxlocal * 3, "FixPIMDLangevin:bufrecv"); } /* ---------------------------------------------------------------------- */ @@ -1160,36 +1102,31 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) int i, m; // copy local values - for(i=0; itag[i]; - bufsorted[tagtmp-1][0] = ptr[i][0]; - bufsorted[tagtmp-1][1] = ptr[i][1]; - bufsorted[tagtmp-1][2] = ptr[i][2]; + bufsorted[tagtmp - 1][0] = ptr[i][0]; + bufsorted[tagtmp - 1][1] = ptr[i][1]; + bufsorted[tagtmp - 1][2] = ptr[i][2]; m++; } MPI_Allgather(&m, 1, MPI_INT, counts, 1, MPI_INT, universe->uworld); for (i = 0; i < nreplica; i++) { counts[i] *= 3; } displacements[0] = 0; - for (i = 0; i < nreplica-1; i++) { displacements[i+1] = displacements[i] + counts[i]; } - MPI_Allgatherv(bufsorted[0], 3*m, MPI_DOUBLE, bufsortedall[0], counts, displacements, MPI_DOUBLE, universe->uworld); - } - else if(cmode == MULTI_PROC) - { + for (i = 0; i < nreplica - 1; i++) { displacements[i + 1] = displacements[i] + counts[i]; } + MPI_Allgatherv(bufsorted[0], 3 * m, MPI_DOUBLE, bufsortedall[0], counts, displacements, + MPI_DOUBLE, universe->uworld); + } else if (cmode == MULTI_PROC) { m = 0; - for(i=0; iuworld, &requests[0]); - MPI_Irecv(tagrecvall, ntotal, MPI_LMP_TAGINT, planrecv[iplan], 0, universe->uworld, &requests[1]); - MPI_Send(bufsendall[0], 3*ntotal, MPI_DOUBLE, plansend[iplan], 0, universe->uworld); + for (i = 0; i < nprocs - 1; i++) { displacements[i + 1] = displacements[i] + counts[i]; } + MPI_Gatherv(bufsend[0], 3 * m, MPI_DOUBLE, bufsendall[0], counts, displacements, MPI_DOUBLE, 0, + world); + for (int iplan = 0; iplan < sizeplan; iplan++) { + if (me == 0) { + MPI_Irecv(bufrecvall[0], 3 * ntotal, MPI_DOUBLE, planrecv[iplan], 0, universe->uworld, + &requests[0]); + MPI_Irecv(tagrecvall, ntotal, MPI_LMP_TAGINT, planrecv[iplan], 0, universe->uworld, + &requests[1]); + MPI_Send(bufsendall[0], 3 * ntotal, MPI_DOUBLE, plansend[iplan], 0, universe->uworld); MPI_Send(tagsendall, ntotal, MPI_LMP_TAGINT, plansend[iplan], 0, universe->uworld); - MPI_Waitall(2,requests,statuses); + MPI_Waitall(2, requests, statuses); } MPI_Bcast(tagrecvall, ntotal, MPI_LMP_TAGINT, 0, world); - MPI_Bcast(bufrecvall[0], 3*ntotal, MPI_DOUBLE, 0, world); - for(i=0; imap(tagrecvall[i]); if (m < 0 || m >= nlocal) continue; - bufbeads[modeindex[iplan]][3*m+0] = bufrecvall[i][0]; - bufbeads[modeindex[iplan]][3*m+1] = bufrecvall[i][1]; - bufbeads[modeindex[iplan]][3*m+2] = bufrecvall[i][2]; + bufbeads[modeindex[iplan]][3 * m + 0] = bufrecvall[i][0]; + bufbeads[modeindex[iplan]][3 * m + 1] = bufrecvall[i][1]; + bufbeads[modeindex[iplan]][3 * m + 2] = bufrecvall[i][2]; } } } @@ -1233,20 +1172,17 @@ void FixPIMDLangevin::compute_vir_() { int nlocal = atom->nlocal; xf = vir_ = xcf = centroid_vir = 0.0; - int idx = atom->map(1); - for(int i=0; if[i][j]; xcf += (x_unwrap[i][j] - xc[i][j]) * atom->f[i][j]; } } MPI_Allreduce(&xf, &vir_, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); MPI_Allreduce(&xcf, ¢roid_vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); - if(pstyle == ANISO){ - for(int i=0; i<6; i++) c_vir_tensor[i] = 0.0; - for(int i=0; if[i][0]; c_vir_tensor[1] += (x_unwrap[i][1] - xc[i][1]) * atom->f[i][1]; c_vir_tensor[2] += (x_unwrap[i][2] - xc[i][2]) * atom->f[i][2]; @@ -1264,14 +1200,14 @@ void FixPIMDLangevin::compute_vir() { volume = domain->xprd * domain->yprd * domain->zprd; c_press->compute_vector(); - virial[0] = c_press->vector[0]*volume; - virial[1] = c_press->vector[1]*volume; - virial[2] = c_press->vector[2]*volume; - virial[3] = c_press->vector[3]*volume; - virial[4] = c_press->vector[4]*volume; - virial[5] = c_press->vector[5]*volume; - for(int i=0; i<6; i++) virial[i] /= universe->procs_per_world[universe->iworld]; - double vir_bead=(virial[0]+virial[1]+virial[2]); + virial[0] = c_press->vector[0] * volume; + virial[1] = c_press->vector[1] * volume; + virial[2] = c_press->vector[2] * volume; + virial[3] = c_press->vector[3] * volume; + virial[4] = c_press->vector[4] * volume; + virial[5] = c_press->vector[5] * volume; + for (int i = 0; i < 6; i++) virial[i] /= universe->procs_per_world[universe->iworld]; + double vir_bead = (virial[0] + virial[1] + virial[2]); MPI_Allreduce(&vir_bead, &vir, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); MPI_Allreduce(MPI_IN_PLACE, &virial[0], 6, MPI_DOUBLE, MPI_SUM, universe->uworld); } @@ -1282,10 +1218,10 @@ void FixPIMDLangevin::compute_stress_tensor() { int nlocal = atom->nlocal; int *type = atom->type; - if(universe->iworld == 0){ + if (universe->iworld == 0) { inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); - for(int i=0; i<6; i++) ke_tensor[i] = 0.0; - for(int i=0; iv[i][0] * atom->v[i][0] * force->mvv2e; ke_tensor[1] += 0.5 * mass[type[i]] * atom->v[i][1] * atom->v[i][1] * force->mvv2e; ke_tensor[2] += 0.5 * mass[type[i]] * atom->v[i][2] * atom->v[i][2] * force->mvv2e; @@ -1294,9 +1230,9 @@ void FixPIMDLangevin::compute_stress_tensor() ke_tensor[5] += 0.5 * mass[type[i]] * atom->v[i][1] * atom->v[i][2] * force->mvv2e; } MPI_Allreduce(MPI_IN_PLACE, &ke_tensor, 6, MPI_DOUBLE, MPI_SUM, world); - for(int i=0; i<6; i++) - { - stress_tensor[i] = inv_volume * ((2*ke_tensor[i] - c_vir_tensor[i]) * force->nktv2p + virial[i]) / np; + for (int i = 0; i < 6; i++) { + stress_tensor[i] = + inv_volume * ((2 * ke_tensor[i] - c_vir_tensor[i]) * force->nktv2p + virial[i]) / np; } } MPI_Bcast(&stress_tensor, 6, MPI_DOUBLE, 0, universe->uworld); @@ -1310,12 +1246,8 @@ void FixPIMDLangevin::compute_totke() totke = ke_bead = 0.0; int nlocal = atom->nlocal; int *type = atom->type; - for(int i=0; iv[i][j] * atom->v[i][j]; - } + for (int i = 0; i < nlocal; i++) { + for (int j = 0; j < 3; j++) { kine += 0.5 * mass[type[i]] * atom->v[i][j] * atom->v[i][j]; } } kine *= force->mvv2e; MPI_Allreduce(&kine, &ke_bead, 1, MPI_DOUBLE, MPI_SUM, world); @@ -1329,13 +1261,13 @@ void FixPIMDLangevin::compute_spring_energy() total_spring_energy = se_bead = 0.0; double **x = atom->x; - double* _mass = atom->mass; - int* type = atom->type; + double *_mass = atom->mass; + int *type = atom->type; int nlocal = atom->nlocal; - for(int i=0; iiworld] * (x[i][0]*x[i][0] + x[i][1]*x[i][1] + x[i][2]*x[i][2]); + for (int i = 0; i < nlocal; i++) { + spring_energy += 0.5 * _mass[type[i]] * fbond * lam[universe->iworld] * + (x[i][0] * x[i][0] + x[i][1] * x[i][1] + x[i][2] * x[i][2]); } MPI_Allreduce(&spring_energy, &se_bead, 1, MPI_DOUBLE, MPI_SUM, world); } @@ -1370,8 +1302,8 @@ void FixPIMDLangevin::compute_t_prim() /* void FixPIMDLangevin::compute_t_vir() { - t_vir = -0.5 / np * vir_; - t_cv = 1.5 * atom->natoms * force->boltz * temp - 0.5 / np * centroid_vir; + t_vir = -0.5 * inverse_np * vir_; + t_cv = 1.5 * atom->natoms * force->boltz * temp - 0.5 * inverse_np * centroid_vir; } */ /* ---------------------------------------------------------------------- */ @@ -1387,9 +1319,8 @@ void FixPIMDLangevin::compute_p_prim() void FixPIMDLangevin::compute_p_cv() { inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); - if(universe->iworld == 0) - { - p_cv = 1. / 3. * inv_volume * ((2. * ke_bead - 1. * centroid_vir) * force->nktv2p + 1. * vir) / np; + if (universe->iworld == 0) { + p_cv = THIRD * inv_volume * ((2.0 * ke_bead - centroid_vir) * force->nktv2p + vir) / np; } MPI_Bcast(&p_cv, 1, MPI_DOUBLE, 0, universe->uworld); } @@ -1399,58 +1330,53 @@ void FixPIMDLangevin::compute_p_cv() void FixPIMDLangevin::compute_totenthalpy() { volume = domain->xprd * domain->yprd * domain->zprd; - if(barostat == BZP) - { - if(pstyle == ISO) - { - totenthalpy = tote + 0.5*W*vw[0]*vw[0]/np + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); + if (barostat == BZP) { + if (pstyle == ISO) { + totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + Pext * volume / force->nktv2p - + Vcoeff * kBT * log(volume); + } else if (pstyle == ANISO) { + totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + 0.5 * W * vw[1] * vw[1] * inverse_np + + 0.5 * W * vw[2] * vw[2] * inverse_np + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); } - else if(pstyle == ANISO) - { - totenthalpy = tote + 0.5*W*vw[0]*vw[0]/np + 0.5*W*vw[1]*vw[1]/np + 0.5*W*vw[2]*vw[2]/np + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); - } - } - else if(barostat == MTTK) totenthalpy = tote + 1.5*W*vw[0]*vw[0]/np + Pext * (volume - vol0); + } else if (barostat == MTTK) + totenthalpy = tote + 1.5 * W * vw[0] * vw[0] * inverse_np + Pext * (volume - vol0); } /* ---------------------------------------------------------------------- */ double FixPIMDLangevin::compute_vector(int n) { - if(n==0) { return ke_bead; } - if(n==1) { return se_bead; } - if(n==2) { return pe_bead; } - if(n==3) { return tote; } + if (n == 0) return ke_bead; + if (n == 1) return se_bead; + if (n == 2) return pe_bead; + if (n == 3) return tote; // if(n==3) { return W*vw[0]; } - if(!pstat_flag) - { - if(n==4) { return t_prim; } - if(n==5) { return t_vir; } - if(n==6) { return t_cv; } - } - else if(pstat_flag) - { - if(pstyle == ISO) - { - if(barostat == BZP) - { - if(n==4) { return 0.5*W*vw[0]*vw[0]; } + if (!pstat_flag) { + if (n == 4) return t_prim; + if (n == 5) return t_vir; + if (n == 6) return t_cv; + } else if (pstat_flag) { + if (pstyle == ISO) { + if (barostat == BZP) { + if (n == 4) return 0.5 * W * vw[0] * vw[0]; + } else if (barostat == MTTK) { + if (n == 4) return 1.5 * W * vw[0] * vw[0]; } - else if(barostat == MTTK) - { - if(n==4) { return 1.5*W*vw[0]*vw[0]; } + if (n == 5) { + volume = domain->xprd * domain->yprd * domain->zprd; + return np * Pext * volume / force->nktv2p; } - if(n==5) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } - if(n==6) { volume = domain->xprd * domain->yprd * domain->zprd; return - Vcoeff * np * kBT * log(volume); } - if(n==7) { return totenthalpy; } - if(n==8) { return p_cv; } - if(n==9) { return total_spring_energy; } - } - else if(pstyle == ANISO) - { - + if (n == 6) { + volume = domain->xprd * domain->yprd * domain->zprd; + return -Vcoeff * np * kBT * log(volume); + } + if (n == 7) return totenthalpy; + if (n == 8) return p_cv; + if (n == 9) return total_spring_energy; + } else if (pstyle == ANISO) { } } + /* if(n==7) { return p_prim; } @@ -1474,7 +1400,6 @@ double FixPIMDLangevin::compute_vector(int n) if(n>14 && n<21) return stress_tensor[n-15]; if(n==21) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } if(n==22) { volume = domain->xprd * domain->yprd * domain->zprd; return - Vcoeff * np * kBT * log(volume); } - } + } */ return 0.0; - */ } diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 3af036caf9..93f4670808 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -47,7 +47,7 @@ class FixPIMDLangevin : public Fix { int np; // number of beads double inverse_np; // 1.0/np double temp; // temperature - double planck, hbar; // Planck's constant + double hbar; // Planck's constant double lj_epsilon, lj_sigma, lj_mass; // LJ unit energy, length, and mass scales double other_planck; double kBT; // k_B * temp @@ -119,8 +119,7 @@ class FixPIMDLangevin : public Fix { int tstat_flag; // tstat_flat = 1 if thermostat if used void Langevin_init(); void b_step(); // integrate for dt/2 according to B part (v <- v + f * dt/2) - void - a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) + void a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) void qc_step(); // integrate for dt/2 for the centroid mode (x <- x + v * dt/2) void o_step(); // integrate for dt according to O part (O-U process, for thermostating) From 6b1cad1e3d1624b947a2798dca3c80bb63161cd0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 25 Feb 2023 23:16:51 -0500 Subject: [PATCH 016/448] programming style updates --- src/REPLICA/fix_pimd_langevin.cpp | 155 ++++++++++++------------------ src/REPLICA/fix_pimd_langevin.h | 6 +- 2 files changed, 62 insertions(+), 99 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 22bed54c3b..24b677b141 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -64,7 +64,7 @@ enum { SINGLE_PROC, MULTI_PROC }; /* ---------------------------------------------------------------------- */ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) + Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) { time_integrate = 1; tagsend = tagrecv = nullptr; @@ -101,12 +101,17 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : tau = 1.0; tau_p = 1.0; Pext = 1.0; + pilescale = 1.0; tstat_flag = 1; pstat_flag = 0; mapflag = 1; removecomflag = 1; fmmode = PHYSICAL; pstyle = ISO; + totenthalpy = 0.0; + + int seed = -1; + for (int i = 0; i < 6; i++) p_flag[i] = 0; for (int i = 3; i < narg - 1; i += 2) { @@ -119,20 +124,17 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : method = CMD; else error->universe_all(FLERR, "Unknown method parameter for fix pimd/langevin"); - } else if (strcmp(arg[i], "integrator") == 0) - - { + } else if (strcmp(arg[i], "integrator") == 0) { if (strcmp(arg[i + 1], "obabo") == 0) integrator = OBABO; else if (strcmp(arg[i + 1], "baoab") == 0) integrator = BAOAB; else - error->universe_all(FLERR, - "Unknown integrator parameter for fix pimd/langevin. Only obabo and baoab " - "integrators are supported!"); - } - - else if (strcmp(arg[i], "ensemble") == 0) { + error->universe_all( + FLERR, + "Unknown integrator parameter for fix pimd/langevin. Only obabo and baoab " + "integrators are supported!"); + } else if (strcmp(arg[i], "ensemble") == 0) { if (strcmp(arg[i + 1], "nve") == 0) { ensemble = NVE; tstat_flag = 0; @@ -150,95 +152,69 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : tstat_flag = 1; pstat_flag = 1; } else - error->universe_all( - FLERR, - "Unknown ensemble parameter for fix pimd/langevin. Only nve and nvt ensembles are supported!"); - } - - else if (strcmp(arg[i], "fmass") == 0) { + error->universe_all(FLERR, + "Unknown ensemble parameter for fix pimd/langevin. Only nve and nvt " + "ensembles are supported!"); + } else if (strcmp(arg[i], "fmass") == 0) { fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); if (fmass < 0.0 || fmass > 1.0) error->universe_all(FLERR, "Invalid fmass value for fix pimd/langevin"); - } - - else if (strcmp(arg[i], "fmmode") == 0) { + } else if (strcmp(arg[i], "fmmode") == 0) { if (strcmp(arg[i + 1], "physical") == 0) fmmode = PHYSICAL; else if (strcmp(arg[i + 1], "normal") == 0) fmmode = NORMAL; else - error->universe_all(FLERR, - "Unknown fictitious mass mode for fix pimd/langevin. Only physical mass and " - "normal mode mass are supported!"); - } - - else if (strcmp(arg[i], "scale") == 0) { - pilescale = atof(arg[i + 1]); - if (pilescale < 0.0) error->universe_all(FLERR, "Invalid pile scale value for fix pimd/langevin"); - } - - else if (strcmp(arg[i], "temp") == 0) { + error->universe_all( + FLERR, + "Unknown fictitious mass mode for fix pimd/langevin. Only physical mass and " + "normal mode mass are supported!"); + } else if (strcmp(arg[i], "scale") == 0) { + pilescale = utils::numeric(FLERR, arg[i + 1], false, lmp); + if (pilescale < 0.0) + error->universe_all(FLERR, "Invalid pile scale value for fix pimd/langevin"); + } else if (strcmp(arg[i], "temp") == 0) { temp = utils::numeric(FLERR, arg[i + 1], false, lmp); if (temp < 0.0) error->universe_all(FLERR, "Invalid temp value for fix pimd/langevin"); - } - - else if (strcmp(arg[i], "lj") == 0) { + } else if (strcmp(arg[i], "lj") == 0) { lj_epsilon = utils::numeric(FLERR, arg[i + 1], false, lmp); lj_sigma = utils::numeric(FLERR, arg[i + 2], false, lmp); lj_mass = utils::numeric(FLERR, arg[i + 3], false, lmp); other_planck = utils::numeric(FLERR, arg[i + 4], false, lmp); - i++; - i++; - i++; - } - - else if (strcmp(arg[i], "thermostat") == 0) { + i += 3; + } else if (strcmp(arg[i], "thermostat") == 0) { if (strcmp(arg[i + 1], "PILE_L") == 0) { thermostat = PILE_L; - seed = atoi(arg[i + 2]); + seed = utils::inumeric(FLERR, arg[i + 2], false, lmp); i++; } - } - - else if (strcmp(arg[i], "tau") == 0) { - tau = atof(arg[i + 1]); - } - - else if (strcmp(arg[i], "press") == 0) { - Pext = atof(arg[i + 1]); + } else if (strcmp(arg[i], "tau") == 0) { + tau = utils::numeric(FLERR, arg[i + 1], false, lmp); + } else if (strcmp(arg[i], "press") == 0) { + Pext = utils::numeric(FLERR, arg[i + 1], false, lmp); if (Pext < 0.0) error->universe_all(FLERR, "Invalid press value for fix pimd/langevin"); - } - - else if (strcmp(arg[i], "barostat") == 0) { + } else if (strcmp(arg[i], "barostat") == 0) { if (strcmp(arg[i + 1], "MTTK") == 0) { barostat = MTTK; } else if (strcmp(arg[i + 1], "BZP") == 0) { barostat = BZP; } else error->universe_all(FLERR, "Unknown barostat parameter for fix pimd/langevin"); - } - - else if (strcmp(arg[i], "iso") == 0) { + } else if (strcmp(arg[i], "iso") == 0) { pstyle = ISO; i--; - } - - else if (strcmp(arg[i], "aniso") == 0) { + } else if (strcmp(arg[i], "aniso") == 0) { pstyle = ANISO; i--; - } - - else if (strcmp(arg[i], "taup") == 0) { - tau_p = atof(arg[i + 1]); + } else if (strcmp(arg[i], "taup") == 0) { + tau_p = utils::numeric(FLERR, arg[i + 1], false, lmp); if (tau_p <= 0.0) error->universe_all(FLERR, "Invalid tau_p value for fix pimd/langevin"); } else if (strcmp(arg[i], "fixcom") == 0) { if (strcmp(arg[i + 1], "yes") == 0) removecomflag = 1; else if (strcmp(arg[i + 1], "no") == 0) removecomflag = 0; - } - - else if (strcmp(arg[i], "map") == 0) { + } else if (strcmp(arg[i], "map") == 0) { if (strcmp(arg[i + 1], "yes") == 0) mapflag = 1; else if (strcmp(arg[i + 1], "no") == 0) @@ -257,25 +233,11 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : // some initilizations - id_pe = new char[8]; - strcpy(id_pe, "pimd_pe"); - char **newarg = new char *[3]; - newarg[0] = id_pe; - newarg[1] = (char *) "all"; - newarg[2] = (char *) "pe"; - modify->add_compute(3, newarg); - delete[] newarg; + id_pe = utils::strdup(std::string(id) + "_pimd_pe"); + modify->add_compute(std::string(id_pe) + " all pe"); - id_press = new char[12]; - strcpy(id_press, "pimd_press"); - newarg = new char *[5]; - newarg[0] = id_press; - newarg[1] = (char *) "all"; - newarg[2] = (char *) "pressure"; - newarg[3] = (char *) "thermo_temp"; - newarg[4] = (char *) "virial"; - modify->add_compute(5, newarg); - delete[] newarg; + id_press = utils::strdup(std::string(id) + "_pimd_press"); + modify->add_compute(std::string(id_press) + " all pressure thermo_temp virial"); vol0 = domain->xprd * domain->yprd * domain->zprd; @@ -339,7 +301,14 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : /* ---------------------------------------------------------------------- */ -FixPIMDLangevin::~FixPIMDLangevin() {} +FixPIMDLangevin::~FixPIMDLangevin() +{ + modify->delete_compute(id_pe); + modify->delete_compute(id_press); + delete[] id_pe; + delete[] id_press; + delete random; +} /* ---------------------------------------------------------------------- */ @@ -387,8 +356,8 @@ void FixPIMDLangevin::init() beta_np = 1.0 / force->boltz / temp * inverse_np; fbond = _fbond * force->mvv2e; - if (universe->me == 0) - printf("fix pimd/langevin -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); + if ((universe->me == 0) && (universe->uscreen)) + fprintf(universe->uscreen, "fix pimd/langevin -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); if (integrator == OBABO) { dtf = 0.5 * update->dt * force->ftm2v; @@ -413,15 +382,10 @@ void FixPIMDLangevin::init() Langevin_init(); if (pstat_flag) baro_init(); - int ipe = modify->find_compute(id_pe); - c_pe = modify->compute[ipe]; - - int ipress = modify->find_compute(id_press); - c_press = modify->compute[ipress]; + c_pe = modify->get_compute_by_id(id_pe); + c_press = modify->get_compute_by_id(id_press); t_prim = t_vir = t_cv = p_prim = p_vir = p_cv = p_md = 0.0; - - if (universe->me == 0) fprintf(screen, "fix pimd/langevin successfully initialized!\n"); } /* ---------------------------------------------------------------------- */ @@ -1335,8 +1299,9 @@ void FixPIMDLangevin::compute_totenthalpy() totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); } else if (pstyle == ANISO) { - totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + 0.5 * W * vw[1] * vw[1] * inverse_np + - 0.5 * W * vw[2] * vw[2] * inverse_np + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); + totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + + 0.5 * W * vw[1] * vw[1] * inverse_np + 0.5 * W * vw[2] * vw[2] * inverse_np + + Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); } } else if (barostat == MTTK) totenthalpy = tote + 1.5 * W * vw[0] * vw[0] * inverse_np + Pext * (volume - vol0); @@ -1376,7 +1341,7 @@ double FixPIMDLangevin::compute_vector(int n) } else if (pstyle == ANISO) { } } - + /* if(n==7) { return p_prim; } diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 93f4670808..e68f326ae6 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -107,14 +107,12 @@ class FixPIMDLangevin : public Fix { double dtv, dtf, dtv2, dtv3; double gamma, c1, c2, tau; double *tau_k, *c1_k, *c2_k; - double pilescale = 1.0; + double pilescale; double Lan_temp; double r1, r2, r3; double _omega_np, *_omega_k, *Lan_s, *Lan_c; // sin(omega_k*dt*0.5), cos(omega_k*dt*0.5) class RanMars *random; - int seed; - FILE *frand; int tstat_flag; // tstat_flat = 1 if thermostat if used void Langevin_init(); @@ -128,7 +126,7 @@ class FixPIMDLangevin : public Fix { double f_omega, mtk_term1; int pstat_flag; // pstat_flag = 1 if barostat is used int pstyle; // pstyle = ISO or ANISO (will support TRICLINIC in the future) - double W, tau_p, Pext, totenthalpy = 0.0, Vcoeff; + double W, tau_p, Pext, totenthalpy, Vcoeff; int p_flag[6]; double vw[6]; // barostat velocity double ke_tensor[6]; // kinetic energy tensor From 5a593f06f6f48b6bc5220a139fecc704b4193a49 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 10 Mar 2023 02:00:18 -0500 Subject: [PATCH 017/448] apply make fix-whitespace --- doc/src/fix_deposit.rst | 6 +++--- doc/src/fix_pimd.rst | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/src/fix_deposit.rst b/doc/src/fix_deposit.rst index 0199ae98ce..7d19e93148 100644 --- a/doc/src/fix_deposit.rst +++ b/doc/src/fix_deposit.rst @@ -221,9 +221,9 @@ options choose a z-coordinate for insertion independently. The vx, vy, and vz components of velocity for the inserted particle are set by sampling a uniform distribution between the bounds set by -the values specified for the *vx*, *vy*, and *vz* keywords. Note that -normally, new particles should be a assigned a negative vertical -velocity so that they move towards the surface. For molecules, the +the values specified for the *vx*, *vy*, and *vz* keywords. Note that +normally, new particles should be a assigned a negative vertical +velocity so that they move towards the surface. For molecules, the same velocity is given to every particle (no rotation or bond vibration). If the *target* option is used, the velocity vector of the inserted diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 4d08497928..b774a7c8df 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -17,7 +17,7 @@ Syntax * ID, group-ID are documented in :doc:`fix ` command * style = *pimd/langevin* or *pimd/nvt* = style name of this fix command * zero or more keyword/value pairs may be appended -* keywords for style *pimd/nvt* +* keywords for style *pimd/nvt* .. parsed-literal:: *keywords* = *method* or *fmass* or *sp* or *temp* or *nhc* @@ -27,7 +27,7 @@ Syntax *temp* value = temperature (temperarate units) *nhc* value = Nc = number of chains in Nose-Hoover thermostat -* keywords for style *pimd/langevin* +* keywords for style *pimd/langevin* .. parsed-literal:: *keywords* = *method* or *integrator* or *ensemble* or *fmass* or *fmmode* or *scale* or *lj* or *temp* or *thermostat* or *tau* or *press* or *barostat* or *taup* or *iso* or *aniso* @@ -183,7 +183,7 @@ quasi-beads to :doc:`binary restart files `. See the a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion. -Fix *pimd/langevin* ... +Fix *pimd/langevin* ... None of the :doc:`fix_modify ` options are relevant to fix pimd/nvt. From da6d3de48ea6e5b13571339a9a40eec2d1a2574a Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 10 Mar 2023 02:06:40 -0500 Subject: [PATCH 018/448] correct planck's constant for lj units --- src/REPLICA/fix_pimd_langevin.cpp | 8 +++----- src/REPLICA/fix_pimd_langevin.h | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 24b677b141..879c546326 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -55,7 +55,6 @@ enum { BAOAB, OBABO }; enum { ISO, ANISO, TRICLINIC }; enum { PILE_L }; enum { MTTK, BZP }; -// char* Barostats[] = {"MTTK", "BZP"}; static std::map Barostats{{MTTK, "MTTK"}, {BZP, "BZP"}}; enum { NVE, NVT, NPH, NPT }; @@ -181,7 +180,8 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : lj_sigma = utils::numeric(FLERR, arg[i + 2], false, lmp); lj_mass = utils::numeric(FLERR, arg[i + 3], false, lmp); other_planck = utils::numeric(FLERR, arg[i + 4], false, lmp); - i += 3; + other_mvv2e = utils::numeric(FLERR, arg[i + 5], false, lmp); + i += 4; } else if (strcmp(arg[i], "thermostat") == 0) { if (strcmp(arg[i + 1], "PILE_L") == 0) { thermostat = PILE_L; @@ -317,7 +317,6 @@ int FixPIMDLangevin::setmask() int mask = 0; mask |= POST_FORCE; mask |= INITIAL_INTEGRATE; - // mask |= POST_NEIGHBOR; mask |= FINAL_INTEGRATE; mask |= END_OF_STEP; return mask; @@ -341,7 +340,7 @@ void FixPIMDLangevin::init() double planck; if (strcmp(update->unit_style, "lj") == 0) { - double planck_star = sqrt(lj_epsilon) * sqrt(atom->mass[0]) * lj_sigma; + double planck_star = sqrt(lj_epsilon) * sqrt(lj_mass) * lj_sigma * sqrt(other_mvv2e); planck = other_planck / planck_star; } else { planck = force->hplanck; @@ -997,7 +996,6 @@ void FixPIMDLangevin::nmpimd_transform(double **src, double **des, double *vecto void FixPIMDLangevin::comm_init() { - // if(me == 0){ if (sizeplan) { delete[] plansend; delete[] planrecv; diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index e68f326ae6..6c450210e9 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -50,6 +50,7 @@ class FixPIMDLangevin : public Fix { double hbar; // Planck's constant double lj_epsilon, lj_sigma, lj_mass; // LJ unit energy, length, and mass scales double other_planck; + double other_mvv2e; double kBT; // k_B * temp double beta, beta_np; // beta = 1./kBT beta_np = 1./kBT/np int thermostat; // NHC or PILE_L From f301c00406f6699d94f8632dc3ee6e598e89b40d Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 10 Mar 2023 02:37:15 -0500 Subject: [PATCH 019/448] delete unused nmpimd_transform --- src/REPLICA/fix_pimd_langevin.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 6c450210e9..b491179403 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -100,7 +100,6 @@ class FixPIMDLangevin : public Fix { void reallocate(); void nmpimd_init(); - void nmpimd_transform(double **src, double **des, double **mat); void nmpimd_transform(double **, double **, double *); /* Langevin integration */ From 45da03340ab23ecb62941aad47b5f61bbd0f98d9 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 10 Mar 2023 02:56:44 -0500 Subject: [PATCH 020/448] update package info; delete unused code --- src/REPLICA/fix_pimd_langevin.cpp | 9 ++++----- src/REPLICA/fix_pimd_langevin.h | 6 +----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 879c546326..1552690a08 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -13,10 +13,10 @@ /* ---------------------------------------------------------------------- Package FixPIMDLangevin - Purpose Quantum Path Integral Algorithm for Quantum Chemistry + Purpose Path Integral Molecular Dynamics with Langevin Thermostat Yifan Li @ Princeton University (yifanl0716@gmail.com) - Added components: + Current Features: - Multi-processor parallelism for each bead - White-noise Langevin thermostat - Bussi-Zykova-Parrinello barostat (isotropic and anisotropic) @@ -557,7 +557,7 @@ void FixPIMDLangevin::post_force(int /*flag*/) } compute_vir(); - compute_vir_(); + compute_cvir(); compute_pote(); if (method == NMPIMD) { inter_replica_comm(f); @@ -1127,10 +1127,9 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) } } -/* ---------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- */ -void FixPIMDLangevin::compute_vir_() +void FixPIMDLangevin::compute_cvir() { int nlocal = atom->nlocal; xf = vir_ = xcf = centroid_vir = 0.0; diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index b491179403..60eca51907 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -177,14 +177,10 @@ class FixPIMDLangevin : public Fix { void compute_spring_energy(); // 2: spring elastic energy void compute_pote(); // 3: potential energy void compute_tote(); // 4: total energy: 1+2+3 for all the beads - // void compute_t_prim(); // 5: primitive kinetic energy estimator - // void compute_p_prim(); // primitive pressure estimator void compute_stress_tensor(); - // void compute_t_vir(); // centroid-virial kinetic energy estimator void compute_p_cv(); // centroid-virial pressure estimator - // void compute_p_vir(); // centroid-virial pressure estimator void compute_vir(); - void compute_vir_(); + void compute_cvir(); void compute_totenthalpy(); }; } // namespace LAMMPS_NS From 266f8fb67e7167d0865a53caf8fe7780f55fa34f Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 13 Mar 2023 23:42:25 -0400 Subject: [PATCH 021/448] clean up fix pimd/langevin --- src/REPLICA/fix_pimd_langevin.cpp | 94 ++++++++++++++++++------------- src/REPLICA/fix_pimd_langevin.h | 19 ++----- 2 files changed, 60 insertions(+), 53 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 1552690a08..4436878ba4 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -49,7 +49,7 @@ using namespace LAMMPS_NS; using namespace FixConst; using namespace MathConst; -enum { PIMD, NMPIMD, CMD }; +enum { NMPIMD }; enum { PHYSICAL, NORMAL }; enum { BAOAB, OBABO }; enum { ISO, ANISO, TRICLINIC }; @@ -88,7 +88,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : mass = nullptr; - method = PIMD; + method = NMPIMD; ensemble = NVT; integrator = OBABO; thermostat = PILE_L; @@ -115,15 +115,10 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : for (int i = 3; i < narg - 1; i += 2) { if (strcmp(arg[i], "method") == 0) { - if (strcmp(arg[i + 1], "pimd") == 0) - method = PIMD; - else if (strcmp(arg[i + 1], "nmpimd") == 0) - method = NMPIMD; - else if (strcmp(arg[i + 1], "cmd") == 0) - method = CMD; - else - error->universe_all(FLERR, "Unknown method parameter for fix pimd/langevin"); - } else if (strcmp(arg[i], "integrator") == 0) { + if (strcmp(arg[i + 1], "nmpimd") == 0)method = NMPIMD; + else error->universe_all(FLERR, "Unknown method parameter for fix pimd/langevin"); + } + else if (strcmp(arg[i], "integrator") == 0) { if (strcmp(arg[i + 1], "obabo") == 0) integrator = OBABO; else if (strcmp(arg[i + 1], "baoab") == 0) @@ -228,7 +223,15 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : global_freq = 1; vector_flag = 1; - size_vector = 11; + if (!pstat_flag) size_vector = 10; + else if (pstat_flag) { + if (pstyle == ISO){ + size_vector = 15; + } + else if (pstyle == ANISO){ + size_vector = 17; + } + } extvector = 1; // some initilizations @@ -391,7 +394,6 @@ void FixPIMDLangevin::init() void FixPIMDLangevin::setup(int vflag) { - if (universe->me == 0) printf("Setting up Path-Integral ...\n"); int nlocal = atom->nlocal; double **x = atom->x; double **v = atom->v; @@ -427,8 +429,6 @@ void FixPIMDLangevin::setup(int vflag) else if (cmode == MULTI_PROC) nmpimd_transform(bufbeads, v, M_x2xp[universe->iworld]); } - if (universe->me == 0 && screen) fprintf(screen, "Setting up Path-Integral ...\n"); - if (universe->me == 0) printf("Setting up Path-Integral ...\n"); post_force(vflag); compute_totke(); end_of_step(); @@ -558,6 +558,7 @@ void FixPIMDLangevin::post_force(int /*flag*/) compute_vir(); compute_cvir(); + compute_t_vir(); compute_pote(); if (method == NMPIMD) { inter_replica_comm(f); @@ -1231,6 +1232,8 @@ void FixPIMDLangevin::compute_spring_energy() (x[i][0] * x[i][0] + x[i][1] * x[i][1] + x[i][2] * x[i][2]); } MPI_Allreduce(&spring_energy, &se_bead, 1, MPI_DOUBLE, MPI_SUM, world); + se_bead /= universe->procs_per_world[universe->iworld]; + MPI_Allreduce(&se_bead, &total_spring_energy, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); } /* ---------------------------------------------------------------------- */ @@ -1243,6 +1246,7 @@ void FixPIMDLangevin::compute_pote() c_pe->compute_scalar(); pe_bead = c_pe->scalar; pot_energy_partition = pe_bead / universe->procs_per_world[universe->iworld]; + MPI_Allreduce(&pot_energy_partition, &pote, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); } /* ---------------------------------------------------------------------- */ @@ -1253,28 +1257,28 @@ void FixPIMDLangevin::compute_tote() } /* ---------------------------------------------------------------------- */ -/* + void FixPIMDLangevin::compute_t_prim() { t_prim = 1.5 * atom->natoms * np * force->boltz * temp - total_spring_energy; } -*/ + /* ---------------------------------------------------------------------- */ -/* + void FixPIMDLangevin::compute_t_vir() { t_vir = -0.5 * inverse_np * vir_; t_cv = 1.5 * atom->natoms * force->boltz * temp - 0.5 * inverse_np * centroid_vir; } -*/ + /* ---------------------------------------------------------------------- */ -/* + void FixPIMDLangevin::compute_p_prim() { p_prim = atom->natoms * np * force->boltz * temp * inv_volume - 1.0 / 1.5 * inv_volume * total_spring_energy; p_prim *= force->nktv2p; } -*/ + /* ---------------------------------------------------------------------- */ void FixPIMDLangevin::compute_p_cv() @@ -1312,30 +1316,42 @@ double FixPIMDLangevin::compute_vector(int n) if (n == 1) return se_bead; if (n == 2) return pe_bead; if (n == 3) return tote; - // if(n==3) { return W*vw[0]; } - if (!pstat_flag) { - if (n == 4) return t_prim; - if (n == 5) return t_vir; - if (n == 6) return t_cv; - } else if (pstat_flag) { - if (pstyle == ISO) { - if (barostat == BZP) { - if (n == 4) return 0.5 * W * vw[0] * vw[0]; - } else if (barostat == MTTK) { - if (n == 4) return 1.5 * W * vw[0] * vw[0]; - } - if (n == 5) { + if (n == 4) return t_prim; + if (n == 5) return t_vir; + if (n == 6) return t_cv; + if (n == 7) return p_prim; + if (n == 8) return p_md; + if (n == 9) return p_cv; + + if (pstat_flag) { volume = domain->xprd * domain->yprd * domain->zprd; + if (pstyle == ISO) { + if (n == 10) return vw[0]; + if (barostat == BZP) { + if (n == 11) return 0.5 * W * vw[0] * vw[0]; + } else if (barostat == MTTK) { + if (n == 11) return 1.5 * W * vw[0] * vw[0]; + } + if (n == 12) { return np * Pext * volume / force->nktv2p; } - if (n == 6) { + if (n == 13) { + return -Vcoeff * np * kBT * log(volume); + } + if (n == 14) return totenthalpy; + } else if (pstyle == ANISO) { + if (n == 10) return vw[0]; + if (n == 11) return vw[1]; + if (n == 12) return vw[2]; + if (n == 13) return 0.5 * W * (vw[0] * vw[0] + vw[1] * vw[1] + vw[2] * vw[2]); + if (n == 14) { + return np * Pext * volume / force->nktv2p; + } + if (n == 15) { volume = domain->xprd * domain->yprd * domain->zprd; return -Vcoeff * np * kBT * log(volume); } - if (n == 7) return totenthalpy; - if (n == 8) return p_cv; - if (n == 9) return total_spring_energy; - } else if (pstyle == ANISO) { + if (n == 16) return totenthalpy; } } diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 60eca51907..87481b2770 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -140,34 +140,21 @@ class FixPIMDLangevin : public Fix { /* centroid-virial estimator computation */ double vol0 = 0.0; double inv_volume = 0.0; - // double inv_volume = 0.0, vol_ = 0.0, vol0 = 0.0; double volume = 0.0; double **xc, *xcall; int maxxc; - // int n_unwrap; int maxunwrap; - // int maxunwrap, nlocal_init; - // tagint *tag_init, *tag_initall; - // imageint *image_init, *image_initall; double **x_unwrap; - // double **x_unwrap, **x_unwrapsort; - // double **x_unwrapall; - // void init_x_unwrap(); void reallocate_x_unwrap(); void reallocate_xc(); void collect_xc(); - // void compute_xc(); - // void compute_fc(); double xf, vir, vir_, xcf, centroid_vir; - double t_vir, t_cv, p_prim, p_vir, p_cv, p_cv_, p_md; - // double vir_, xcf, vir2; + double t_prim, t_vir, t_cv, p_prim, p_vir, p_cv, p_md; /* Computes */ double kine, pote, tote, totke; double ke_bead, se_bead, pe_bead, pot_energy_partition; double total_spring_energy; - double t_prim; - // double p_prim; char *id_pe; char *id_press; class Compute *c_pe; @@ -178,6 +165,10 @@ class FixPIMDLangevin : public Fix { void compute_pote(); // 3: potential energy void compute_tote(); // 4: total energy: 1+2+3 for all the beads void compute_stress_tensor(); + void compute_t_prim(); + void compute_t_vir(); + void compute_t_cv(); + void compute_p_prim(); void compute_p_cv(); // centroid-virial pressure estimator void compute_vir(); void compute_cvir(); From b4dc074638080e8964708c7ac2aaab4381d8e1b6 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Tue, 14 Mar 2023 02:46:31 -0400 Subject: [PATCH 022/448] delete global variable inv_volume --- src/REPLICA/fix_pimd_langevin.cpp | 13 ++++++++++--- src/REPLICA/fix_pimd_langevin.h | 3 +-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 4436878ba4..fe1dabd551 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -411,6 +411,8 @@ void FixPIMDLangevin::setup(int vflag) } collect_xc(); compute_spring_energy(); + compute_t_prim(); + compute_p_prim(); if (method == NMPIMD) { inter_replica_comm(x); if (cmode == SINGLE_PROC) @@ -495,6 +497,8 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) } collect_xc(); compute_spring_energy(); + compute_t_prim(); + compute_p_prim(); if (method == NMPIMD) { inter_replica_comm(x); @@ -1181,7 +1185,7 @@ void FixPIMDLangevin::compute_stress_tensor() int nlocal = atom->nlocal; int *type = atom->type; if (universe->iworld == 0) { - inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); + double inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); for (int i = 0; i < 6; i++) ke_tensor[i] = 0.0; for (int i = 0; i < nlocal; i++) { ke_tensor[0] += 0.5 * mass[type[i]] * atom->v[i][0] * atom->v[i][0] * force->mvv2e; @@ -1213,6 +1217,8 @@ void FixPIMDLangevin::compute_totke() } kine *= force->mvv2e; MPI_Allreduce(&kine, &ke_bead, 1, MPI_DOUBLE, MPI_SUM, world); + MPI_Allreduce(&ke_bead, &totke, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + totke /= universe->procs_per_world[universe->iworld]; } /* ---------------------------------------------------------------------- */ @@ -1232,8 +1238,8 @@ void FixPIMDLangevin::compute_spring_energy() (x[i][0] * x[i][0] + x[i][1] * x[i][1] + x[i][2] * x[i][2]); } MPI_Allreduce(&spring_energy, &se_bead, 1, MPI_DOUBLE, MPI_SUM, world); - se_bead /= universe->procs_per_world[universe->iworld]; MPI_Allreduce(&se_bead, &total_spring_energy, 1, MPI_DOUBLE, MPI_SUM, universe->uworld); + total_spring_energy /= universe->procs_per_world[universe->iworld]; } /* ---------------------------------------------------------------------- */ @@ -1275,6 +1281,7 @@ void FixPIMDLangevin::compute_t_vir() void FixPIMDLangevin::compute_p_prim() { + double inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); p_prim = atom->natoms * np * force->boltz * temp * inv_volume - 1.0 / 1.5 * inv_volume * total_spring_energy; p_prim *= force->nktv2p; } @@ -1283,7 +1290,7 @@ void FixPIMDLangevin::compute_p_prim() void FixPIMDLangevin::compute_p_cv() { - inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); + double inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); if (universe->iworld == 0) { p_cv = THIRD * inv_volume * ((2.0 * ke_bead - centroid_vir) * force->nktv2p + vir) / np; } diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 87481b2770..43f6df5e84 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -139,8 +139,7 @@ class FixPIMDLangevin : public Fix { /* centroid-virial estimator computation */ double vol0 = 0.0; - double inv_volume = 0.0; - double volume = 0.0; + double volume; double **xc, *xcall; int maxxc; int maxunwrap; From 2c6fe1e8bc337a09df63ebb274b0b8c24362c818 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 13:57:42 -0400 Subject: [PATCH 023/448] add p_md calculation --- src/REPLICA/fix_pimd_langevin.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index fe1dabd551..12233f6ee0 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -585,7 +585,7 @@ void FixPIMDLangevin::end_of_step() if (pstat_flag) compute_totenthalpy(); if (update->ntimestep % 10000 == 0) { - if (universe->me == 0) printf("This is the end of step %ld.\n", update->ntimestep); + if (universe->me == 0) printf("This is the end of step %lld.\n", update->ntimestep); } } @@ -1294,6 +1294,7 @@ void FixPIMDLangevin::compute_p_cv() if (universe->iworld == 0) { p_cv = THIRD * inv_volume * ((2.0 * ke_bead - centroid_vir) * force->nktv2p + vir) / np; } + p_md = THIRD * inv_volume * (totke + vir); MPI_Bcast(&p_cv, 1, MPI_DOUBLE, 0, universe->uworld); } From 77b9fe37ba8e41b17e15118833ffb2203c162fd5 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 14:00:56 -0400 Subject: [PATCH 024/448] delete dead code --- src/REPLICA/fix_pimd_langevin.cpp | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 12233f6ee0..2266dc5e6c 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -1363,29 +1363,5 @@ double FixPIMDLangevin::compute_vector(int n) } } - /* - - if(n==7) { return p_prim; } - if(n==8) { return p_md; } - if(n==9) { return p_cv; } - if(n==10) {return totenthalpy; - if(pstyle == ISO){ - if(n==11) { return vw[0]; } - if(n==12) { - if(barostat == BZP) { return 0.5*W*vw[0]*vw[0]; } - else if(barostat == MTTK) { return 1.5*W*vw[0]*vw[0]; } - } - if(n==13) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } - if(n==14) { volume = domain->xprd * domain->yprd * domain->zprd; - // printf("Vcoeff = %.6e np = %d kBT = %.6e logV = %.6e\n", Vcoeff, np, kBT, log(volume)); - return - Vcoeff * np * kBT * log(volume); } - } - else if(pstyle==ANISO){ - if(n>10 && n<=13) return vw[n-11]; - if(n==14) return 0.5*W*vw[0]*vw[0]+0.5*W*vw[1]*vw[1]+0.5*W*vw[2]*vw[2]; - if(n>14 && n<21) return stress_tensor[n-15]; - if(n==21) { volume = domain->xprd * domain->yprd * domain->zprd; return np * Pext * volume / force->nktv2p; } - if(n==22) { volume = domain->xprd * domain->yprd * domain->zprd; return - Vcoeff * np * kBT * log(volume); } - } */ return 0.0; } From f7bc270c00040ae5a2da5cbc9dda990be571f3ab Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 14:51:04 -0400 Subject: [PATCH 025/448] Do not initialized random number generator when there is no thermostat --- src/REPLICA/fix_pimd_langevin.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 2266dc5e6c..bcd94b3beb 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -250,9 +250,11 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : // initialize Marsaglia RNG with processor-unique seed - if (integrator == BAOAB || integrator == OBABO) { - Lan_temp = temp; - random = new RanMars(lmp, seed + universe->me); + if (tstat_flag) { + if (integrator == BAOAB || integrator == OBABO) { + Lan_temp = temp; + random = new RanMars(lmp, seed + universe->me); + } } me = comm->me; From 3f965a1c337f60262585278753ca2b2e4ae3a197 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 16:25:56 -0400 Subject: [PATCH 026/448] format the specification of external pressure --- src/REPLICA/fix_pimd_langevin.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index bcd94b3beb..949129873f 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -185,9 +185,6 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : } } else if (strcmp(arg[i], "tau") == 0) { tau = utils::numeric(FLERR, arg[i + 1], false, lmp); - } else if (strcmp(arg[i], "press") == 0) { - Pext = utils::numeric(FLERR, arg[i + 1], false, lmp); - if (Pext < 0.0) error->universe_all(FLERR, "Invalid press value for fix pimd/langevin"); } else if (strcmp(arg[i], "barostat") == 0) { if (strcmp(arg[i + 1], "MTTK") == 0) { barostat = MTTK; @@ -197,10 +194,10 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : error->universe_all(FLERR, "Unknown barostat parameter for fix pimd/langevin"); } else if (strcmp(arg[i], "iso") == 0) { pstyle = ISO; - i--; + Pext = utils::numeric(FLERR, arg[i+1], false, lmp); } else if (strcmp(arg[i], "aniso") == 0) { pstyle = ANISO; - i--; + Pext = utils::numeric(FLERR, arg[i+1], false, lmp); } else if (strcmp(arg[i], "taup") == 0) { tau_p = utils::numeric(FLERR, arg[i + 1], false, lmp); if (tau_p <= 0.0) error->universe_all(FLERR, "Invalid tau_p value for fix pimd/langevin"); From 0aca0435ef3c852343fa985879623120bb4da199 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 16:43:44 -0400 Subject: [PATCH 027/448] delete mapflag input script interface --- src/REPLICA/fix_pimd_langevin.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 949129873f..3559fc8efe 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -206,11 +206,6 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : removecomflag = 1; else if (strcmp(arg[i + 1], "no") == 0) removecomflag = 0; - } else if (strcmp(arg[i], "map") == 0) { - if (strcmp(arg[i + 1], "yes") == 0) - mapflag = 1; - else if (strcmp(arg[i + 1], "no") == 0) - mapflag = 0; } else { error->universe_all(FLERR, fmt::format("Unknown keyword {} for fix {}", arg[i], style)); } From aa84548002d4ca690f030b6fc3bccbe167f20fbb Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 16:45:18 -0400 Subject: [PATCH 028/448] set mapflag=0 if there is only 1 bead --- src/REPLICA/fix_pimd_langevin.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 3559fc8efe..964cca44c2 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -260,6 +260,9 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : nreplica = universe->nworlds; ireplica = universe->iworld; + if (nreplica == 1) mapflag = 0; + else mapflag = 1; + int *iroots = new int[nreplica]; MPI_Group uworldgroup, rootgroup; From 4e0af69b67d77a247a3495109219697d60e9e7c5 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 17:06:28 -0400 Subject: [PATCH 029/448] update documentation keyword part --- doc/src/fix_pimd.rst | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index b774a7c8df..63f57f1fdf 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -30,15 +30,28 @@ Syntax * keywords for style *pimd/langevin* .. parsed-literal:: - *keywords* = *method* or *integrator* or *ensemble* or *fmass* or *fmmode* or *scale* or *lj* or *temp* or *thermostat* or *tau* or *press* or *barostat* or *taup* or *iso* or *aniso* + *keywords* = *method* or *integrator* or *ensemble* or *fmmode* or *scale* or *temp* or *thermostat* or *tau* or or *iso* or *aniso* or *barostat* or *taup* or *fixcom* or *lj* *method* value = *nmpimd* - *fmass* value = scaling factor on mass - *sp* value = scaling factor on Planck constant - *temp* value = target temperature (temperarate units) - *thermostat* values = PILE_L *seed* - *seed* = random number seed + *integrator* value = *obabo* or *baoab* + *fmmode* value = *physical* or *normal* + *temp* value = Temperature (temperarate unit) + Temperature = target temperarate of the thermostat + *thermostat* values = style seed + style value = *PILE_L* + seed = random number generator seed *tau* value = thermostat damping parameter (time unit) - *press* value = target pressure (pressure units) + *scale* value = scaling factor of the damping times of non-centroid modes of PILE_L thermostat + *iso* or *aniso* values = Pressure (pressure unit) + Pressure = scalar external pressure of the barostat + *barostat* value = *BZP* or *MTTK* + *taup* value = barostat damping parameter (time unit) + *fixcom* value = *yes* or *no* + *lj* values = epsilon sigma mass planck mvv2e + epsilon = energy scale for reduced units (energy units) + sigma = length scale for reduced units (length units) + mass = mass scale for reduced units (mass units) + planck = Planck's constant for other unit style + mvv2e = mass * velocity^2 to energy conversion factor for other unit style Examples """""""" @@ -46,6 +59,7 @@ Examples .. code-block:: LAMMPS fix 1 all pimd/nvt method nmpimd fmass 1.0 sp 2.0 temp 300.0 nhc 4 + fix 1 all pimd/langevin ensemble npt integrator obabo temp 113.15 thermostat PILE_L 1234 tau 1.0 press 1.0 barostat BZP taup 1.0 iso Description """"""""""" From 5071b2f016e591e9a4c469e9886745fb8d726633 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Wed, 15 Mar 2023 17:25:25 -0400 Subject: [PATCH 030/448] update document notes part --- doc/src/fix_pimd.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 63f57f1fdf..5c82e9c55d 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -106,7 +106,9 @@ would be 3 x N x P x Nc. Fix *pimd/nvt* implements a complete velocity-verlet integrator combined with NH massive chain thermostat, so no other time integration fix should be used. - Similarly fix *pimd/langeving* implements ... + Fix *pimd/langevin* implements a complete velocity-verlet integrator + combined with Langevin thermostat in the normal mode representation, and + also provides a barostat to sample the NPH/NPT ensembles. The *method* keyword determines what style of PIMD is performed. A value of *pimd* is standard PIMD. A value of *nmpimd* is for From ad25af56a9bccd8c5da3b1f5ca610af25f0dde08 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 17 Mar 2023 15:29:26 -0400 Subject: [PATCH 031/448] add reference in fix pimd/langevin document --- doc/src/fix_pimd.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 5c82e9c55d..1f7d406d5e 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -280,3 +280,10 @@ Path Integrals, McGraw-Hill, New York (1965). **(Herman)** M. F. Herman, E. J. Bruskin, B. J. Berne, J Chem Phys, 76, 5150 (1982). +.. _Parrinello1: + +**(Parrinello1)** G. Bussi, T. Zykova-Timan, M. Parrinello, J Chem Phys, 130, 074101 (2009). + +.. _Manolopoulos: + +**(Manolopoulos)** M. Ceriotti, M. Parrinello, T. Markland, D. Manolopoulos, J. Chem. Phys. 133, 124104 (2010). \ No newline at end of file From 0e22e36b941d26fd231cd69ce16c090382d91f97 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 17 Mar 2023 15:38:48 -0400 Subject: [PATCH 032/448] add method nmpimd note for fix pimd/langevin document --- doc/src/fix_pimd.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 1f7d406d5e..4de504e70c 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -132,6 +132,10 @@ normal-mode PIMD. A value of *cmd* is for centroid molecular dynamics overall translation of the ring-polymer and is assigned the mass of the real particle. +.. note:: + Fix pimd/langevin only supports *method* value *nmpimd*. This should be enough + for most PIMD applications for quantum thermodynamics purpose. + Motion of the centroid can be effectively uncoupled from the other normal modes by scaling the fictitious masses to achieve a partial adiabatic separation. This is called a Centroid Molecular Dynamics From 008147d1f38dd1612d1ebe0e634208e265347dda Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 17 Mar 2023 17:41:29 -0400 Subject: [PATCH 033/448] correct mass preconditioning of fix pimd/langevin --- src/REPLICA/fix_pimd_langevin.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 964cca44c2..671625afc8 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -150,7 +150,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : "Unknown ensemble parameter for fix pimd/langevin. Only nve and nvt " "ensembles are supported!"); } else if (strcmp(arg[i], "fmass") == 0) { - fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); + fmass = utils::numeric(FLERR, arg[i+1], false, lmp); if (fmass < 0.0 || fmass > 1.0) error->universe_all(FLERR, "Invalid fmass value for fix pimd/langevin"); } else if (strcmp(arg[i], "fmmode") == 0) { @@ -830,13 +830,13 @@ void FixPIMDLangevin::Langevin_init() Lan_s = new double[np]; if (fmmode == PHYSICAL) { for (int i = 0; i < np; i++) { - _omega_k[i] = _omega_np * sqrt(lam[i]); + _omega_k[i] = _omega_np * sqrt(lam[i]) / sqrt(fmass); Lan_c[i] = cos(sqrt(lam[i]) * _omega_np_dt_half); Lan_s[i] = sin(sqrt(lam[i]) * _omega_np_dt_half); } } else if (fmmode == NORMAL) { for (int i = 0; i < np; i++) { - _omega_k[i] = _omega_np; + _omega_k[i] = _omega_np / sqrt(fmass); Lan_c[i] = cos(_omega_np_dt_half); Lan_s[i] = sin(_omega_np_dt_half); } @@ -947,17 +947,17 @@ void FixPIMDLangevin::nmpimd_init() for (int i = 0; i < np; i++) for (int j = 0; j < np; j++) { M_xp2x[i][j] = M_x2xp[j][i]; } - // Set up masses + // Set up fictitious masses int iworld = universe->iworld; for (int i = 1; i <= atom->ntypes; i++) { mass[i] = atom->mass[i]; + mass[i] *= fmass; if (iworld) { if (fmmode == PHYSICAL) { mass[i] *= 1.0; } else if (fmmode == NORMAL) { mass[i] *= lam[iworld]; } - mass[i] *= fmass; } } } From 76c19410c737faaeb2080b7268b31a5aed10b8d5 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 17 Mar 2023 17:44:48 -0400 Subject: [PATCH 034/448] correct fmass input of fix pimd/langevin --- src/REPLICA/fix_pimd_langevin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 671625afc8..88289f7609 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -94,6 +94,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : thermostat = PILE_L; barostat = BZP; fmass = 1.0; + np = universe->nworlds; sp = 1.0; temp = 298.15; Lan_temp = 298.15; @@ -151,7 +152,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : "ensembles are supported!"); } else if (strcmp(arg[i], "fmass") == 0) { fmass = utils::numeric(FLERR, arg[i+1], false, lmp); - if (fmass < 0.0 || fmass > 1.0) + if (fmass < 0.0 || fmass > np) error->universe_all(FLERR, "Invalid fmass value for fix pimd/langevin"); } else if (strcmp(arg[i], "fmmode") == 0) { if (strcmp(arg[i + 1], "physical") == 0) @@ -335,7 +336,6 @@ void FixPIMDLangevin::init() // prepare the constants masstotal = group->mass(igroup); - np = universe->nworlds; inverse_np = 1.0 / np; double planck; From fd21a584bf01e15639db1823d99524d23748458d Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Sat, 18 Mar 2023 10:17:01 -0400 Subject: [PATCH 035/448] update fmass part of fix pimd/langevin document --- doc/src/fix_pimd.rst | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 4de504e70c..28a5308dd7 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -30,10 +30,11 @@ Syntax * keywords for style *pimd/langevin* .. parsed-literal:: - *keywords* = *method* or *integrator* or *ensemble* or *fmmode* or *scale* or *temp* or *thermostat* or *tau* or or *iso* or *aniso* or *barostat* or *taup* or *fixcom* or *lj* + *keywords* = *method* or *integrator* or *ensemble* or *fmmode* or *fmass* or *scale* or *temp* or *thermostat* or *tau* or or *iso* or *aniso* or *barostat* or *taup* or *fixcom* or *lj* *method* value = *nmpimd* *integrator* value = *obabo* or *baoab* *fmmode* value = *physical* or *normal* + *fmass* value = scaling factor on mass *temp* value = Temperature (temperarate unit) Temperature = target temperarate of the thermostat *thermostat* values = style seed @@ -81,9 +82,11 @@ by the following equations: .. math:: Z = & \int d{\bf q} d{\bf p} \cdot \textrm{exp} [ -\beta H_{eff} ] \\ - H_{eff} = & \bigg(\sum_{i=1}^P \frac{p_i^2}{2m_i}\bigg) + V_{eff} \\ + H_{eff} = & \bigg(\sum_{i=1}^P \frac{p_i^2}{2M_i}\bigg) + V_{eff} \\ V_{eff} = & \sum_{i=1}^P \bigg[ \frac{mP}{2\beta^2 \hbar^2} (q_i - q_{i+1})^2 + \frac{1}{P} V(q_i)\bigg] +$M_i$ is the fictitious mass of the $i$-th mode, and m is the actual mass of the atoms. + The interested user is referred to any of the numerous references on this methodology, but briefly, each quantum particle in a path integral simulation is represented by a ring-polymer of P quasi-beads, labeled @@ -152,6 +155,27 @@ masses of beads, which can be used for the Partial Adiabatic CMD :ref:`(Hone) `, or to be set as P, which results in the fictitious masses to be equal to the real particle masses. +The keyword *fmmode* of *fix pimd/langevin* determines the mode of fictitious +mass preconditioning. There are two options: *physical* and *normal*. If *fmmode* is +*physical*, then the physical mass of the particles are used (and then multiplied by +*fmass*). If *fmmode* is *normal*, then the physical mass is first multiplied by the +eigenvalue of each normal mode, and then multiplied by *fmass*. More precisely, the +fictitious mass of *fix pimd/langevin* is determined by two factors: *fmmode* and *fmass*. +If *fmmode* is *physical*, then the fictitious mass is +.. math:: + $M_i = \mathrm{fmass} \times m$ + +If *fmmode* is *normal*, then the fictitious mass is +.. math:: + $M_i = \mathrm{fmass} \times \lambda_i \times m$ + +where $\lambda_i$ is the eigenvalue of the $i$-th normal mode. +.. note:: + Fictitious mass is only used in the momentum of the equation of motion + ($\bf{p}_i=M_i\bf{v}_i$), and not used in the spring elastic energy + ($\sum_{i=1}^P \frac{1}{2}m\omega_P^2(q_i - q_{i+1})^2$, $m$ is always the + actual mass of the particles). + The keyword *sp* is a scaling factor on Planck's constant, which can be useful for debugging or other purposes. The default value of 1.0 is appropriate for most situations. From 7beec96dd333601d17088b44efda65a0390cd283 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Sat, 18 Mar 2023 10:23:09 -0400 Subject: [PATCH 036/448] support sp in fix pimd/langevin --- src/REPLICA/fix_pimd_langevin.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 88289f7609..7a901316f3 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -154,6 +154,9 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : fmass = utils::numeric(FLERR, arg[i+1], false, lmp); if (fmass < 0.0 || fmass > np) error->universe_all(FLERR, "Invalid fmass value for fix pimd/langevin"); + } else if (strcmp(arg[i], "sp") == 0) { + sp = utils::numeric(FLERR, arg[i+1], false, lmp); + if (sp < 0.0) error->universe_all(FLERR, "Invalid sp value for fix pimd/nvt"); } else if (strcmp(arg[i], "fmmode") == 0) { if (strcmp(arg[i + 1], "physical") == 0) fmmode = PHYSICAL; @@ -345,7 +348,7 @@ void FixPIMDLangevin::init() } else { planck = force->hplanck; } - + planck *= sp; hbar = planck / (2.0 * MY_PI); kBT = force->boltz * temp; double beta = 1.0 / (force->boltz * temp); From d8f41a9032cb6271bb63bd53d8d5231d9051eddf Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Sat, 18 Mar 2023 10:25:05 -0400 Subject: [PATCH 037/448] support sp in fix pimd/nvt --- src/REPLICA/fix_pimd_nvt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/REPLICA/fix_pimd_nvt.cpp b/src/REPLICA/fix_pimd_nvt.cpp index 1f2f29f35c..e899c75a27 100644 --- a/src/REPLICA/fix_pimd_nvt.cpp +++ b/src/REPLICA/fix_pimd_nvt.cpp @@ -219,7 +219,7 @@ void FixPIMDNVT::init() const double Boltzmann = force->boltz; const double Plank = force->hplanck; - double hbar = Plank / (2.0 * MY_PI); + double hbar = Plank / (2.0 * MY_PI) * sp; double beta = 1.0 / (Boltzmann * nhc_temp); double _fbond = 1.0 * np / (beta * beta * hbar * hbar); From be8c0b9835d68354e4f5b9925f25eb0bfc9f539b Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 20 Mar 2023 14:08:42 -0400 Subject: [PATCH 038/448] enable fixcom feature of fix pimd/langevin --- src/REPLICA/fix_pimd_langevin.cpp | 24 ++++++++++++++++++++++++ src/REPLICA/fix_pimd_langevin.h | 1 + 2 files changed, 25 insertions(+) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 7a901316f3..e1d3960a50 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -451,6 +451,7 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) if (integrator == OBABO) { if (tstat_flag) { o_step(); + if (removecomflag) remove_com_motion(); if (pstat_flag) press_o_step(); } if (pstat_flag) { @@ -488,6 +489,7 @@ void FixPIMDLangevin::initial_integrate(int /*vflag*/) a_step(); if (tstat_flag) { o_step(); + if (removecomflag) remove_com_motion(); if (pstat_flag) press_o_step(); } qc_step(); @@ -526,6 +528,7 @@ void FixPIMDLangevin::final_integrate() if (integrator == OBABO) { if (tstat_flag) { o_step(); + if (removecomflag) remove_com_motion(); if (pstat_flag) press_o_step(); } } else if (integrator == BAOAB) { @@ -1134,6 +1137,27 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) /* ---------------------------------------------------------------------- */ +void FixPIMDLangevin::remove_com_motion(){ + if(universe->iworld == 0) + { + double **v = atom->v; + int *mask = atom->mask; + int nlocal = atom->nlocal; + if (dynamic) masstotal = group->mass(igroup); + double vcm[3]; + group->vcm(igroup,masstotal,vcm); + for (int i = 0; i < nlocal; i++) { + if (mask[i] & groupbit) { + v[i][0] -= vcm[0]; + v[i][1] -= vcm[1]; + v[i][2] -= vcm[2]; + } + } + } +} + +/* ---------------------------------------------------------------------- */ + void FixPIMDLangevin::compute_cvir() { int nlocal = atom->nlocal; diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 43f6df5e84..b8bed1a10f 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -147,6 +147,7 @@ class FixPIMDLangevin : public Fix { void reallocate_x_unwrap(); void reallocate_xc(); void collect_xc(); + void remove_com_motion(); double xf, vir, vir_, xcf, centroid_vir; double t_prim, t_vir, t_cv, p_prim, p_vir, p_cv, p_md; From 7a38f49a21cacc6f0701e67c715f446f4c835df5 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 20 Mar 2023 14:10:09 -0400 Subject: [PATCH 039/448] add lj example for fix pimd/langevin --- examples/PACKAGES/pimd/lj/data.metalnpt01 | 422 ++++++++++++++++++++++ examples/PACKAGES/pimd/lj/data.metalnpt02 | 422 ++++++++++++++++++++++ examples/PACKAGES/pimd/lj/data.metalnpt03 | 422 ++++++++++++++++++++++ examples/PACKAGES/pimd/lj/data.metalnpt04 | 422 ++++++++++++++++++++++ examples/PACKAGES/pimd/lj/in.lmp | 28 ++ examples/PACKAGES/pimd/lj/run.sh | 1 + 6 files changed, 1717 insertions(+) create mode 100644 examples/PACKAGES/pimd/lj/data.metalnpt01 create mode 100644 examples/PACKAGES/pimd/lj/data.metalnpt02 create mode 100644 examples/PACKAGES/pimd/lj/data.metalnpt03 create mode 100644 examples/PACKAGES/pimd/lj/data.metalnpt04 create mode 100755 examples/PACKAGES/pimd/lj/in.lmp create mode 100644 examples/PACKAGES/pimd/lj/run.sh diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt01 b/examples/PACKAGES/pimd/lj/data.metalnpt01 new file mode 100644 index 0000000000..3dc2944ed9 --- /dev/null +++ b/examples/PACKAGES/pimd/lj/data.metalnpt01 @@ -0,0 +1,422 @@ +LAMMPS data file via write_data, version 8 Feb 2023, timestep = 100000 + +200 atoms +1 atom types + +-11.876696863105703 11.876696863105703 xlo xhi +-11.876696863105703 11.876696863105703 ylo yhi +-11.876696863105703 11.876696863105703 zlo zhi + +Masses + +1 39.948 + +Pair Coeffs # lj/cut + +1 0.00965188 3.4 + +Atoms # atomic + +39 1 -10.338208372875723 -8.724519590498623 -8.445612139491281 0 -1 1 +82 1 -7.5133824622188925 -6.978636164411631 -10.191775661279799 0 0 0 +57 1 -6.093878587859262 -9.276313581141936 -7.744358551066254 1 0 0 +8 1 -7.188384493977925 -11.000743174865285 -10.566868392413127 0 1 1 +49 1 -0.45896030511450936 -8.721648062141405 -7.76988436909876 0 1 0 +54 1 4.36019737005205 -9.840722628422576 -9.652200105153977 0 -1 1 +114 1 3.904944042667676 -8.560258519206736 -6.227256449483399 -1 0 1 +128 1 1.537670815459421 11.367557646509137 -7.44113189883349 0 0 -2 +102 1 2.6467980910798623 -6.300231690446356 -10.839747469959917 1 -1 -1 +157 1 6.599214138053117 -6.278630725537236 -7.389049268829837 -1 0 1 +20 1 8.160418209241914 -11.236890922228888 -9.90427297873004 0 1 0 +147 1 10.464052914243185 -5.834517788008704 -9.403782126876184 -1 2 0 +169 1 9.355540563360105 -8.982132042608429 -6.861385656669775 0 1 1 +123 1 -6.908328795781873 -3.2942152122483694 -10.871702946953768 -1 0 -1 +130 1 -6.59789640513614 -2.559000332768779 -7.109058819418416 -1 1 0 +140 1 -9.12121182032633 -1.3228381271313019 -9.248705124201138 -1 1 0 +153 1 -4.57209419001429 -5.197951679459013 -8.806559015841044 0 1 0 +129 1 -0.17714454435176596 -5.056145756511569 -8.582370909018262 0 1 1 +148 1 -3.197585507102101 -2.0540921199407465 -9.77932871778502 0 0 0 +119 1 -3.51954842440485 -3.8478081846346726 10.678236929073831 0 -1 -1 +174 1 3.1384595215939513 -1.9078182147633918 -10.748237231758047 -1 1 -1 +134 1 -0.0032185119392025285 -0.36841629060197645 -8.631895429784365 -1 0 2 +189 1 2.892780086534627 -1.3587472579142499 -6.410113256095116 0 0 2 +28 1 6.224912481821424 -1.100900418829165 -9.316948573538184 0 0 -1 +1 1 7.533342646866252 -2.8858379557892953 -6.5588822497649195 1 -1 0 +24 1 10.891564390761006 -2.1693511431878143 -8.14872153065027 0 -1 1 +176 1 10.35065200687287 -3.6683271215630047 -4.32699396695263 0 0 0 +182 1 -10.764131367809398 0.5730937842904389 -5.180063181396292 0 1 -1 +137 1 -8.194528746006949 3.76661130396705 -8.596433076900993 -1 1 0 +89 1 -5.793296966734716 0.9591211322466908 -8.532912969707475 0 0 -1 +88 1 -3.2415549382910047 2.6063473128515433 -11.019658141847422 0 1 -1 +160 1 -0.17978720428819353 5.335367005111222 -5.961111228150678 0 0 1 +125 1 -3.2595127311899836 3.541669787125592 -7.094678802230409 0 1 0 +167 1 2.6101389699783257 2.7016950511217104 -7.510579719545417 0 1 0 +107 1 2.478905108002845 1.3710464608203452 -11.241338409619438 -1 1 1 +45 1 -0.2728444271939366 3.4472072045614333 -9.803824961885091 0 1 0 +95 1 7.005885045149228 1.8641755193621776 -11.033503201926393 0 2 -1 +111 1 11.28085723924775 1.3577973865073396 -8.404143782130012 0 1 1 +37 1 7.50412447792306 1.5806311975228182 -7.696866725729485 1 0 2 +53 1 9.464056637143884 5.181490576538966 -10.160960273108417 -1 -1 1 +122 1 -8.61454149114821 11.46923394337289 -7.097906043887797 2 -1 -1 +126 1 -8.658911027419105 9.160142379367757 -10.196432851978876 0 0 -1 +72 1 -11.223582472260205 7.275428216701358 10.836645274139237 2 0 0 +144 1 -3.0387339366126 -9.918200912273784 -9.896452956043586 0 1 1 +135 1 0.03771056281680529 7.830565362407303 -8.390686664231268 1 0 0 +183 1 2.8786138768293665 5.221499246050073 -10.100270572243783 0 0 0 +155 1 3.821499942128122 9.224610559399695 -9.359914290522674 0 0 0 +21 1 6.6299071097705 6.818271712520994 -8.197268594363944 1 0 0 +66 1 9.53812274637967 7.559409537149467 -6.194715694404919 -2 -1 0 +22 1 11.107750453110658 10.72621054512756 -6.232964722376559 -1 0 0 +42 1 9.127119842763733 9.280850325093446 -10.249747757735628 -1 1 0 +77 1 -6.840159982144716 -10.92057206639582 -3.876267638432264 1 -1 1 +47 1 -8.742923464684916 -8.023408201112765 -5.403173093100989 1 2 1 +18 1 -10.63751608820882 -11.30186343558728 -3.9206887105699195 1 0 -1 +46 1 11.298180499183054 -7.685155723666886 -4.06604680107494 1 0 -2 +14 1 -9.566429851257723 -7.447961115721825 -2.010931774940218 -1 0 2 +178 1 -4.527419254322211 -8.045910047035035 -4.819501104832851 2 1 0 +48 1 -3.2147691406929866 -10.888877164915472 -6.377437598460709 1 1 -1 +55 1 -0.9601171939836206 -6.238495322587188 -4.2762406549238605 -1 0 -1 +12 1 -1.8964494825899862 -9.405283267682947 -2.3799601015584315 -1 0 2 +15 1 6.020890846962015 -8.178330582079944 0.7240728610757863 -1 0 -1 +64 1 2.731938348082501 -10.543443272156145 -1.741916704711699 1 1 0 +44 1 8.065377899358 -6.2776681789760715 -3.599447303926354 -1 0 1 +188 1 10.02823971588665 -8.47709879900416 -0.7307124355000334 -1 0 0 +200 1 -9.394872508283228 -3.330386381489715 -5.1567351351767705 -1 0 0 +198 1 -7.21209897973175 -1.1704302343832897 -2.203950414480204 0 0 1 +76 1 -9.986350100477846 -3.0116982250661763 -1.5200938888623745 1 0 0 +194 1 -6.746550374491012 -4.972813556867408 -2.5010542319113824 0 1 -1 +68 1 -2.5395355119165752 -3.5084431511046077 -6.11089008487593 0 1 1 +96 1 -3.383034995518244 -3.996115182399876 -2.1114098179404905 -1 2 0 +91 1 3.023350222125586 -6.242259457656427 -2.3794062527217115 1 -1 -1 +154 1 -0.21966769644821582 -2.9431607814775376 -3.0023832902544516 -1 2 0 +19 1 3.1658091018639274 -2.0642468786997554 -2.307083850490244 0 1 -1 +120 1 6.655220459905831 -2.268055028492757 -2.8431810436972036 1 1 1 +138 1 9.657284951715521 -4.552145938528714 -0.6562837148986382 -1 1 -1 +9 1 7.577787647310252 -2.027383158459481 0.591256647470022 0 0 1 +150 1 -9.975709520806461 2.045189761629004 -1.3967042898865678 1 -1 1 +38 1 -5.780821497271447 4.724336446491739 -4.727424802574532 1 0 2 +172 1 -9.690365647641709 4.0528825638271995 -4.90299752668659 0 0 2 +29 1 -7.905836311144201 7.618140007848844 2.0916587803060374 1 -1 -1 +87 1 -3.2429786758343386 -0.9446923499804107 -3.602689802943157 0 -1 1 +93 1 -6.311310050813026 0.9463486890063564 -4.844328963553153 0 -1 1 +195 1 1.0294591756555889 0.17190072131794665 -3.729109843284945 1 -1 3 +149 1 -2.2517532526979984 2.837758606759653 -2.568308902690684 1 0 0 +25 1 4.622058806898725 1.1966098061131745 -0.5762266975161516 -1 0 1 +35 1 2.770724754796497 3.7811224145924633 -3.6900492736017867 1 -1 0 +116 1 5.985384722273807 5.820793889080573 -5.01963853113883 0 1 0 +5 1 5.710509981071034 1.5091333740272113 -4.1779355439452 0 -1 -1 +112 1 4.909280213802248 5.451229842365678 -0.23301351689583433 -1 0 0 +152 1 11.352756404691903 -0.5457110274170986 -1.851635893722021 -2 -1 0 +132 1 8.574718024729343 1.7846682488107686 -1.3135653711870618 0 0 0 +173 1 8.985071256603522 3.7974294357041134 -5.507410143502991 0 0 1 +73 1 -9.997675226742189 8.034933990134746 -6.6211967592334595 0 -2 1 +161 1 -11.552860384837217 7.057039822309078 -3.567109853559714 2 0 2 +78 1 -1.8080552760100446 10.151101687740656 -1.7466859905812946 1 -2 1 +11 1 4.503908677727956 -11.845112920212848 -5.000489634351112 0 2 1 +84 1 2.4816138724708487 7.425072174245171 -5.250945864454475 1 0 0 +90 1 6.134640615065156 9.297869169242624 -0.8361676575747339 0 -1 1 +36 1 1.9591052897014976 7.715785297331987 -1.741598961638701 2 -1 0 +98 1 8.55440808947692 7.573996243117245 -2.894381804652479 -1 0 0 +56 1 7.300059241947594 10.446841724098018 -6.708609001665156 -1 0 1 +109 1 9.185972290533323 11.319457447612841 -0.9199703749554402 -1 1 1 +115 1 -7.290737513756202 -8.128422064576581 2.840900089769448 1 0 0 +124 1 -11.095494798277388 -8.787146009506092 4.06143463064398 1 0 -2 +121 1 -8.269324094623837 -10.076632693187037 6.580117501920071 0 1 -1 +80 1 -4.964400090273426 -7.254460179243866 -0.2516287260948715 0 0 1 +101 1 -4.352556925935133 -8.093642941491481 4.9061967743324075 1 3 1 +4 1 1.6615068736969008 10.065280091130505 4.658196599859135 -1 -1 -1 +81 1 7.340287496174785 -8.542929146635126 6.681008128047246 -1 1 1 +6 1 8.92830710513934 -10.595453002991315 2.772878983207939 1 1 0 +166 1 -8.702005772998799 -5.0252019350878925 4.355591496028076 0 2 0 +40 1 -7.050509790391359 -4.52399648752538 1.2979104738341645 1 1 0 +127 1 -5.6981160982548635 -2.4804262914214696 3.963876974872145 0 -1 0 +104 1 -0.43889931205929145 -0.6786512342031208 -0.26982380817326046 -1 0 -1 +151 1 0.38632233704260427 -6.436575550724694 0.28827602607540115 0 1 2 +60 1 -2.3388191412291297 -2.1909895686965264 5.332358036316238 0 1 0 +168 1 3.905092056046815 -3.342842649601014 0.743162620375255 -1 1 -1 +51 1 0.30821594516237355 -3.3431888641351466 2.97421468380087 0 0 -1 +97 1 2.0959982908166124 -0.09218688876005032 2.2065126859574242 0 -1 -1 +103 1 4.032770557637615 -1.033589048853706 6.026643139338357 -1 2 0 +163 1 -10.67096111340156 -2.753792851497721 2.2777487994238297 0 -1 0 +175 1 5.732332747304902 -3.395357434547403 3.9793999602240824 -1 1 0 +158 1 8.900731939704714 -6.465614302153284 2.882524782105495 -1 0 -1 +85 1 10.256991086371421 -0.03399764580791596 5.19749850902792 1 0 1 +63 1 -8.206071489694988 -0.20777550918309284 1.1337283531787357 -1 0 1 +133 1 -10.53669133454302 2.413445898515217 3.6779422317228634 1 1 0 +67 1 -6.580427997228583 3.5308019506173483 3.249950052857889 1 0 0 +83 1 -3.837130760373457 0.5948829995405305 2.7555803207629808 0 -2 1 +162 1 0.5628056325507875 0.015590885064073646 6.104541108047491 0 0 0 +170 1 -2.741308504695489 4.278253215456882 6.467354505657028 -1 1 -2 +181 1 -5.298818879016533 0.6747551441657151 5.729306597544269 -1 1 -1 +71 1 1.6643578976841618 4.095917673198805 -0.5219437486813767 0 -1 -1 +31 1 1.0515428688465895 4.152933403466363 6.1671972298548825 0 -2 0 +139 1 3.7848906674638663 3.6854393920193473 3.29399693806094 -1 2 0 +3 1 10.981379981294642 1.2656622142958476 0.9353988521574017 0 -1 1 +108 1 6.1052451115408175 0.8636547219490183 3.620998736363435 1 1 0 +16 1 8.972094495168673 3.5728016103606848 4.03251575890399 0 -2 1 +110 1 -11.360244143589199 5.991417852211969 3.108858276372061 0 0 -2 +50 1 -7.001523002421964 11.111129854490866 4.085896982012491 0 0 0 +191 1 -8.535734954334753 7.01291974923636 5.601813919122847 1 -1 0 +187 1 -10.711068400768836 11.24759510548256 5.108018843428019 1 1 0 +180 1 -1.0115990012221623 6.198904069067613 -1.8166876549028856 1 -1 2 +30 1 -0.6366171189365808 8.860606610617594 1.2441466899617097 1 -2 -1 +2 1 -1.8186886713768473 5.401678057284073 2.675711617904522 1 -2 -1 +17 1 -2.0021887273825953 8.358120841698845 5.289337562756078 -2 0 -1 +7 1 4.074924702840786 8.78812906409422 1.7171879913627848 -1 0 1 +164 1 1.8692613585489788 6.285969009685708 2.179749632062295 -1 0 0 +69 1 4.63280772470042 6.917030747154868 5.0992927825629835 0 -2 -1 +61 1 10.180483484726627 5.102933813094147 -0.6143013682078827 -1 -2 0 +34 1 7.6753980260971115 9.289346236573914 2.385702988209246 0 0 -1 +43 1 7.122060213065371 6.027541758611427 2.434097564627603 -1 -2 1 +177 1 8.528259310530697 7.357497844279905 5.573095645895759 -1 1 -1 +179 1 11.765063377112929 -11.216117555594387 -10.520782276852188 -1 3 2 +65 1 -9.939292746165652 -8.35547457034324 11.370610161953358 0 -1 -1 +27 1 -10.951259960706151 -11.676718912293088 8.46919851147203 1 1 1 +58 1 -9.681801591871107 -6.867288275839336 8.155377252027327 -1 0 -1 +32 1 -6.131008336203429 -5.3807894145123 6.404139996945254 2 1 -2 +26 1 -5.277766259873033 -8.47443173172751 9.34226968131783 1 0 0 +142 1 -2.2300264866152233 -6.734520703453221 8.54527447884555 2 1 0 +100 1 -1.5334511532264656 -10.941538235330839 6.762850724892153 1 2 0 +184 1 7.375517404090732 -7.455937963783537 -11.443563002056962 0 1 2 +105 1 1.3322147240971494 -7.892907018083993 3.959755431262508 0 0 -1 +75 1 4.579073338589469 -6.332281766890766 5.401380400098642 0 -1 0 +99 1 1.6872589572610692 -11.008904691990601 10.790406649632594 0 0 0 +193 1 2.165378393000026 -6.907577487565213 9.269079214220964 1 1 -1 +33 1 4.415243573456659 -11.651415043860048 7.196586725345009 0 -1 0 +79 1 8.562132664810616 11.60776935837499 5.9765813232044 -1 0 0 +92 1 9.7882797687825 -9.546408677583251 11.099049944831634 0 2 -1 +165 1 -9.230629586630256 -3.286419219229394 7.361693942438226 0 0 0 +199 1 -6.865681519441191 -4.960200472270827 9.951650907912764 0 -1 1 +70 1 -5.465385410624981 -2.359017759235627 7.824489075549977 0 1 1 +146 1 -1.4128831058942808 -0.5651321764460739 11.276244400666037 2 1 1 +106 1 -1.359759429785522 -2.5612049312124596 8.66030082151058 0 0 -1 +52 1 0.6275246163307096 -3.6626685091764974 11.394079726568394 0 0 0 +86 1 5.385048800206313 -4.521509414521681 8.656605720260643 -1 0 1 +197 1 1.5960773668099044 -4.632851183052137 7.050260712413685 -1 0 -1 +185 1 2.0988154112902677 -0.6155858372057779 10.039741652805866 -2 1 -2 +190 1 7.402096413387279 -0.25029457328283883 9.918579248632192 0 0 -1 +145 1 7.12421994994077 -3.662416626939269 -11.744325877649178 -1 -2 0 +131 1 11.18002293743892 -5.284301350499634 6.202872301153104 1 0 0 +156 1 -5.458324556633278 -0.38542205585237 11.508150106421377 0 -1 -1 +10 1 -9.11455987814511 -0.7284053525098189 4.7937364242043685 0 0 2 +196 1 -9.334790977795333 0.22026194254469544 8.665774918646903 1 2 1 +143 1 -7.202065049712928 3.0671354576980563 8.711576683539384 1 0 0 +13 1 -11.827431931265373 3.351396387549464 6.969024410690874 -1 -1 1 +59 1 -3.4888315694577976 1.7945900827414363 9.37212343512276 1 -1 1 +186 1 0.1399856131518682 2.5706426278242667 9.701168522174706 1 1 0 +136 1 3.4415384834588973 2.185354911818653 7.959200431003509 0 -1 -3 +192 1 10.528638878678947 2.482587032106114 9.852249456508758 1 1 1 +113 1 7.169273245351864 2.240386648237891 6.81806834338785 -1 -1 -1 +62 1 3.8919207853480167 6.881948160439718 8.99101225575 1 0 0 +74 1 -8.178685418297237 9.818884262184877 8.930172678325137 1 -1 0 +118 1 -11.577334387980462 8.493934752303879 6.984011067983683 0 1 0 +117 1 -5.265098295144998 11.327347075770236 7.5602122003602945 -1 -1 0 +23 1 -5.150793196726769 5.778029085599102 11.296630874448987 0 0 -2 +171 1 -4.323653153250317 7.139179037030907 7.775653914779269 0 2 -2 +94 1 0.595594702317225 9.593135599654605 9.048522029833913 -1 0 0 +41 1 5.495056487999116 11.528824616719037 11.673423310901565 0 0 -1 +141 1 9.858324590689726 5.708495049079261 9.011577695177973 1 -1 -1 +159 1 9.655575431519994 9.766549249024301 9.761747234830672 0 -1 0 + +Velocities + +39 3.843901085922765 -0.7556840039136884 3.588481686862416 +82 -6.7131250110640295 0.1978517371310493 3.794615543737683 +57 -3.8444246166822666 -0.12509187511770853 -0.15016726331630528 +8 2.510198026755905 3.9393955076781997 2.1890256483333417 +49 2.3436002495676416 -3.937791517692209 -0.8678317852601907 +54 0.6032383013072746 3.3962808798459587 -4.353772407339659 +114 1.733121125021854 -5.515987819958336 5.5418081738213125 +128 0.6238341583124627 -4.373836957545107 -1.8358939583013871 +102 3.7217703111263405 -2.1130321869806172 0.3604425898099683 +157 -3.060805678543839 -4.541031970793705 2.0247670855961024 +20 0.19495210236206537 0.7445218389780817 -4.9481403197240175 +147 1.300002576089047 0.4456991718445389 -0.49416915478347523 +169 -0.4362191685321444 -3.947171092840025 -1.656461237016801 +123 -4.189637911629164 -3.3929868871757067 0.6670412748458154 +130 0.6134420085318386 2.2669355259081905 -3.459678248548238 +140 -3.017718530938869 2.2011145660870097 -0.08987220236519784 +153 1.8522800493758318 0.8156876148506785 -9.385509457300062 +129 4.422122082904887 0.7131966606636173 0.3531709089212848 +148 0.6611682907987628 -0.38909659051429185 -0.4773785971811748 +119 -1.669105812009433 -0.37002694554897725 -3.3024540150626986 +174 -6.672226703796612 4.247321732812844 1.6315053674536977 +134 -3.0608984486057835 -2.4129204610506294 -2.734745807674302 +189 -2.302704208974844 3.481037259019509 -2.794714120652709 +28 -2.75682827680027 -3.050875489215879 -4.227117245181596 +1 -2.1560141369701795 4.052819594846101 5.448339653382999 +24 -2.386079256841039 -2.8280668145030563 4.35837241466938 +176 -1.4372688768932664 -6.6415313837559875 4.129983376772735 +182 -0.4720828255607976 3.662207995039096 2.519318256725504 +137 3.2869116185302323 3.2307568609578143 -1.9509349541264633 +89 0.9583454014186878 -1.6238254590624648 1.3557912965537908 +88 1.7694593220184982 -1.036030143090322 1.9233033494166958 +160 1.008621423016506 -6.119196433851812 5.640861548269096 +125 1.8734575131064475 -1.5413231325971886 -1.3731468026454559 +167 0.5552538334188052 4.600624550198432 0.10361430748931168 +107 -3.2399064229680294 -1.8236363657903167 0.5755237816639006 +45 -0.8909937912895557 3.652128037032182 0.47945125158298724 +95 -3.55734648018246 -1.7071938037895589 -0.49307606319505376 +111 -0.5877274590969576 -1.0815552570296887 1.2264280053757328 +37 -0.4940015083502718 2.120546197357239 -6.129979680695427 +53 -0.2896516389711194 0.42515885739039166 -1.8677025658203998 +122 0.967791765282903 1.7401195129115046 1.9118554789129 +126 -2.954209751448974 2.164651827051895 2.3297982456925053 +72 3.173369384034092 -3.8176084785054245 -2.272242460318536 +144 7.811875555936 4.819434744326224 0.3359991553117815 +135 0.1395889289809734 1.0258297209323288 -3.8437628564556956 +183 3.6133240015570744 -0.6507150055387017 -3.110230107415811 +155 -1.81416144798709 -3.5659788058079758 -2.041490164886604 +21 0.6092276970785621 -4.133031653047547 -1.1692481377542574 +66 -1.2540845964267104 -3.824259504042551 3.29729030480536 +22 2.5446763351186448 -0.6513499783353496 -2.0932016159863465 +42 5.82871794909335 1.6743919751666467 0.7126718280768334 +77 -0.4040118365141223 -3.2290750702108357 1.818231240430787 +47 0.028653058178313952 -2.27141290239272 0.7388413469098802 +18 -0.3605358292652272 -2.51632133097868 -2.2152302223559324 +46 -4.956822430210972 1.7347845441659948 -0.8052402055568453 +14 1.0447813005670052 1.7950897980192044 -5.120385937069129 +178 2.8613069610645323 -1.221832900100255 4.786474400939546 +48 -1.0101057057064093 -4.108390928419403 -3.626668446988165 +55 3.380329095570148 1.9767809972549477 -0.7468971412257048 +12 0.5796037236485843 -2.968894009109519 -1.109629405353503 +15 -1.0805423425753338 -0.6224135466634316 2.517980927489596 +64 2.772129192684522 2.307682180641892 1.326944641441264 +44 -2.8172327982334355 1.083586023278567 -1.8763865737567058 +188 -3.437261818925725 1.5454398749025489 -0.16540078855271825 +200 -4.575258061249265 4.788641216932844 -0.4020526553149053 +198 2.0555443873273083 -3.895983368588817 1.158820403753976 +76 -0.43680328576927907 -2.690054938184871 -3.1926091395345697 +194 -4.927518640766644 -2.7958765254010074 2.346084579105554 +68 3.8869230882195995 -4.532127531608888 -3.709193335672372 +96 0.5541428371102486 2.469654795647139 1.3292842757665846 +91 -0.732047074282118 -2.6885559423815857 -2.1949168022734056 +154 -2.5136766428597386 3.590700279102351 -0.059374328708080126 +19 -6.161653279730477 -2.8765306398549155 2.4409492942004887 +120 3.4942280062726017 -3.9836089343560284 -3.098191865520773 +138 -1.392154916395345 -2.6054126458670575 -0.5249503554366697 +9 -1.4056559546036238 -7.532778826245055 -1.3371688664267456 +150 0.5460808983742688 1.1289965684546914 0.03903574349628039 +38 7.617629027425106 5.411105913171608 -2.660628272394109 +172 1.971077098016012 -2.934759849810778 -2.6385133345793075 +29 -0.8567705552974654 6.938534740571189 1.1877415743187205 +87 -2.465817251368031 -0.5425773738872799 -0.8367656554342691 +93 -3.238874163573574 -1.2524540618123574 0.7858441913773856 +195 0.6658739747764354 -1.3905513374439 -4.4817269197268415 +149 4.447455849494194 -3.5745477247727786 -0.5281496993793596 +25 3.022648709593685 0.43914951689799137 -0.6775610151451638 +35 1.3277674074899293 0.9468507964705938 -3.026965993493294 +116 3.907132307739244 1.560341819486881 -2.1186616218198884 +5 -3.10241641974574 6.10623002683338 -0.012215259748321432 +112 -2.863798374154691 0.5948426813836486 0.35177484162268213 +152 1.5766503044655036 -0.41730163186181074 1.996501964828515 +132 -2.0634425438904502 -6.992874517268254 -0.2451331836568511 +173 0.12455810167557121 0.14574198963840712 2.9966160518510416 +73 -0.10493988646970537 0.013265555839272553 -3.9096646776491677 +161 -0.7682600042762859 1.8026603641653332 -2.7660568636516665 +78 -4.598805320864625 -0.6966368634003359 -2.729429984123398 +11 -0.9758381654162251 0.5227854122925947 0.3448945101494703 +84 2.841479136799234 0.22602223675017963 -1.9286282882334902 +90 -1.170230656537341 -0.6922100007103397 1.00880686523509 +36 -1.555842370975647 0.5631255749042902 -1.1019837065378786 +98 2.0124676556916246 0.6570695281160257 5.910973495167498 +56 -0.022897610961461763 5.352337474059436 -7.2334429828662445 +109 -0.08981766099555996 -2.306157996649536 -0.3829489041252826 +115 -0.9773922652842171 -1.500230307176322 -3.510085314469408 +124 -1.1435154328225432 2.1646855444941977 -2.677614067537958 +121 -0.6489305438370466 -5.377205725667324 6.410392354489873 +80 -2.184720009719291 -4.6495239027996265 -0.404219915911962 +101 -1.8277373470288034 -0.16307514644975357 -4.871062878988115 +4 5.273572229084702 -6.329640548895822 -0.10537322064888095 +81 -3.237096839577087 -1.2899510482475711 -0.501749653216555 +6 -2.850185972190969 -0.9855865922331829 1.2879726986158606 +166 -0.71207408822265 -1.941276610007301 -0.46670672944069197 +40 2.5501094465369287 -4.1121537776062285 -3.7730629800493616 +127 0.9391826983400688 -0.23609028118969985 -0.8428319005564415 +104 -2.889702758235898 2.6026465825944647 1.733501739951787 +151 1.0239383010373613 4.20250515830853 -2.5188428027750676 +60 0.8768242700054026 -1.4452870366932915 4.607166615214986 +168 2.6499467008683806 0.15351519699868008 -2.4173199831848433 +51 -2.7001470663696083 2.298050292705142 -1.8727439352999022 +97 4.077411493370136 -0.49363711607361804 2.618893169202227 +103 -0.7976469434966291 -2.8296239792549494 -3.1085019733170576 +163 1.4239083858918546 -1.7152330037559187 -3.7262201886107413 +175 2.28608354457103 -5.013082617544787 1.9463144730607622 +158 2.364724804444635 -1.417965451640216 3.3110988056960116 +85 2.634049111053192 2.030183273599258 -1.1156959044778305 +63 -2.5594596368644584 6.5807348164634165 1.2216612365119401 +133 0.11496856368877509 -1.3029278864933922 0.3137832360475215 +67 3.2847742901460815 -3.509493405431694 2.207008202574443 +83 2.570557721108847 -0.3717669874940476 0.19918880069367745 +162 3.0399699011039054 1.3116112714661063 2.674382531726811 +170 -1.38109599459742 3.3822351643604485 2.3645182440787846 +181 -3.229104480841883 0.4809626947427979 -1.0038042842684436 +71 3.9132675825937917 1.4930647145750953 -2.169388439547446 +31 0.2080392077753374 -0.7175240437209078 5.244126748535574 +139 -3.2722113265821164 2.403646928095839 4.89007181946881 +3 0.23844888496446556 -1.2064671761077215 -3.765272552252597 +108 1.9533881124972572 2.2407632376201616 2.7809203919337717 +16 -2.546655497698339 -2.9475172512416052 5.679217575496501 +110 -2.0619258300646304 -2.5135908125338595 -1.9634278842507895 +50 2.7297022478135924 -1.7023753942716038 0.9305543045166054 +191 -5.08419299322051 0.0712033790584315 4.019663294315123 +187 -1.1602692653736124 0.6592040176624594 -0.9276587772961099 +180 3.9270482120535912 0.7337070019018614 -6.1521791130682715 +30 2.146405625539158 -4.470711382216746 2.4389136902743624 +2 -2.164694698633498 -3.946038803617009 -6.932908852758065 +17 -5.0136316664846525 -4.910395378878622 0.2531438520391362 +7 6.405139093241594 -0.029320522419797518 -2.4556700372713656 +164 -4.71978957162196 0.7565882723845814 -7.804804192177828 +69 0.585325244096323 -4.172549570259053 1.421305529899283 +61 -1.2969434367599055 0.21371727493194503 -5.996553017036012 +34 0.836211095631979 4.842199148306591 -0.264740483545493 +43 4.973431404758735 -3.0161637272673114 0.6585207320279483 +177 1.9972180553856484 2.8405653312769714 3.7936113983454574 +179 -1.8016662165736297 0.17922718595288942 1.675961420609039 +65 -0.3262344061357664 4.502937830108041 -1.6925046570602365 +27 3.2148912674329595 -4.265923914349978 0.20837858074619325 +58 -2.5148141053183966 -3.410776250506333 -4.126435252324821 +32 -3.9688004644027894 -4.975859333985981 -0.31037975343014773 +26 -1.8868624613436276 -0.6784023280861808 -6.9019978159434325 +142 -2.2655622806415803 5.065238482808602 -0.5612653461135326 +100 -3.1689440110918863 3.611829368506524 -5.535634657025687 +184 1.155071447769214 1.3970696009831187 5.21877428678114 +105 -1.0527289600189955 -0.359868396602688 -4.314898952688254 +75 1.1126434309490583 7.161365583137096 -6.8797286508213995 +99 -2.2511573267704605 4.325930022921806 -4.536664094156967 +193 -1.8538759123569282 -0.3771359852226918 1.3265167612281819 +33 4.043103770190031 -2.463191434468879 0.2825585567463736 +79 0.8247934215179962 -0.8593180918731026 1.8075425908507756 +92 -1.9872298962564725 4.526116206000229 5.875185828559399 +165 -0.9325271408003691 1.9234746099504088 0.09139445808177141 +199 -2.4466143796538278 -3.5392337118481905 0.07336564176962056 +70 1.6955535004916 2.7542669443749292 -2.844202030673744 +146 -2.7188074197448584 1.8546678027188679 3.404472056065058 +106 1.6207845192963544 1.2164210998710923 7.1450165172108 +52 6.210256198054289 -2.1514980948844977 -3.0246733234381606 +86 -4.166581136807711 -0.379450814784322 -2.11423926273923 +197 -2.0944322960049 2.1097024434581955 -1.5699756741420037 +185 0.496431323422778 -0.673746468047717 1.6256733179580487 +190 3.5894390751435754 -0.5232916689073732 -2.5898259464521436 +145 -5.060692392767518 -3.604348262830216 8.963086293155014 +131 -1.7493649096325448 1.9215551392824017 -5.654561521157757 +156 3.0486560090093078 0.7623397112130897 -0.6623326467666147 +10 -0.3025813929631971 3.8012367067722552 1.7944918683195408 +196 0.20779509519657535 1.1724947587327104 -3.2497684331092898 +143 0.1615216816901657 0.541965759645283 -0.3699391852573772 +13 0.3416281793998905 2.006587618812918 -4.356326172952984 +59 1.6542517855144645 1.9404536050042447 2.6385288647359855 +186 -3.4589984191612237 4.344929883747252 -2.4261876990284055 +136 -1.052237178030063 1.7981079687785935 1.5452947189881334 +192 -1.8283033036376375 -2.1460456664281984 0.4532252919540826 +113 -0.07210257811201395 0.4448121853700756 0.4002442722770919 +62 0.07671657245048122 3.988794018720988 -1.5215067553007326 +74 -6.261763851450271 6.841230877971418 0.19948931371832682 +118 -4.55843930988713 0.7045880922983706 -1.5541929923380147 +117 -1.7138030815767766 -2.2218466460669197 -2.4862510267677966 +23 3.4139900995951797 -1.2153416151189098 1.5870813641624815 +171 2.9673700826094715 -2.730113253007238 -0.013674771129509489 +94 -1.559158449433541 -4.089352807642382 -4.9936243516296415 +41 0.05830786336808787 1.0332428056957692 -1.4731928753411638 +141 2.0403501209228514 0.38114816689047215 0.2637593201666092 +159 -2.276370624127765 -5.5130320242721425 -2.201507053272948 diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt02 b/examples/PACKAGES/pimd/lj/data.metalnpt02 new file mode 100644 index 0000000000..d48c9e654f --- /dev/null +++ b/examples/PACKAGES/pimd/lj/data.metalnpt02 @@ -0,0 +1,422 @@ +LAMMPS data file via write_data, version 8 Feb 2023, timestep = 100000 + +200 atoms +1 atom types + +-11.876696863105703 11.876696863105703 xlo xhi +-11.876696863105703 11.876696863105703 ylo yhi +-11.876696863105703 11.876696863105703 zlo zhi + +Masses + +1 39.948 + +Pair Coeffs # lj/cut + +1 0.00965188 3.4 + +Atoms # atomic + +39 1 -10.348412656724513 -8.709686235988883 -8.4270990310572 0 -1 1 +57 1 -6.076254771403757 -9.286388884881402 -7.702702502017148 1 0 0 +82 1 -7.550388144071918 -7.009510153923324 -10.103430125234938 0 0 0 +65 1 -10.007477542149314 -8.426774632489874 11.409858756818739 0 -1 -1 +8 1 -7.164995520412905 -11.038468804393306 -10.58636480246276 0 1 1 +49 1 -0.45959797061569213 -8.711842576893478 -7.759689256680434 0 1 0 +54 1 4.335836096446666 -9.860468354448713 -9.596810041931791 0 -1 1 +102 1 2.5723817340883883 -6.321599469181216 -10.836018784654463 1 -1 -1 +114 1 3.9633708583907534 -8.59122246718616 -6.211421303718058 -1 0 1 +128 1 1.6111319524977374 11.42178725036819 -7.424763349756333 0 0 -2 +157 1 6.676723241532642 -6.249807038476984 -7.434858543313773 -1 0 1 +20 1 8.180031746693997 -11.224906976375225 -9.914700910890055 0 1 0 +147 1 10.552595438745763 -5.846535200951102 -9.39377855844701 -1 2 0 +169 1 9.349136090221942 -8.979140149397233 -6.8265579785125965 0 1 1 +123 1 -6.855446583817184 -3.2640394531559696 -10.949254791001273 -1 0 -1 +130 1 -6.535059536526429 -2.567484128692307 -7.041716414515715 -1 1 0 +140 1 -9.06855871809178 -1.3542845787289544 -9.224892837601802 -1 1 0 +153 1 -4.569518029474378 -5.203914109037015 -8.781875667281184 0 1 0 +129 1 -0.2299073567614939 -5.077417463604178 -8.55580527821163 0 1 1 +148 1 -3.144987560803104 -2.0908434236033218 -9.879429686918634 0 0 0 +119 1 -3.5411143846194992 -3.8360561641889532 10.696563632316428 0 -1 -1 +134 1 -0.04545170129816967 -0.3594090384455699 -8.557611667254108 -1 0 2 +174 1 3.1061081743214345 -1.9799957752444968 -10.724581364205001 -1 1 -1 +189 1 2.8769937819916396 -1.3674240720053161 -6.389788220787231 0 0 2 +28 1 6.237115641177313 -1.1545998190288946 -9.272228860156012 0 0 -1 +1 1 7.549394959535029 -2.854734791893552 -6.538590887699934 1 -1 0 +24 1 10.883729099000904 -2.1271876989337706 -8.117545982704844 0 -1 1 +176 1 10.267930709995003 -3.6438442151633126 -4.343476582694092 0 0 0 +182 1 -10.786266284256198 0.5593263120798149 -5.188887623332871 0 1 -1 +137 1 -8.253864841052525 3.7298295620111226 -8.568533527553154 -1 1 0 +89 1 -5.794201120520342 0.9380076791670935 -8.557102414588634 0 0 -1 +88 1 -3.290466618666769 2.666597373561615 -10.965754432660972 0 1 -1 +160 1 -0.18201736379451042 5.440877252854083 -6.045408976448922 0 0 1 +125 1 -3.2721098231201498 3.482326329512073 -7.20800643325733 0 1 0 +167 1 2.6838478408055124 2.662941774470184 -7.446400398896404 0 1 0 +107 1 2.461769881852174 1.4723823486650787 -11.23948224456525 -1 1 1 +45 1 -0.32643148409171074 3.4132158246810462 -9.890588978502432 0 1 0 +95 1 7.12050576869771 1.8830305880227627 -11.021337217501824 0 2 -1 +111 1 11.302810293745958 1.3519264206984616 -8.432303785348612 0 1 1 +37 1 7.499987535787309 1.5957548452787924 -7.727720303674275 1 0 2 +53 1 9.440512427968931 5.294797843867766 -10.137582763727357 -1 -1 1 +122 1 -8.602536179448315 11.512272015578171 -7.106756749836173 2 -1 -1 +126 1 -8.684507097426447 9.102724910576027 -10.228076159133025 0 0 -1 +72 1 -11.212168106684132 7.24750708554837 10.879317278944692 2 0 0 +144 1 -3.026583839716779 -9.884067057114146 -9.895519067990667 0 1 1 +135 1 -0.0021296445465068814 7.861337183488864 -8.408004375424728 1 0 0 +183 1 2.8552963287326403 5.197557014594176 -10.04944592034365 0 0 0 +155 1 3.763607040992876 9.197661654352766 -9.383705258407385 0 0 0 +21 1 6.743085276662367 6.819489412060577 -8.245771575257553 1 0 0 +66 1 9.52403312105875 7.459476022143324 -6.138585785756646 -2 -1 0 +42 1 9.12856561120073 9.359598065403702 -10.255808680046007 -1 1 0 +22 1 11.084937277836246 10.7346270298744 -6.189336343510782 -1 0 0 +47 1 -8.79851480543095 -8.030651717047036 -5.3995272670275725 1 2 1 +77 1 -6.824604399212273 -10.927075660857042 -3.894519486445894 1 -1 1 +18 1 -10.638894292838417 -11.301447222259686 -3.92180055862298 1 0 -1 +46 1 11.290286356240586 -7.674430365874162 -4.055829279128204 1 0 -2 +14 1 -9.506577112536185 -7.441780453176744 -2.0080876276818103 -1 0 2 +178 1 -4.543756730558393 -8.097143654115143 -4.784790404681888 2 1 0 +48 1 -3.2444312260629573 -10.940861821243079 -6.354255167480908 1 1 -1 +55 1 -0.9464860706310958 -6.285996525353373 -4.30908825600282 -1 0 -1 +12 1 -1.856123326430506 -9.517447392023085 -2.3435724928975645 -1 0 2 +15 1 6.077305695814157 -8.166300444221115 0.7448836933119019 -1 0 -1 +64 1 2.7452944971646858 -10.558129575009149 -1.730050297615053 1 1 0 +44 1 8.116024736633927 -6.297043957734161 -3.618119081228304 -1 0 1 +188 1 9.990490631214506 -8.453825757862562 -0.7847723993749525 -1 0 0 +200 1 -9.371399961242005 -3.371895968187197 -5.193597997968697 -1 0 0 +198 1 -7.163187216472317 -1.1934858004192783 -2.2622400054633864 0 0 1 +76 1 -9.919958613706985 -3.040871792288106 -1.4149931903428534 1 0 0 +194 1 -6.743945843921815 -5.005230021567819 -2.613393963742155 0 1 -1 +68 1 -2.5671189668335317 -3.434435519320573 -6.1465461411366 0 1 1 +96 1 -3.430661147431614 -4.018545052073527 -2.021400662533695 -1 2 0 +91 1 2.9683873682514026 -6.254217834947031 -2.3589109971891737 1 -1 -1 +154 1 -0.2218228203315391 -2.902150057925404 -2.9725706529414366 -1 2 0 +19 1 3.2665435171804194 -1.9817522239515633 -2.3096363660640975 0 1 -1 +120 1 6.609146288179666 -2.2318382061287565 -2.808377349441308 1 1 1 +138 1 9.631227201052864 -4.547744518411388 -0.6709487904267171 -1 1 -1 +9 1 7.596887391638223 -2.0237588049028696 0.6051605861836649 0 0 1 +150 1 -10.044973671786467 2.0147581633676452 -1.3897952482345524 1 -1 1 +38 1 -5.7978106400822895 4.770632320137689 -4.758054319452569 1 0 2 +172 1 -9.658785222083136 4.026164557116778 -4.942402258050777 0 0 2 +152 1 11.431334273176418 -0.4623515239881826 -1.925450909701469 -2 -1 0 +29 1 -7.909238416570071 7.61624491229837 2.2042493522591258 1 -1 -1 +87 1 -3.3103551172038665 -0.94337019011639 -3.5930404382745955 0 -1 1 +93 1 -6.2863195662557 0.9404795536165196 -4.898675396085437 0 -1 1 +195 1 1.0245553543549981 0.20159488775043144 -3.679042462676364 1 -1 3 +149 1 -2.269526344184385 2.8074136653426387 -2.5814855370744945 1 0 0 +25 1 4.649154714287583 1.2394738761102164 -0.6186508337325307 -1 0 1 +35 1 2.8516234465534787 3.745844200453856 -3.7667964552544286 1 -1 0 +5 1 5.795606814798939 1.5285888723891716 -4.179888075744685 0 -1 -1 +116 1 6.001522247841404 5.755884373452364 -5.02433183427119 0 1 0 +112 1 4.844016623012077 5.465934695953432 -0.25432767294668557 -1 0 0 +132 1 8.53939720077536 1.8213558063438606 -1.3830903771567364 0 0 0 +173 1 9.062655610340409 3.8664027467280935 -5.47150892329001 0 0 1 +73 1 -9.979257287380412 7.98839910326609 -6.702836934882303 0 -2 1 +161 1 -11.50425364162053 7.022415057658153 -3.488322518144713 2 0 2 +78 1 -1.7469625877850241 10.184158454427994 -1.7648096425042503 1 -2 1 +11 1 4.444644958846757 11.851997915189173 -4.933412264679578 0 1 1 +84 1 2.459047681073617 7.373812748831801 -5.213139361825189 1 0 0 +90 1 6.1482860548874925 9.307626902509035 -0.9026751698054234 0 -1 1 +36 1 1.9695381713294537 7.78336838361963 -1.7729647147442544 2 -1 0 +98 1 8.527874795717773 7.612035599231426 -2.9325216125652 -1 0 0 +56 1 7.282783408448612 10.400831236794666 -6.728973679619628 -1 0 1 +109 1 9.156728968120607 11.308407539099598 -0.9040861597803378 -1 1 1 +115 1 -7.309621980156194 -8.117595813105002 2.8126740615279595 1 0 0 +124 1 -11.142069858043358 -8.82667541719755 4.10932707265772 1 0 -2 +121 1 -8.21003433895173 -10.089956822420406 6.660752548831763 0 1 -1 +80 1 -4.909425537698309 -7.256236799158399 -0.2747148144591023 0 0 1 +101 1 -4.312342956814611 -8.070113074572049 4.879741561255617 1 3 1 +4 1 1.5494925162428856 10.03102296069128 4.602107842780676 -1 -1 -1 +81 1 7.27113702294054 -8.472013640467047 6.625505444757195 -1 1 1 +6 1 8.885736885591768 -10.557271403060728 2.7878338185404203 1 1 0 +166 1 -8.69650192512206 -5.07362796560642 4.236148217669305 0 2 0 +40 1 -6.987849762900474 -4.511534637942379 1.3175075163680883 1 1 0 +127 1 -5.689629608203652 -2.3907227510814337 3.9463589292537864 0 -1 0 +104 1 -0.4397363632556015 -0.6165598923688651 -0.3313279093278112 -1 0 -1 +151 1 0.4300685018079994 -6.441488457556783 0.38045612640805615 0 1 2 +60 1 -2.3217820522915846 -2.1704723730197557 5.333166404467865 0 1 0 +168 1 3.9149834819211655 -3.3791911515481985 0.7567189672094479 -1 1 -1 +51 1 0.398133835057336 -3.3931578730294385 3.016370538231655 0 0 -1 +97 1 2.1573351041413034 -0.0855884286300217 2.2286851783702524 0 -1 -1 +103 1 3.9664988893980713 -1.064731427067052 6.037166605284854 -1 2 0 +163 1 -10.709566329240587 -2.7332402144894417 2.2660820588417665 0 -1 0 +175 1 5.762755562271241 -3.3856559659466114 4.002375112428048 -1 1 0 +158 1 8.862173003831924 -6.538751027751994 2.8769202677556542 -1 0 -1 +85 1 10.229250850148503 -0.01502947727190853 5.300096059690905 1 0 1 +63 1 -8.263417127255543 -0.18022873161562153 1.17510825734459 -1 0 1 +133 1 -10.480766232506394 2.392923584409271 3.720879727063737 1 1 0 +67 1 -6.544234163722191 3.501038541004621 3.191437971422375 1 0 0 +83 1 -3.849802400718045 0.6646468573486004 2.7446055069817703 0 -2 1 +162 1 0.6098193007635196 -0.05324811248282152 6.154363200071202 0 0 0 +170 1 -2.6786368359767714 4.255168732248176 6.435570102352074 -1 1 -2 +181 1 -5.252793067773865 0.7761154003139943 5.79909696611136 -1 1 -1 +71 1 1.6452911952303246 4.06622820161267 -0.5166203216146883 0 -1 -1 +31 1 1.0738987741436463 4.15303788757344 6.141061091921109 0 -2 0 +139 1 3.8104659718300624 3.693576878280304 3.384062081506274 -1 2 0 +3 1 10.9858871588246 1.2545617976234098 0.8570931258327192 0 -1 1 +108 1 6.174388178357244 0.8538858651722911 3.6472942727893374 1 1 0 +16 1 8.97282237909764 3.5943899325206274 4.02632096928566 0 -2 1 +110 1 -11.336507152318017 5.947474598331584 3.14037651741927 0 0 -2 +50 1 -7.046202899905131 11.083294806174674 4.036430331092051 0 0 0 +191 1 -8.508890702823583 6.994301261898876 5.5988324620755945 1 -1 0 +187 1 -10.749519222803974 11.280267500561628 5.071750333310352 1 1 0 +180 1 -1.0032349913124285 6.140237973021502 -1.7436540397788036 1 -1 2 +2 1 -1.7946548786825645 5.404613901091388 2.68002365908378 1 -2 -1 +30 1 -0.6282593143948212 8.881746166196663 1.2420280890418454 1 -2 -1 +17 1 -1.9971151666590217 8.252473054961822 5.30244560397972 -2 0 -1 +7 1 4.0488432159812255 8.81693522673231 1.6114995620401231 -1 0 1 +164 1 1.873438403508949 6.222826359057496 2.2533705281578316 -1 0 0 +69 1 4.6051775335846745 6.921132428828564 5.128620799236167 0 -2 -1 +61 1 10.268176907196304 5.08172043450454 -0.642274843845057 -1 -2 0 +34 1 7.601946368008498 9.256904252690223 2.406585955238384 0 0 -1 +43 1 7.165450199452092 6.0290506218302085 2.4419163969738023 -1 -2 1 +177 1 8.561622776612461 7.244917835893727 5.602147565752702 -1 1 -1 +179 1 11.750057623239174 -11.228395927014766 -10.487778908482419 -1 3 2 +27 1 -10.974224751020245 -11.635298968202441 8.509409995684443 1 1 1 +58 1 -9.692847117546727 -6.99702076150861 8.089242933510139 -1 0 -1 +32 1 -6.165044846878473 -5.3531372054847 6.419358142287187 2 1 -2 +26 1 -5.15775210282499 -8.509724647787523 9.35521475378418 1 0 0 +142 1 -2.2394120995772013 -6.757001235575803 8.53817557952535 2 1 0 +100 1 -1.562747759528225 -10.930435349230905 6.862796976881519 1 2 0 +184 1 7.329483236732028 -7.477553906204161 -11.457403276020457 0 1 2 +105 1 1.3124523565691075 -7.852976862538032 4.005035595809602 0 0 -1 +75 1 4.597924698307231 -6.283694211187047 5.476806400599068 0 -1 0 +99 1 1.716773073271929 -10.998458790026556 10.715096401091909 0 0 0 +193 1 2.1325154242736666 -6.931854968739277 9.419307764840358 1 1 -1 +33 1 4.48712925680286 -11.671378658171115 7.267170381111049 0 -1 0 +79 1 8.573107089496888 11.611228502272368 5.983087465760138 -1 0 0 +92 1 9.81601068917706 -9.527916362770739 11.159627680682005 0 2 -1 +165 1 -9.2113400341349 -3.219195257680457 7.288219778779848 0 0 0 +199 1 -6.931272020823427 -5.000130571946396 9.88597891452116 0 -1 1 +70 1 -5.507541862888313 -2.393142934597723 7.807143673901248 0 1 1 +146 1 -1.4771503758916822 -0.5410305896302106 11.279923136114263 2 1 1 +106 1 -1.3651808664767915 -2.54616781259121 8.590647351661577 0 0 -1 +52 1 0.6779843498698166 -3.7311606456725768 11.453754175953545 0 0 0 +86 1 5.4031998049641565 -4.549788149287394 8.596350093940629 -1 0 1 +197 1 1.573548668834416 -4.687213943022477 7.1278633337641 -1 0 -1 +185 1 2.1532991864501554 -0.6046775517606129 10.000779301772766 -2 1 -2 +190 1 7.401787297285096 -0.2505978640044338 9.870584022136198 0 0 -1 +145 1 7.111702440333872 -3.6540730490844453 -11.814469255040187 -1 -2 0 +131 1 11.130905707249603 -5.281990426153451 6.209567942496238 1 0 0 +156 1 -5.482768650143603 -0.4312680407464029 11.466238929392272 0 -1 -1 +10 1 -9.053182404201642 -0.711645217691651 4.8230146575990815 0 0 2 +196 1 -9.337441409320208 0.1609718702750058 8.663781619737854 1 2 1 +143 1 -7.17068301465806 3.0756929715249197 8.74321294778271 1 0 0 +13 1 -11.784452395762827 3.289072175663378 7.001527553636599 -1 -1 1 +59 1 -3.4378714190696336 1.7721863061771366 9.36771463550879 1 -1 1 +186 1 0.1662370132365254 2.5243181917810595 9.709168312215267 1 1 0 +136 1 3.4094152339708126 2.153729603693705 8.008621315534214 0 -1 -3 +192 1 10.489678729236587 2.4935818679754185 9.842929691077494 1 1 1 +113 1 7.1536296108923345 2.1797090477435894 6.8304033834765505 -1 -1 -1 +62 1 3.9169396613561496 6.861682724751661 8.976027690230366 1 0 0 +74 1 -8.118378807759774 9.793902614888827 8.932362315849124 1 -1 0 +118 1 -11.58583737453999 8.536873240765573 7.014861349235567 0 1 0 +117 1 -5.277108589074334 11.352800033973235 7.597327201748058 -1 -1 0 +23 1 -5.157626384085098 5.75340956696832 11.215724105856438 0 0 -2 +171 1 -4.306475221375887 7.1666374724202555 7.827635610104089 0 2 -2 +94 1 0.5173001347371304 9.700900025717369 9.033047100941438 -1 0 0 +41 1 5.490142462338115 11.510392579949611 11.613725539319557 0 0 -1 +141 1 9.87566572043054 5.774221219191659 9.0665289512053 1 -1 -1 +159 1 9.686865955901812 9.753371327924555 9.75057962979839 0 -1 0 + +Velocities + +39 -1.9399818993193945 -6.2245952285602995 3.5338548174142916 +57 1.5287860491005811 -2.72214429330134 2.2456706435699694 +82 4.011405667244886 1.5297461738282854 -0.00848199347765205 +65 -8.99687886174914 -3.5904944014362874 -0.24257004026483364 +8 1.3456043077490425 -2.128460026427474 0.5438548397418695 +49 3.9804563992312922 -6.033137289721198 -2.4992971438276896 +54 -0.8797092038138496 -4.4441361344158485 -1.158307352101043 +102 -1.6073661483672754 -6.3013772766305705 -0.8971841583061024 +114 4.952776653242985 1.9508143607180544 -4.637659613505405 +128 -1.269058654850369 2.9109256516813193 0.4053666332013952 +157 -1.0484348115580815 1.3302695757858152 -2.3230656835483483 +20 1.6286859684439459 0.8384182438479687 3.337320080806048 +147 1.7009416069818912 -1.6078420463299883 0.41513271531119245 +169 4.488200687237288 -6.490934602483694 0.13987631822178037 +123 -2.8913963004993426 7.445402407235762 -0.2708525381058624 +130 -1.3405859620177862 1.4399831113332697 0.048073865645907876 +140 5.071347652434061 -0.6702612789643095 4.605780995472893 +153 -3.7972143859475698 -0.514917067426214 -4.9181301157390225 +129 -0.524987732421045 -3.209340969084892 2.932495986872108 +148 -5.447057077277419 -1.4060679681657386 -5.483184347880067 +119 -2.5629223421862375 1.3882127095818109 2.83591016397441 +134 -1.3621064953428361 4.288456433365155 -1.6190478694645496 +174 1.7758446648889914 4.86331991854285 1.1265592480566544 +189 -2.1997618638118066 -5.481413979755256 -1.086026577758521 +28 0.47277982211285713 -2.417172577737755 -1.932990476216946 +1 0.6703800334847378 0.767366418061703 0.19201532965448842 +24 0.04297238333671294 5.144308305848863 0.078997482901074 +176 0.4965479246937361 -0.13321844730810892 -0.13420426694661658 +182 -0.03943631525057928 -0.4576897656157408 5.202139202652978 +137 3.3038160138315282 -2.8142339694373977 5.5902387847740025 +89 -0.7210799083306686 1.5890809944259632 -0.7203455040724582 +88 1.0693506358892855 0.004219772825099388 -0.34637529725335453 +160 2.818428049318086 3.2244292228167537 -4.494216600884747 +125 0.42818621594139183 3.1889923789665167 -0.2889418149701054 +167 -1.634028108672504 2.274964875925839 -2.5010575325085713 +107 -2.275260397982265 0.40965124117591156 3.7368455922538386 +45 -0.7001662440449031 1.119455401379465 0.23148546097076927 +95 5.262372995855103 -2.4350400461030928 4.204427583146448 +111 -2.8606969082837232 -2.7980553847036016 -5.595977877258418 +37 -2.2899225677006445 -0.8948602257995134 -0.4803200724258121 +53 3.002131309420766 2.6120771462261168 -0.9952903525863226 +122 0.8674217257039606 -7.734997952666523 0.833404061351757 +126 -1.1420613062006533 -4.550118096866477 -4.2790463933780245 +72 -1.8516741228057083 5.947761028964626 1.6102399224289305 +144 -1.1917460086100382 5.214371411898472 2.577241700331775 +135 -0.6560595442322588 -5.810339924107932 -4.318267593309593 +183 -10.386809746296331 1.1897898885572993 3.451816626760367 +155 -5.162635743080924 -0.24765733386766664 -0.9110712844247615 +21 -4.2563878171076155 -3.402344841498928 -6.759865341543254 +66 3.892260841699981 -3.872668437572034 -0.3337143786545691 +42 0.4166666127989469 6.100606589949791 -1.4397576055696024 +22 0.3608663266598049 -0.6522614903150212 1.896193166731318 +47 -5.327073086748509 -3.490472671050769 -0.07383525372930849 +77 -0.978728222397191 3.4020107799172736 1.0077489411757843 +18 -0.4650542307772494 2.9718359172432747 1.4633800163719572 +46 -3.027050149464662 4.17167624743228 -1.827230734431756 +14 -0.09677720578549692 -2.7193038262530447 1.7914199983541117 +178 3.696002315695369 1.6876713658009856 -4.672832052845037 +48 3.983692149992739 -1.1833239408832328 -4.299433489091069 +55 1.4078039475385906 2.056934505867413 3.7406982539078393 +12 -6.525348764219679 3.3122244911450394 2.6197769407714624 +15 -3.3141834562011994 0.5054069138851847 -2.97725365266652 +64 -7.771910612976191 -4.581106933347833 -0.41638292972909086 +44 1.6412238745050067 -1.8908109366759165 -0.06612343065785803 +188 -3.5844091539515395 1.8268122826497 -0.2374993089904055 +200 7.894813073634868 0.057995156825788374 -2.5771892403060033 +198 2.1286980919165597 1.0207578884216715 -2.002608806720997 +76 -4.082585877193767 -3.634723448931757 0.6497689857802457 +194 -5.141422516595061 -5.385767090831518 4.1044833771883145 +68 -1.3677719930905985 1.0604606148180302 -1.7254671966550923 +96 -2.592687583785919 -0.5546395167068001 0.38605262002135754 +91 -4.294011884932044 -4.480411411848511 4.543287343202344 +154 1.815487275814105 -0.07008532516876564 -4.441392134697374 +19 -0.24976249513756998 1.579721447829149 -1.7421975373515703 +120 1.804118819372854 0.520165481785893 -0.866356354838586 +138 0.7160603181741005 -3.5316114730742316 2.8815518324723897 +9 -4.1756988875943195 2.0672991466342374 -0.8825046873416664 +150 1.815083623557248 2.773051884794719 1.9746918971798604 +38 -1.502458122060807 2.504120522003904 3.5630087040476006 +172 2.925371783317832 -4.008067088721308 2.95272814084428 +152 -4.6300230395213555 -1.2429914909034638 -3.848634119515747 +29 2.326120452340355 2.730479927388889 -4.850062460498464 +87 -3.7757652246448092 -2.144244861787354 1.0169754355289107 +93 -2.0873983214067384 0.5358760575940038 -0.23325341995082138 +195 -1.4168233936677792 2.3959259540484603 -2.0506018284590537 +149 2.2841089396850274 0.26447423100144896 -0.8987301521306412 +25 2.8990369033774663 3.4475964151025584 0.06622887609588958 +35 -3.439056984685437 3.8288190767067634 0.5330155111995796 +5 1.1832213107046619 -0.3877998693431248 -1.369194610956917 +116 -2.0849829431786198 -1.7654561629509715 0.6633937705540919 +112 -0.5822227923488573 0.3013831835536517 -4.31387983328802 +132 -4.968232076425547 -0.6461873308157724 3.153818258163696 +173 -2.606365772909947 -3.929167709306097 -2.1504295970222675 +73 1.5595598163445097 -0.6161933298135185 6.6258235518245785 +161 5.1614226588847085 4.911303681383577 3.193451794720913 +78 2.399770604666089 -1.7368694007148553 3.13840955491289 +11 -0.1723279344217883 3.2117525787482495 -5.003125430736541 +84 -3.0246026160032238 -0.10349126829912314 -2.244471367403812 +90 2.2752472907587027 0.5192129247104318 1.739661062051631 +36 3.3131943405122586 -4.945706489020841 0.7304326039438429 +98 2.222390966846857 2.076728811998776 2.745752031197498 +56 3.2308827790046997 2.20226369176158 -0.16256864643069302 +109 -5.432919034165497 -0.6507653252627013 -2.288197504123378 +115 3.2470353212929526 -7.326498442980268 2.0848162375252226 +124 3.23326108206676 -1.3727946801269606 -2.040624527813595 +121 4.263689866797482 2.7161360736926117 -0.9353436003014414 +80 -3.183923910858363 -1.409115057483441 0.20655585479413852 +101 1.8647413072811272 -5.138741167769708 1.449442652238715 +4 -4.059920467104848 2.021712460074869 4.0296908872357 +81 -1.4496413113665318 0.22275997734715647 1.0204012050853233 +6 -2.5319674910604797 2.921972066778776 -0.5937144564354684 +166 -1.7032554189048639 0.4271452228969883 -3.929596648952609 +40 -3.2997667945300786 1.7569019147151133 0.9556994202850172 +127 -4.094479436855724 1.004173845399162 -0.957686162248562 +104 5.839775077994146 0.5614942472461542 1.3388300846640222 +151 0.03681474392662332 4.158212179208171 3.087410074045597 +60 -0.5753595098363337 -1.944185172990125 -8.542198180005448 +168 1.356831683366837 -2.3643099268420564 3.337777267437989 +51 0.594767745409305 2.5443394223058013 -0.5744844027146594 +97 -1.4592614460552826 -2.9896997140291077 4.468909988652328 +103 -1.7464552873436274 -2.725030040682925 -4.682984068370838 +163 -1.6811327453491027 1.203374785043913 -2.52756154734346 +175 -2.36073693749339 -3.2083472883959288 -2.522379591971816 +158 2.0901462213047384 -0.8790568223757592 2.862349710125339 +85 1.6955544698562546 1.329401432748634 1.339424168209504 +63 -0.9387866016534254 -4.101481886236126 2.5768942521591023 +133 -3.3950934863801323 -1.1853227351766746 -0.8938618367927571 +67 -4.93636647331341 -5.808321017441839 -1.5826220082758682 +83 -4.348910184667013 0.5721399223517865 -0.7197270365001088 +162 1.9809720767805532 -3.8356819219002203 -1.5209517397218844 +170 -4.1339290337428345 5.621618700525048 -1.5836709740423311 +181 1.1838126543084162 -1.2107904166348504 5.997389392830687 +71 -3.6322706258882382 0.4573448065249036 -3.4819929402094774 +31 1.5672965345476493 -2.5171072174405418 -5.016079150444441 +139 2.347944365043533 5.087068349207903 -1.4373175728413294 +3 -0.6897541703497496 -5.2109972760726215 -3.1967261285849102 +108 2.1632029794076 -2.3278780023196486 -2.2165896316468543 +16 0.5518752214748219 1.7443113317844785 -0.3914314868799459 +110 0.6545696772446776 -2.3972319991341955 4.869786319607602 +50 3.4589447101316337 -3.631848006300771 3.113137145447494 +191 -1.2968299225913498 0.4433703369757638 -1.5568387599668925 +187 1.9322905031758904 1.7630376183510783 -1.713007037692872 +180 6.8380544057940424 1.3883512491464782 2.155270210489675 +2 -0.9447291546303294 -0.0513923732527517 -3.0672808505869886 +30 1.6158645533289293 3.1155851081317145 -2.1710811001472363 +17 -1.543787339459575 3.1374805002054007 -4.413979305864849 +7 4.040936876599553 1.9639386370487468 3.3637852508743804 +164 1.4392327984967968 -0.8254697339648331 -0.33613984139186426 +69 4.683013019846548 -1.4001774602376138 2.7483283024733463 +61 4.859801586904617 0.3945575299928299 -0.36030106753723035 +34 2.144274218554215 0.30058665232035375 1.6815154302941946 +43 -2.262284846661947 -1.933549681130589 -1.7228919249476684 +177 -0.04379017544723046 -3.0489629385721146 0.8031465712034731 +179 0.1618165357299699 -0.15566873489305255 -1.156913000807537 +27 2.280685460437968 0.25990101487970774 2.9095092475822724 +58 -0.6292223334449243 -1.0309616093739953 -3.156937935356546 +32 -0.011281818866179849 -0.9102886141888968 3.1492471714773824 +26 0.3704942133027209 -1.9855236287495084 -1.1813125622083982 +142 -1.0547774115337973 9.781673444693524 -0.5474605098370294 +100 -2.466739505935093 -2.401234723424822 -0.9166143227115303 +184 0.998183931841219 0.5555844351868584 -0.24866844568146534 +105 -0.9091746414938665 -0.6852682268807229 -0.5049408850325867 +75 -1.2458876998256998 -3.70960636595479 -1.979594195572476 +99 4.943544682867021 -2.8438984768476887 -2.114165836507449 +193 1.6648153391738203 1.9396654116178769 -2.563892949279256 +33 -1.6878161438450656 0.40927910646954185 0.5582734801758544 +79 -3.538909021595642 3.805204310016289 2.7765516255860625 +92 -2.394452859130453 -1.9459314788883335 -4.8163793839903395 +165 5.545976326258468 -1.4902648191681507 -2.852217343260048 +199 6.057154285340822 -2.785333961235231 -3.9368802597200943 +70 4.428171740986177 -4.8728670167946255 3.9631873121213563 +146 3.789706894596731 -0.4960046634434 2.7214958472715947 +106 -0.23074985036276763 -8.713636612175375 4.005748004431039 +52 -0.7237533363087905 4.119548929665377 -2.8963629157006965 +86 -0.7790443173139772 8.632440811261022 1.3650149071424797 +197 1.0158635207501077 -0.6540677867631334 -1.9286092656946883 +185 0.14103906323580015 -1.9230099439242179 -2.9613897973588497 +190 -6.016428738140042 -1.2480913921594763 3.6835279433237065 +145 2.079579027486713 7.671127892348986 -1.2249224435341195 +131 -0.32590310182334836 -2.4757135143210527 -1.108006743304219 +156 1.5441602101522276 -4.3012365664752 2.152192470473115 +10 -1.9251615561320725 7.7941703098856605 1.152489777841718 +196 -2.5417164626144206 -2.322970333327737 6.382288207464665 +143 1.1146704068320736 2.2068798409995507 4.003296941736723 +13 0.2218873541633033 2.002339450538451 -3.9278426768807844 +59 -1.1249725039613747 -1.38236183692768 0.6273981188606278 +186 0.17954184943335427 -2.3932954696372053 -0.7313011465358523 +136 -0.6086309213506338 3.5713339511273894 -3.8080329205654193 +192 -2.4502215368224705 -4.545932925209442 -1.62934516857554 +113 -3.3214500416678074 4.555014566016373 7.353766374710929 +62 -4.358088896189819 -5.982496403026446 2.5501878477362316 +74 -0.5539329584507672 2.794170243271062 -2.161412931865338 +118 -1.979611801168517 3.0336891371182197 1.2515672466968413 +117 -2.6346443065380387 -6.52420382221947 -2.3221165776786097 +23 6.421824321311546 1.7253174765287 -9.160076509970361 +171 2.1156964930224973 3.568443790163169 -3.4488134770961105 +94 2.1701428589622624 4.886850980047828 3.260178593455835 +41 6.033712104492915 2.2785562972718627 -1.4849735175385876 +141 1.4706522295431979 -1.8195923066965298 0.019053288005804775 +159 -4.554564437682667 0.05936456417819991 -1.932073129933284 diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt03 b/examples/PACKAGES/pimd/lj/data.metalnpt03 new file mode 100644 index 0000000000..ca36561e7a --- /dev/null +++ b/examples/PACKAGES/pimd/lj/data.metalnpt03 @@ -0,0 +1,422 @@ +LAMMPS data file via write_data, version 8 Feb 2023, timestep = 100000 + +200 atoms +1 atom types + +-11.876696863105703 11.876696863105703 xlo xhi +-11.876696863105703 11.876696863105703 ylo yhi +-11.876696863105703 11.876696863105703 zlo zhi + +Masses + +1 39.948 + +Pair Coeffs # lj/cut + +1 0.00965188 3.4 + +Atoms # atomic + +39 1 -10.394704135733114 -8.775565826160808 -8.397941096758792 0 -1 1 +57 1 -6.0931281896189695 -9.344348749599556 -7.681818125657076 1 0 0 +82 1 -7.510250310452092 -7.015516388660279 -10.07082880494168 0 0 0 +47 1 -8.77559664157391 -8.051556457641034 -5.414795391990417 1 2 1 +8 1 -7.186535453159322 -11.036850971616609 -10.567777816088821 0 1 1 +49 1 -0.39620530191825165 -8.622783800666731 -7.678166749572666 0 1 0 +184 1 7.393521813917142 -7.373039726272342 -11.446331826056564 0 1 2 +54 1 4.350458272629415 -9.857224313433228 -9.653286924521744 0 -1 1 +114 1 3.8685603455186985 -8.598956542283156 -6.307174409208557 -1 0 1 +128 1 1.5947628847115236 11.435941489344966 -7.415359628481937 0 0 -2 +102 1 2.581923114006006 -6.377657392511939 -10.762619336954629 1 -1 -1 +157 1 6.660414728640671 -6.277919775804619 -7.429265669038422 -1 0 1 +20 1 8.111607396483045 -11.231970200759829 -9.923403990974927 0 1 0 +147 1 10.627447337694411 -5.758860591417452 -9.410039814850826 -1 2 0 +169 1 9.360516562348877 -8.959647419481891 -6.858134439225374 0 1 1 +123 1 -6.81574278381186 -3.257465879140419 -10.90227212401971 -1 0 -1 +182 1 -10.83184823295899 0.6211210726593173 -5.225302920513499 0 1 -1 +130 1 -6.48675645240678 -2.4960330140097717 -7.149887944428669 -1 1 0 +140 1 -9.06689925915267 -1.3404094442689392 -9.265230651366284 -1 1 0 +153 1 -4.596115154274846 -5.2269288210583476 -8.762725686367764 0 1 0 +129 1 -0.18023204267520931 -5.069487595679249 -8.563855383994511 0 1 1 +148 1 -3.129776386379185 -2.132302209017619 -9.812957672584432 0 0 0 +68 1 -2.5326692981381176 -3.433323674590902 -6.08354364753642 0 1 1 +119 1 -3.563878018222407 -3.8548716132518166 10.583657201237452 0 -1 -1 +174 1 3.1103832548223167 -1.970524067942005 -10.720839500990373 -1 1 -1 +134 1 -0.0533798609747933 -0.3943397369034881 -8.568909963478589 -1 0 2 +189 1 2.8780134490012608 -1.3406833227009611 -6.386852522463116 0 0 2 +28 1 6.229563951867086 -1.1530156323854972 -9.327046250788925 0 0 -1 +1 1 7.525938759972945 -2.8198310481116913 -6.5604190503711814 1 -1 0 +24 1 10.94065283830757 -2.1209886921600436 -8.153560298060441 0 -1 1 +89 1 -5.78369558828959 0.914992281244533 -8.554571507812774 0 0 -1 +137 1 -8.18813666088715 3.7027977864495334 -8.645965827566897 -1 1 0 +88 1 -3.2799196205792844 2.576742862817614 -11.027465080959736 0 1 -1 +160 1 -0.2557418723462786 5.44151330793023 -5.976638045093324 0 0 1 +125 1 -3.2953557120100467 3.5116994482831103 -7.1553118740511215 0 1 0 +167 1 2.6725243652102173 2.638087495697569 -7.466301426847419 0 1 0 +107 1 2.5245946528561056 1.4391466346789628 -11.24156229950114 -1 1 1 +45 1 -0.29130191021650537 3.390022307884845 -9.780519849519312 0 1 0 +95 1 7.067732497970006 1.8275651232311958 -11.06782765028197 0 2 -1 +111 1 11.286054617943643 1.4415120259015062 -8.377487796984207 0 1 1 +37 1 7.567677172981714 1.512274859816151 -7.66702414977977 1 0 2 +53 1 9.41684489904846 5.317555173980882 -10.149115122842298 -1 -1 1 +122 1 -8.696560905496263 11.52907921791907 -7.072120720309414 2 -1 -1 +126 1 -8.701961655974642 9.131336810565264 -10.209192118557077 0 0 -1 +72 1 -11.181614439635823 7.328242947804642 10.873052780217858 2 0 0 +144 1 -3.063630044241759 -9.888584626042347 -9.88620302733954 0 1 1 +135 1 -0.011770197460421628 7.809248750526247 -8.433472830923051 1 0 0 +183 1 2.868185059788288 5.159526867067117 -10.074475497261854 0 0 0 +155 1 3.7046375990422384 9.18029420434672 -9.355401725486303 0 0 0 +21 1 6.6545915304717695 6.763201059850044 -8.264144019598284 1 0 0 +66 1 9.504750400993288 7.515486524178964 -6.171582593350192 -2 -1 0 +22 1 11.084351988266622 10.76412261505721 -6.106373064516015 -1 0 0 +42 1 9.142378798766934 9.296638377937079 -10.23790547780751 -1 1 0 +77 1 -6.875408369074396 -10.905367618463075 -3.8927601705390593 1 -1 1 +18 1 -10.586419483635158 -11.318597225412478 -3.865523315987396 1 0 -1 +46 1 11.248362092754824 -7.711534097612761 -3.9950725578324935 1 0 -2 +14 1 -9.503351845338017 -7.486629728113749 -2.029636008930268 -1 0 2 +178 1 -4.577490558383545 -8.077630279121967 -4.852591089043882 2 1 0 +48 1 -3.2127534742600403 -10.982725180284804 -6.34369805529311 1 1 -1 +55 1 -0.9448027936788463 -6.214616210957371 -4.309013304243614 -1 0 -1 +12 1 -1.8077376902517912 -9.51331251139922 -2.294135008818479 -1 0 2 +15 1 6.0707891099498035 -8.158735340051752 0.7389132882736256 -1 0 -1 +64 1 2.744794419170617 -10.568743032836894 -1.6560300803721786 1 1 0 +44 1 8.059994426810258 -6.349491556263628 -3.6188994660194567 -1 0 1 +188 1 10.007211181841205 -8.471311544163584 -0.7301030264655086 -1 0 0 +200 1 -9.361429934020506 -3.325582783501604 -5.251291205351098 -1 0 0 +198 1 -7.206783651218934 -1.1768543952383812 -2.2878728904921033 0 0 1 +76 1 -9.957900853453992 -2.990392708748729 -1.4836790089375538 1 0 0 +194 1 -6.720915931526202 -5.0514840317136205 -2.6178060083265535 0 1 -1 +96 1 -3.442998842345119 -4.030752937282784 -2.1099501345166054 -1 2 0 +104 1 -0.4344464897733502 -0.6370527730950448 -0.3065766310174318 -1 0 -1 +91 1 3.028414651691776 -6.371562707358944 -2.3012007885342207 1 -1 -1 +154 1 -0.18450456920986724 -2.8959245063427446 -2.9727341046372144 -1 2 0 +19 1 3.3110202139376677 -2.0069344123928587 -2.3036519362171575 0 1 -1 +176 1 10.315295502792623 -3.712962672865248 -4.262743726209571 0 0 0 +120 1 6.599910778171431 -2.290014983742207 -2.708516274908039 1 1 1 +138 1 9.70090444039391 -4.510671194156078 -0.7586380570561282 -1 1 -1 +9 1 7.581463530555666 -2.0591591013924426 0.5576192070111965 0 0 1 +150 1 -9.916366847902271 1.9274446583917424 -1.3280546499490278 1 -1 1 +38 1 -5.810864806174543 4.79569434382538 -4.7432663890343605 1 0 2 +172 1 -9.649044476681059 4.000883539130775 -4.9787866594630685 0 0 2 +87 1 -3.293106763914671 -0.9728697280200684 -3.5717383721780784 0 -1 1 +93 1 -6.290260113883048 1.000513447709075 -4.873943848533926 0 -1 1 +195 1 0.9143548729177553 0.18149461265281985 -3.719891858874817 1 -1 3 +149 1 -2.3007300445292564 2.7637958268752776 -2.589523265551314 1 0 0 +25 1 4.621842262318463 1.3043820546828728 -0.6225207492747167 -1 0 1 +35 1 2.847846769015831 3.7484794005209174 -3.7317005078406185 1 -1 0 +5 1 5.76859301522971 1.4821693744986142 -4.192625078793096 0 -1 -1 +116 1 5.980108401532309 5.771931805152196 -4.952107221267599 0 1 0 +112 1 4.9004069037624305 5.449030478588363 -0.25381811981375635 -1 0 0 +152 1 11.427575396440815 -0.5215078327180223 -1.9270850902641319 -2 -1 0 +132 1 8.550991064218966 1.8728424902700131 -1.3413841671493485 0 0 0 +173 1 8.98824885831321 3.8266779448060135 -5.54469830676447 0 0 1 +73 1 -9.970827412932536 8.006037772956901 -6.707069562638264 0 -2 1 +29 1 -7.851850658958549 7.656691482687513 2.2522623824361467 1 -1 -1 +161 1 -11.447924236091708 7.060851422709438 -3.5858559166646984 2 0 2 +78 1 -1.7537678607411138 10.085056705494843 -1.7540835643783588 1 -2 1 +11 1 4.471756401488951 11.779896969440827 -4.946674669424063 0 1 1 +84 1 2.43612195340992 7.404092397911457 -5.290554303714214 1 0 0 +90 1 6.2047805444381146 9.344776673352051 -0.9025295949725489 0 -1 1 +36 1 1.9413202066882462 7.760257880084115 -1.7928253633196454 2 -1 0 +98 1 8.489759189718113 7.59448375625753 -2.9903904190005255 -1 0 0 +56 1 7.283347233840352 10.49272575590101 -6.717344837699539 -1 0 1 +109 1 9.256731562506227 11.306927316729052 -0.9017849515922478 -1 1 1 +115 1 -7.271375340356332 -8.164250984794014 2.885007836656445 1 0 0 +124 1 -11.095529268087242 -8.923461918340646 4.126541576799873 1 0 -2 +121 1 -8.243366755262961 -10.114098944495577 6.642910506934619 0 1 -1 +80 1 -4.970941376701066 -7.256796443574398 -0.2694927115936565 0 0 1 +151 1 0.35720010482862147 -6.473326344145772 0.3145914251441795 0 1 2 +4 1 1.490868001691105 10.008505441456391 4.6538607757363515 -1 -1 -1 +6 1 9.00182583692019 -10.573496261667716 2.7405792887239087 1 1 0 +166 1 -8.709149836110669 -5.121301291304988 4.221356992297617 0 2 0 +40 1 -6.986302058442625 -4.546619094873101 1.2165687777692458 1 1 0 +127 1 -5.703890672733537 -2.4808733861641947 3.9258140668162143 0 -1 0 +60 1 -2.3900969955392997 -2.1240248283806444 5.301270425252238 0 1 0 +168 1 3.975110510651529 -3.4413029165097235 0.7867580630241555 -1 1 -1 +51 1 0.36128571956442473 -3.39012855469405 2.9987895355425387 0 0 -1 +97 1 2.1619059504545017 -0.14370659092792337 2.253550136735452 0 -1 -1 +103 1 4.021656515073349 -0.9827338117732367 6.042568640726292 -1 2 0 +163 1 -10.59690034092717 -2.73669268553396 2.3250010477277816 0 -1 0 +175 1 5.789631011184049 -3.417672117461432 3.9954654049476215 -1 1 0 +158 1 8.907482269205014 -6.491283319059688 2.9624073267859536 -1 0 -1 +85 1 10.197413661591135 -0.012917762754849087 5.257965818060175 1 0 1 +63 1 -8.188715623008076 -0.18029853692280418 1.160315648952679 -1 0 1 +133 1 -10.49518128239182 2.3754251515033395 3.670523930057962 1 1 0 +67 1 -6.57681506296786 3.490338685255813 3.2777499682226248 1 0 0 +83 1 -3.8395282904771557 0.6878472661538524 2.789698047147944 0 -2 1 +181 1 -5.242185082676098 0.757446996867543 5.798435988392239 -1 1 -1 +162 1 0.5730435311953745 0.02538554697642809 6.131446692962922 0 0 0 +71 1 1.5861291557437986 4.031923436354859 -0.5668685974116876 0 -1 -1 +31 1 1.1084648099889496 4.166735507593387 6.199029350547128 0 -2 0 +139 1 3.8934885611865404 3.644680090821751 3.3699758952172827 -1 2 0 +3 1 11.031167120250961 1.2297818113295769 0.8240448962619134 0 -1 1 +108 1 6.151774132335838 0.9127260755469919 3.630865862972541 1 1 0 +16 1 8.948393568215273 3.5697656211117277 4.019424538349256 0 -2 1 +110 1 -11.360902504880006 5.931262380786016 3.1386340545012104 0 0 -2 +50 1 -7.03855700568745 11.1587737863648 4.038018652970141 0 0 0 +191 1 -8.539592833531575 6.98957805034221 5.576163396973422 1 -1 0 +187 1 -10.749591400235348 11.27674482179097 5.078753839959464 1 1 0 +180 1 -1.0497509784332344 6.113751500784257 -1.8125940782158025 1 -1 2 +2 1 -1.7901048404834796 5.395364205758469 2.706946913090345 1 -2 -1 +30 1 -0.609763114135145 8.866708941315338 1.2567907242718874 1 -2 -1 +7 1 4.024360795442131 8.792731325824677 1.6316831819568236 -1 0 1 +164 1 1.9253904296798758 6.2539753963352425 2.2732172727821673 -1 0 0 +69 1 4.589943704480154 6.860175335740237 5.107742575629615 0 -2 -1 +61 1 10.211708813407666 5.048929362482134 -0.6556133826774401 -1 -2 0 +34 1 7.618123086186067 9.260791062852595 2.410253158978456 0 0 -1 +43 1 7.187831963553112 6.047643259558733 2.377231426556367 -1 -2 1 +177 1 8.53679514766192 7.2855280107021585 5.618179930120522 -1 1 -1 +65 1 -10.025744517789033 -8.43398132011017 11.42484399314975 0 -1 -1 +27 1 -10.94664003963282 -11.66367183635281 8.50586002909509 1 1 1 +58 1 -9.736423247717525 -6.9374057905213675 8.120131077653108 -1 0 -1 +26 1 -5.214988898132063 -8.488979255655 9.322140672840906 1 0 0 +142 1 -2.2289627568453696 -6.732212289220556 8.533930418433167 2 1 0 +101 1 -4.332868168974628 -8.046497536008985 4.908195000324994 1 3 1 +100 1 -1.5781140115056829 -10.89378955359733 6.845196027213777 1 2 0 +105 1 1.348709072973532 -7.840212526420486 3.935309569976617 0 0 -1 +75 1 4.538409842632715 -6.347596431637598 5.462073088539682 0 -1 0 +99 1 1.681804464017192 -11.02047184883833 10.743929007254543 0 0 0 +193 1 2.131527690130696 -6.895966349546285 9.427352746134135 1 1 -1 +33 1 4.441375653691135 -11.736850231117081 7.202677955581144 0 -1 0 +81 1 7.255373647519644 -8.53916396071646 6.739789624034124 -1 1 1 +92 1 9.790634573312333 -9.44185811686149 11.159147618448468 0 2 -1 +131 1 11.167512844489337 -5.2910720883824744 6.1780456625725 1 0 0 +32 1 -6.188065315477864 -5.388148534056967 6.4630859734577015 2 1 -2 +165 1 -9.199411318810375 -3.239575676768024 7.39142666230393 0 0 0 +199 1 -6.937479844200535 -4.998516463158538 9.811426478379644 0 -1 1 +70 1 -5.484149755229003 -2.3316100376807256 7.82342156113301 0 1 1 +146 1 -1.4782561675061032 -0.5332293079309558 11.298322053799005 2 1 1 +106 1 -1.299565649633866 -2.547377817344993 8.672457149378053 0 0 -1 +86 1 5.4346476876843255 -4.567525864857576 8.586496749161867 -1 0 1 +52 1 0.6258963928325112 -3.6737913184680213 11.408468473681546 0 0 0 +197 1 1.6655903827098761 -4.690360650696893 7.1487356646988935 -1 0 -1 +185 1 2.1215529597432052 -0.6042753779764993 10.00914541981377 -2 1 -2 +145 1 7.122063254971888 -3.6848122349525525 -11.806135592932787 -1 -2 0 +156 1 -5.464187808325629 -0.39192954326422935 11.38371879051662 0 -1 -1 +10 1 -9.035521158465771 -0.7757159430461369 4.809652747733452 0 0 2 +196 1 -9.335669158910619 0.22813232884729473 8.66176404595545 1 2 1 +143 1 -7.124352690053236 3.030922198080938 8.687337455424057 1 0 0 +13 1 -11.772101478818819 3.2748279418542197 6.990058907086091 -1 -1 1 +170 1 -2.6686912671072918 4.2637019013785284 6.493175161410804 -1 1 -2 +59 1 -3.414884055242947 1.7144589247064204 9.304818354414252 1 -1 1 +190 1 7.431647314963107 -0.2323681547056703 9.930387554553988 0 0 -1 +186 1 0.12403907626679356 2.5751847736553266 9.610847507588266 1 1 0 +136 1 3.4038632456152635 2.1695685652264665 7.948376142475482 0 -1 -3 +62 1 3.9322597596563718 6.930006246409542 8.985009369790514 1 0 0 +192 1 10.419594684028056 2.5035467156582776 9.806945423286493 1 1 1 +113 1 7.193391146269118 2.2362428283193516 6.875806515902987 -1 -1 -1 +179 1 11.834426610265067 -11.194697762969987 -10.475928756799647 -1 3 2 +74 1 -8.13998220698503 9.794354756748188 9.006589181804868 1 -1 0 +118 1 -11.66384578850255 8.468830152015009 7.042404750007243 0 1 0 +117 1 -5.315240522733173 11.32072783429444 7.576721087819581 -1 -1 0 +23 1 -5.138619088737474 5.725030905668137 11.239725943022542 0 0 -2 +171 1 -4.330917401708549 7.140228396638214 7.942565065680071 0 2 -2 +17 1 -2.03596415813805 8.313925455397243 5.2823718467129375 -2 0 -1 +94 1 0.5232518791432845 9.687616975679045 9.044820921363916 -1 0 0 +79 1 8.56918534055184 11.565534359174451 5.948120961320791 -1 0 0 +41 1 5.45739715811315 11.541960137674769 11.642369134799488 0 0 -1 +141 1 9.892948341443592 5.76405276568962 9.068370836458591 1 -1 -1 +159 1 9.60684214528172 9.743113663992652 9.758679903521092 0 -1 0 + +Velocities + +39 -2.179321628468343 1.1511761233721014 -0.5234785181560597 +57 -6.53120961304823 2.2544161501487334 -1.2373865721091248 +82 -1.0543302569480935 -1.2919030991113425 -2.688794866729753 +47 1.4420685217894869 -0.5747049377538087 0.6848122481945966 +8 2.36242269061923 3.5603470370323436 1.4936669774368116 +49 -0.6083156247744255 -1.170955618423765 -3.8346753413107364 +184 3.2429732085760055 -3.3821697881066015 -7.235911314720436 +54 -3.6115695852161833 0.0106170916100512 5.665158101271987 +114 6.929262289695876 4.643270489304085 -2.432510904848287 +128 3.7837119455630903 -0.5425190416852157 -0.9248832742343969 +102 -5.730330621950312 2.5925672733788283 -4.330025077474401 +157 -0.16543207126613158 -3.935307993847579 1.876153422628358 +20 -2.5674917416750285 7.261116339316168 -0.2822364811608604 +147 3.957269802164221 -0.44334252499690296 1.8428688293334772 +169 -0.43761432062493966 -2.7004091328373003 -1.9616354437812995 +123 0.4419336641195504 1.661879969268821 -0.34576656499174563 +182 -2.755633666515818 2.89026397900542 -3.3064689855078004 +130 0.4228585869964945 -2.6339270059626747 2.3472759619296717 +140 -2.5258615952943133 4.5464360654810925 -2.960299517136603 +153 2.614799199811544 -6.997005129983971 -0.4675266931999429 +129 -1.0794701392816852 -0.7999027589273617 -1.3594765973927763 +148 -2.5441459127388772 -5.738540142837333 1.2458734580393733 +68 -0.8806574381084391 3.664356747058979 4.498638804868755 +119 1.348535842985886 -1.9096618944303452 1.6705192446304495 +174 0.23536625265167066 3.432430764653958 -0.9841797613553105 +134 0.26301203065712264 2.9239481371691687 4.198089422305616 +189 -5.106229336056745 1.3598593078850199 -5.0921887654096665 +28 -0.5789581538284776 4.678352716038949 1.6083556088979694 +1 4.3168451733041335 -0.8087879863432109 -1.1510010508143134 +24 4.684129190758672 0.5864820180144825 1.3599272674223446 +89 1.2931815025110984 -1.7192563446283065 -3.2675358462468287 +137 -2.489381057507014 1.3936843668930472 -3.4953181455890334 +88 5.564916491075967 0.8520321811715912 -4.447122865446203 +160 -0.07033878109043368 2.2522705799844327 1.9030072089658323 +125 -1.5185131407725638 0.6804743431846004 -2.389477187487043 +167 -3.6035218377687275 -1.9787464624356907 1.2495634883162925 +107 -4.50061384293538 -4.128984940089246 -1.940600692273992 +45 -2.0130680589133294 1.0097638511181886 -1.9327875523898734 +95 -1.8894050626509937 -4.373548537324043 0.32709687823368594 +111 -4.9090211058158335 -4.89034728498546 -4.4838347069372535 +37 -0.7827825654937912 0.2606671310038102 1.2648209822548744 +53 -3.3248176554427693 -1.934526339006954 -2.2700456945424197 +122 2.3544797713703187 -0.1174286295452037 -1.1080357975092663 +126 -1.8232106805443349 -4.42954489421542 3.9468260248902474 +72 -0.3083487798866145 7.089424978098924 -4.065977117594069 +144 -3.209546353795563 2.7953912155418355 -1.9419952653204642 +135 2.825460830342647 -1.3242735854960683 -1.061464548303972 +183 -0.6219322132099675 4.350176294595897 -3.2016653855084876 +155 -4.16183730251878 -4.394917007094668 3.143265712814128 +21 1.042679461197399 -3.76474130433989 3.307467644481217 +66 -0.5660353999856405 -0.9094642274226821 -0.5314610131608182 +22 -1.709804393279522 2.6955272721787336 6.847933865416769 +42 1.5723865718421481 1.2482884329237185 2.4822430118654624 +77 1.0256281250413677 0.6998122284735013 2.9532003047278765 +18 -3.421972744387341 -0.5274519950694775 -4.133682641337289 +46 2.168436016686143 1.0804778012063694 -4.320033516090909 +14 -4.0164283054824255 0.49834440962343196 -0.8290451948901274 +178 -1.7412819488092 2.798973205265782 -0.479900827844132 +48 -0.555572193190021 -2.2271111327857946 -5.48753500392571 +55 -0.2945098160209474 -2.3597197684570634 -1.323571695006608 +12 2.648780275608345 -5.627798255886156 3.878499085658468 +15 5.08064047237585 10.983886551374368 -3.8614562219189974 +64 4.528407739688303 3.5669581487847277 -1.59783436247384 +44 0.6179240842533569 4.733042665051045 3.2581525303469463 +188 -7.148050937863482 -0.9829624495370496 -0.8418403492142479 +200 -2.1181786226695647 -0.7796260516164706 -2.0505857854477805 +198 -0.41864716042364125 2.296081055566785 0.29109905683884685 +76 3.589037248934578 3.9784201870774147 -0.18396191505765547 +194 3.2793423730519953 -0.6090514771278666 -3.4934826993710537 +96 -1.781539941975932 -4.363514711154816 4.864062078072237 +104 1.408163209882818 -2.2024070797001714 1.13197301326935 +91 0.7549842936282545 -1.8949946215618456 -1.0202618871629823 +154 -3.58496442590166 0.6965660533263317 -1.9948941159972786 +19 1.1538547086598117 4.352147462832853 0.5698931598819479 +176 6.6158635134989 -2.4436529370166666 -7.921148144074609 +120 1.9770896033272432 5.325440429480748 0.4321682589452387 +138 -2.434142355712014 -4.211844174503549 3.7463686848024356 +9 -7.9556317081134775 1.3611081846148716 1.1973651519179334 +150 7.132627873294173 -1.1589700932996243 -0.3531633921451265 +38 -2.373885424533282 -1.6670776794732187 7.126244784839699 +172 -4.190332426742245 1.4971407429268737 -2.1038522992559976 +87 3.8705371644824407 0.6946282376038537 -0.5718475935933448 +93 1.3514689577122314 2.2886635029067657 1.1457291529838165 +195 0.8294761589431854 6.809445622982572 -4.490681006002271 +149 4.665694837020095 -3.8971221183097815 -7.000247317496072 +25 -1.4227504585025186 2.666757793916314 -4.2485642256584795 +35 2.0433487025942068 2.1539055294115 -2.682708261193331 +5 -3.648704562720594 -0.39330823945136234 0.15528838477335327 +116 2.764952659364006 3.2308857608345534 -0.538944143891585 +112 1.7976356559372615 -1.540357698562047 -2.170928793825917 +152 -2.4572877205036923 -1.6206485240807629 -4.85936004694647 +132 4.802107956404735 -0.11013197470116909 0.6674735986355181 +173 -0.7045077946396323 0.6277364102624156 1.4282110726540087 +73 -3.4535983591604964 -1.3273163733693092 3.631166806617851 +29 -5.742750315320132 4.210335165654985 -3.183862358662845 +161 0.7207671082657183 -2.639249856838032 1.2031913703667394 +78 1.9802499580941673 3.892356471093276 -6.0300544674355 +11 0.3710597317170738 3.014897507875772 7.0674999285689495 +84 0.06314153271125988 -4.938702818012672 2.3405049696166014 +90 -3.021721770486999 0.5895782968475963 -0.883462541486843 +36 0.6115261475891951 3.326758596635819 5.305093464697983 +98 -3.289247327924386 -0.7716659861479829 -0.8061979190797803 +56 -2.484208615656381 -0.7583806019455193 2.000293738990754 +109 4.065544877208817 -0.31468790514138334 0.3860037578404895 +115 -1.5583103456503846 -4.034490286401138 0.5420000897756707 +124 2.716664944254732 1.195693130251065 -1.0534283229167152 +121 8.492299287405391 -0.8573607139000322 2.0906896396885357 +80 -4.269726737071596 1.290253084422534 1.3756246647776993 +151 0.17922239204385892 -5.243344038190157 -1.7214465623209987 +4 -1.5287457726003018 4.545253326761756 0.4075652200807629 +6 -5.5555965267113505 5.196757149002673 -2.131768740002899 +166 3.8192709965319924 8.287983828276944 -1.2203929922517287 +40 3.450300769917062 1.3679263003539135 -5.713912913407013 +127 -1.8550057408599427 0.2529213554001156 4.292787610095508 +60 -0.4570467791684108 2.1995625338737512 0.38684023826685754 +168 -1.1461639744415708 -3.7753008221986715 -0.7069362633693567 +51 4.246427854086795 2.2660286121479016 -0.17525536000106454 +97 -0.45920058079801923 2.3672214881822935 2.918793131685986 +103 2.8457407886760415 5.079818233132883 -1.6831372889932052 +163 6.588786306029201 2.961102097923318 0.12898108224833468 +175 -0.7784000842847736 0.05239163186710383 4.783927411692968 +158 1.324975092911766 5.716483065795907 -2.766582829578808 +85 1.126575470046233 1.8878210873276244 -0.3160540074040886 +63 0.26385610607819265 -1.0518690744177137 4.681584068045189 +133 -0.8004471826186864 6.474544076922776 1.4133211461125943 +67 3.6157553514613374 3.5767340310447207 0.22045279936244222 +83 -1.0062072078141164 -6.493845317833074 -5.600689394569981 +181 -1.9698774782124704 -2.4967875449198838 -1.482046688397622 +162 -2.904567214261779 4.609525946829769 -4.773883794319192 +71 4.704149679704777 3.1523586525426124 4.57547323305684 +31 -1.5901553457672002 -3.05689507101266 2.2039810687618497 +139 -2.695407001366337 2.151237461783768 -2.283708689815052 +3 -0.46766817551787454 -3.140857693103965 0.4361924390516714 +108 0.1913617703423478 -2.71581239158428 0.6724779385423365 +16 -0.5574602967458635 2.869089341747036 3.246617986586125 +110 -3.2935781644783413 -4.906537822882089 2.429950659174858 +50 1.3517081278566716 0.7979565345760338 -0.4185472621695281 +191 -6.186669509381163 1.5069910278978673 -3.122140179713244 +187 0.8559064953620825 0.3957056787517148 0.9088293844669495 +180 0.221714052316844 3.344232199120801 0.5800459730217239 +2 2.3994296631460794 -2.8375195813060388 -1.0887178593496891 +30 1.2210690766888224 3.5899619104376446 0.08151741673684687 +7 2.7726111769463913 0.687615055956059 0.37410979119832144 +164 -1.1931898641891907 -1.3539824930215878 -3.3405462160564703 +69 1.9731979197688503 -3.2571194324245205 1.6749831681024951 +61 3.1823016504442476 -3.0315743307115213 0.8747268024881065 +34 0.42940760329491323 -0.8546757769020348 0.7046464666351262 +43 -1.2834304624987016 -0.32585553857664296 0.40311374457538895 +177 -4.156106157869977 -1.1691085227558309 4.764406539360629 +65 0.7459698348800096 2.6999150256104985 -3.5548113977053744 +27 1.2331887682296838 -1.694381902758542 0.04304965560826135 +58 -6.154057979578904 -0.19938148972279413 -3.4163165607386854 +26 2.910747146350628 -2.990465499480819 -1.5258142005591657 +142 -2.6857404309480515 -0.4742647340730133 0.8619212003727141 +101 0.8564696967146533 -2.0546263222545185 5.004696469365843 +100 1.7773361390238631 3.5466656645190247 -4.741841979587642 +105 5.236015515046745 -7.745834640119119 -2.0944663177984997 +75 3.19034440896343 4.856191854526413 0.20239301909347396 +99 0.7372059827598996 0.8218000327204846 1.1962914445625328 +193 -5.54751039136509 -0.8984829893317632 -0.09804506747660646 +33 -0.9015609488918586 2.8634014710755875 -0.5142897564939601 +81 -4.226349362632615 0.4990338142221863 -3.177351469506789 +92 4.852938979419456 -0.5312580038435196 0.4444574326006344 +131 -6.780942865007681 0.2505331120455996 2.984671966978939 +32 2.043323184339133 -2.0915365663642502 0.3570674081797969 +165 1.772621337461088 5.624086428613788 -2.1958779155861525 +199 -4.655961690467214 -1.5582587292151853 -1.0372922469851396 +70 2.1009520029345854 -3.4367267457669444 0.3489118952393979 +146 1.1094627356046975 -3.7052416904893786 3.1151669468585044 +106 0.9244635796842038 -0.8697076449017062 -1.1271268628891515 +86 -2.4614440724404063 -1.1443915951868173 3.0472327038543923 +52 2.206997554373295 0.48895638167295574 7.813903343751546 +197 -4.43947099244034 0.3827402537789232 -6.114284477117655 +185 1.8450115502667273 -3.367103363338241 -2.7646657581326055 +145 -4.495233666659511 1.3255674480674051 -1.5848168476287035 +156 -1.1061826790673608 3.490100920043544 1.7425058587963753 +10 0.10888349121518726 -2.3346954910750384 0.3634642612209191 +196 -1.237862986215301 2.306399540514406 -5.426709024577362 +143 1.387043305733553 -2.3787136376519027 -0.20756141146550633 +13 2.2357687358768974 1.685714857075964 2.2457142840004356 +170 5.1889099023089535 2.9826822454922652 1.0755609101553643 +59 -1.712405925615148 -2.553137012160255 0.03926835373766702 +190 -1.7274645985224364 -0.0964601276780217 -0.8892867639051387 +186 -0.5051041743099376 2.0346977046537615 2.086897795173162 +136 1.6635288094047165 0.5254443611211371 1.8199836517530088 +62 0.7708640981248649 0.12152082573932288 1.7717141492471689 +192 -1.0422128532558474 -4.04447955732469 -1.926662726630305 +113 -4.472429838979146 -6.765621050808509 -3.003588999898843 +179 -1.7067254128417755 -7.980317775082368 -0.9140818138687279 +74 3.515578700667397 -5.09057685611017 -2.4373465493326076 +118 -3.836950473028625 -4.398228703366778 -0.9008313748045251 +117 1.2669363304661976 0.4817377004658103 -1.5641060379969072 +23 -3.023411190495862 0.4127754096885368 0.24116380806370397 +171 0.782437003849918 2.278657242176388 -1.477387925776958 +17 0.8979396881179555 -2.2139965953711083 -0.9661842759619532 +94 -2.2083649456241576 -0.3520697824173402 6.939477089019811 +79 -5.097477099334401 -1.1053765447054356 -0.5927717885602897 +41 2.717742851180541 -0.8197068618726784 -1.1670313842646072 +141 1.3223712852080913 -1.1251601779570968 2.4100632027817 +159 -3.979797713933269 1.5260607907829866 1.4624579807682239 diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt04 b/examples/PACKAGES/pimd/lj/data.metalnpt04 new file mode 100644 index 0000000000..7fcb4a8bac --- /dev/null +++ b/examples/PACKAGES/pimd/lj/data.metalnpt04 @@ -0,0 +1,422 @@ +LAMMPS data file via write_data, version 8 Feb 2023, timestep = 100000 + +200 atoms +1 atom types + +-11.876696863105703 11.876696863105703 xlo xhi +-11.876696863105703 11.876696863105703 ylo yhi +-11.876696863105703 11.876696863105703 zlo zhi + +Masses + +1 39.948 + +Pair Coeffs # lj/cut + +1 0.00965188 3.4 + +Atoms # atomic + +39 1 -10.354249178970125 -8.813051919915168 -8.382969093379817 0 -1 1 +57 1 -6.095139656027609 -9.359263918713493 -7.698842353606457 1 0 0 +82 1 -7.493664607592135 -7.0059769885785474 -10.165574967227153 0 0 0 +8 1 -7.207830943811267 -11.030802786228156 -10.545758277848378 0 1 1 +49 1 -0.3707760358866739 -8.703874147846175 -7.734231800660862 0 1 0 +54 1 4.371171010756674 -9.822286390366472 -9.608608173022526 0 -1 1 +114 1 3.857478702816806 -8.583003039261015 -6.26115845444949 -1 0 1 +128 1 1.580452299690882 11.414121196534609 -7.383200117467098 0 0 -2 +102 1 2.6350731915864145 -6.397417482172074 -10.801961817246344 1 -1 -1 +157 1 6.611187455803048 -6.205022609136458 -7.392834911294685 -1 0 1 +20 1 8.102933091687992 -11.214330088075124 -9.936524774492973 0 1 0 +147 1 10.596045290286296 -5.759130098910738 -9.380762680610847 -1 2 0 +169 1 9.366630474689176 -8.921006522319503 -6.843673029579733 0 1 1 +123 1 -6.859009660270495 -3.2379537512590297 -10.864178266429683 -1 0 -1 +130 1 -6.577322046738903 -2.5106835965921164 -7.224326100490352 -1 1 0 +140 1 -9.107723436323155 -1.3229863757258506 -9.244986454221655 -1 1 0 +153 1 -4.548656766959874 -5.17967134910819 -8.787434718939945 0 1 0 +129 1 -0.17808656259561137 -5.023072792674526 -8.617493408883192 0 1 1 +148 1 -3.2601725736553027 -2.033844854035978 -9.777384129731104 0 0 0 +119 1 -3.5689822234610595 -3.8505044768944927 10.627709646886371 0 -1 -1 +174 1 3.140197534695247 -1.913882100151838 -10.76389374977719 -1 1 -1 +134 1 0.048608226174046365 -0.39555664243276595 -8.555122102444741 -1 0 2 +189 1 2.8889478385298655 -1.3768037709890826 -6.4534432907832056 0 0 2 +28 1 6.251824687614619 -1.150087307901578 -9.266876365488919 0 0 -1 +1 1 7.556173300837827 -2.8495110668506705 -6.5781416096142475 1 -1 0 +24 1 10.885498404916829 -2.163413929107282 -8.181530231530648 0 -1 1 +176 1 10.317143708012939 -3.6994503272775026 -4.285905348037859 0 0 0 +182 1 -10.866713794399553 0.5835390862478285 -5.190897922574198 0 1 -1 +137 1 -8.197336531384668 3.7710266805092836 -8.628333311872499 -1 1 0 +89 1 -5.830740775393367 0.9227024639457406 -8.56962226272939 0 0 -1 +88 1 -3.2174671278447153 2.596119117918313 -11.010039397757382 0 1 -1 +160 1 -0.16353319092958282 5.356569592952759 -6.027400461354258 0 0 1 +125 1 -3.2660565494911986 3.5402608994580014 -7.139474945270797 0 1 0 +107 1 2.5004686193441863 1.4213418016161157 -11.264390107008213 -1 1 1 +167 1 2.6306438675911963 2.7047021139073024 -7.49322777752869 0 1 0 +45 1 -0.26576210897417507 3.3660903959893673 -9.858663372020018 0 1 0 +95 1 7.02981932063029 1.8215081284089933 -11.08913793230704 0 2 -1 +111 1 11.249280516767561 1.4119125550850526 -8.355555586118154 0 1 1 +37 1 7.519477058425284 1.5490589443573544 -7.629176894794767 1 0 2 +53 1 9.42047942911636 5.244187392085703 -10.133263719784543 -1 -1 1 +122 1 -8.63992654505136 11.450404981587694 -7.075458716341785 2 -1 -1 +126 1 -8.723342916981192 9.13102883296233 -10.17466547482745 0 0 -1 +72 1 -11.206699277582317 7.297248005363309 10.79372604446887 2 0 0 +144 1 -3.0607758424636864 -9.877816322452732 -9.947243110943289 0 1 1 +135 1 -0.051808796348424835 7.83802622288054 -8.426793042584595 1 0 0 +183 1 2.8265474855254293 5.2650728973076095 -10.056888138059385 0 0 0 +155 1 3.7333346013160673 9.271985029918303 -9.380687277523048 0 0 0 +21 1 6.713007344355741 6.806136281598503 -8.223321187919673 1 0 0 +66 1 9.521874492322397 7.474069880889854 -6.18586873962963 -2 -1 0 +22 1 11.050170157856584 10.74761987425433 -6.194431008418831 -1 0 0 +42 1 9.124991617085433 9.313926068749339 -10.259091612355418 -1 1 0 +77 1 -6.847598261663958 -10.941109014822928 -3.892206492676891 1 -1 1 +47 1 -8.72137736883077 -8.020553455249186 -5.411695457067339 1 2 1 +46 1 11.333911554840483 -7.659682887184623 -4.080815689532784 1 0 -2 +18 1 -10.646224114047842 -11.295142102189118 -3.8769976756703564 1 0 -1 +14 1 -9.605745944890806 -7.401374860679573 -1.982921039201294 -1 0 2 +178 1 -4.564495057067056 -8.050510749495825 -4.8659978849512635 2 1 0 +48 1 -3.165816579392377 -10.956276319999837 -6.319173483966388 1 1 -1 +55 1 -0.9801312338979216 -6.257580408615657 -4.2669674058977485 -1 0 -1 +12 1 -1.844858616965503 -9.490670669998687 -2.2961766563429364 -1 0 2 +15 1 6.049786455655653 -8.189634166823847 0.7790760301881896 -1 0 -1 +64 1 2.7732180154018238 -10.586600242266561 -1.7220526985868578 1 1 0 +44 1 7.987685169786731 -6.317537693048875 -3.624602682973471 -1 0 1 +188 1 9.985693632064716 -8.552544016815117 -0.7260907476837022 -1 0 0 +200 1 -9.468913996814749 -3.332006112139499 -5.219156914346259 -1 0 0 +198 1 -7.176651640198091 -1.1963525306783946 -2.253714347543795 0 0 1 +76 1 -9.922127224407973 -2.9538091484944595 -1.5482866071777552 1 0 0 +194 1 -6.755129554954018 -4.9982944036574395 -2.6156955876752477 0 1 -1 +68 1 -2.4837259122195063 -3.490803572414407 -6.114089975980331 0 1 1 +96 1 -3.411864655652117 -4.073235933810771 -2.067669105620388 -1 2 0 +91 1 3.0280594613502636 -6.3376596415711255 -2.326898295867128 1 -1 -1 +154 1 -0.19811764587289105 -2.9629996027018635 -2.9145103486688195 -1 2 0 +19 1 3.201765959673939 -2.0909064907714274 -2.3150720129859153 0 1 -1 +120 1 6.666250093808799 -2.2381082538053363 -2.826357084420522 1 1 1 +138 1 9.709412364194842 -4.510669257803851 -0.7371785941816178 -1 1 -1 +9 1 7.576584804759921 -2.0173260225381977 0.5837619474494389 0 0 1 +150 1 -9.925148350003655 2.008414757334357 -1.3585989335940631 1 -1 1 +38 1 -5.774540065294694 4.703952130507923 -4.709776738882269 1 0 2 +172 1 -9.650643801070206 4.065753015545833 -4.8890536457268325 0 0 2 +152 1 11.354703841174967 -0.5574832611945055 -1.878354960063874 -2 -1 0 +29 1 -7.8756923654824735 7.618259977195223 2.1884603240114373 1 -1 -1 +87 1 -3.3182201208100697 -0.9619504843434044 -3.571516039019219 0 -1 1 +93 1 -6.22447967806385 0.9237017015404234 -4.899961705314269 0 -1 1 +195 1 0.9557760919893532 0.18190089307880442 -3.7530657563825116 1 -1 3 +149 1 -2.258211757279497 2.7869892960968605 -2.6067337721972543 1 0 0 +25 1 4.582659783463335 1.197304704789868 -0.6333382889463834 -1 0 1 +35 1 2.8340362437473665 3.775198295599683 -3.7220216498098746 1 -1 0 +5 1 5.712702262390174 1.525516395213053 -4.231454437885219 0 -1 -1 +116 1 5.993880302160488 5.819609728686341 -4.981314501727478 0 1 0 +112 1 4.993891288991353 5.44294004315121 -0.20000094912971011 -1 0 0 +132 1 8.553215140035688 1.848923908331039 -1.3929852223418029 0 0 0 +173 1 9.058614097754903 3.793989570565648 -5.529277027531151 0 0 1 +73 1 -9.97609370360327 8.001052498887105 -6.678871508542809 0 -2 1 +161 1 -11.443764897577033 7.1235053711641685 -3.5412879782897306 2 0 2 +78 1 -1.7946589875472476 10.140074782001498 -1.7188309657767924 1 -2 1 +11 1 4.48445505597226 -11.863465860429208 -4.995823112103199 0 2 1 +84 1 2.463379766571318 7.427030445050496 -5.251636426023569 1 0 0 +90 1 6.171978058160043 9.299313343642424 -0.9265676065333643 0 -1 1 +36 1 1.9133463519046003 7.719511929183511 -1.7420567765226709 2 -1 0 +56 1 7.255050752153057 10.433125182056429 -6.693622072998551 -1 0 1 +109 1 9.138840387988623 11.32849279657362 -0.9075432219499753 -1 1 1 +98 1 8.493633429672352 7.664253543281429 -2.9150549381854445 -1 0 0 +115 1 -7.310435599643078 -8.126317136056372 2.852881189844054 1 0 0 +124 1 -11.031652111608674 -8.829616358814924 4.11892916031843 1 0 -2 +121 1 -8.24719811507558 -10.102559907485395 6.644774570363861 0 1 -1 +80 1 -4.990158022745006 -7.228416620009519 -0.23616829431627906 0 0 1 +101 1 -4.425835217027135 -8.041862792922046 4.912842377205241 1 3 1 +4 1 1.6093443070111064 10.036215537003722 4.649624528139505 -1 -1 -1 +6 1 8.957102959942503 -10.648514255179037 2.7520244907338807 1 1 0 +81 1 7.208459443972924 -8.512507364143946 6.7186127098675 -1 1 1 +166 1 -8.735612761804596 -5.051940162290023 4.287135452158321 0 2 0 +40 1 -7.0154409632766175 -4.6058645552640805 1.2332349553758588 1 1 0 +127 1 -5.628166701486109 -2.4571683554307384 3.9074191001707503 0 -1 0 +104 1 -0.4346324933964958 -0.6513905925349095 -0.2958543835790408 -1 0 -1 +151 1 0.3877075536664327 -6.4007225085014845 0.24945488280004469 0 1 2 +60 1 -2.369840965541917 -2.0961144039265633 5.2852382593681435 0 1 0 +168 1 3.911007973828095 -3.389123300929967 0.7576129789066393 -1 1 -1 +51 1 0.3292384996563097 -3.420112775820937 2.935489834742583 0 0 -1 +97 1 2.1485649172664862 -0.10439592636417316 2.279403065792625 0 -1 -1 +103 1 4.042877904485135 -1.0208892892284567 6.118986931410435 -1 2 0 +163 1 -10.685207062128164 -2.805182722090798 2.2992408280776737 0 -1 0 +175 1 5.777080728790477 -3.428422767297768 3.9500489905592655 -1 1 0 +158 1 8.901770795533949 -6.449835056793116 2.8925949474189174 -1 0 -1 +85 1 10.225188926473791 0.0017773278841735195 5.209115671649155 1 0 1 +63 1 -8.213348572388885 -0.1729333455438991 1.128439638194422 -1 0 1 +133 1 -10.560391258433501 2.3871994933981604 3.6217764405881163 1 1 0 +67 1 -6.58893267726452 3.5537178434565275 3.2475644463629347 1 0 0 +83 1 -3.8515887631140515 0.6260605243857498 2.809794279660778 0 -2 1 +162 1 0.5353669870800427 0.011171969691910696 6.140615526988775 0 0 0 +170 1 -2.6982076482868784 4.239239002024167 6.5023488926564 -1 1 -2 +181 1 -5.269736706670749 0.6633143508889567 5.80856876438175 -1 1 -1 +71 1 1.6280398876142836 3.9922472717626896 -0.5550063690378906 0 -1 -1 +31 1 1.1405250667226041 4.200703300864838 6.2167435118694465 0 -2 0 +139 1 3.842562548009269 3.6547622321511497 3.2913955399115533 -1 2 0 +3 1 10.98202973743475 1.2548431833407037 0.9250033618641567 0 -1 1 +108 1 6.094576089388102 0.9247979169923504 3.624011344184912 1 1 0 +16 1 8.94421023892344 3.592040529277952 3.968834804835023 0 -2 1 +110 1 -11.386726712959288 6.012786074810452 3.1335330551037686 0 0 -2 +50 1 -7.019873322974002 11.162655244151733 4.132863440221239 0 0 0 +191 1 -8.58859990391919 7.042920679843704 5.549588183323656 1 -1 0 +187 1 -10.694945657883851 11.280545373237025 5.089277301544773 1 1 0 +180 1 -0.9832322177090624 6.17374336331137 -1.7810168677844587 1 -1 2 +30 1 -0.5786545001726999 8.92644611919124 1.2001444343316763 1 -2 -1 +2 1 -1.7987623083026563 5.385135175592104 2.641095387043805 1 -2 -1 +17 1 -1.9803131781320147 8.340104277288379 5.2339610584552005 -2 0 -1 +7 1 4.056078571838132 8.755054555667046 1.7129552906297647 -1 0 1 +164 1 1.8606879960472185 6.264401812470137 2.238048307949188 -1 0 0 +69 1 4.582260343749063 6.901308432226479 5.16724455389889 0 -2 -1 +61 1 10.203999344055715 5.098875037493535 -0.6552273031803888 -1 -2 0 +34 1 7.6452062423181015 9.296589241677342 2.4017008610787727 0 0 -1 +43 1 7.186240451053859 6.044802069738282 2.458597580290494 -1 -2 1 +177 1 8.52522272174418 7.310838340899178 5.550705478002598 -1 1 -1 +179 1 11.738401405730409 -11.171052154041227 -10.46073671167246 -1 3 2 +65 1 -9.923794257190753 -8.360277300667597 11.397343948439744 0 -1 -1 +27 1 -10.96202039046517 -11.679459496759502 8.461761452894827 1 1 1 +58 1 -9.782820449181592 -6.900116722543098 8.161461366886957 -1 0 -1 +32 1 -6.176757614808324 -5.427580338396943 6.37353314773015 2 1 -2 +26 1 -5.244950495195521 -8.48903289150118 9.276610316099598 1 0 0 +142 1 -2.2192381371286913 -6.710860567512032 8.5692633945157 2 1 0 +100 1 -1.5829434980745454 -10.919909502588283 6.783259906533759 1 2 0 +184 1 7.415704119987677 -7.40752254135457 -11.394836902247562 0 1 2 +105 1 1.324436294552863 -7.868824845245506 3.928981783067961 0 0 -1 +75 1 4.559950916659301 -6.316720857110099 5.422215632967026 0 -1 0 +99 1 1.6556187341181972 -11.042676696296036 10.823511254079808 0 0 0 +193 1 2.1147403084852634 -6.885083505075134 9.409447220216105 1 1 -1 +33 1 4.45464187128425 -11.736247949088288 7.271061852952995 0 -1 0 +79 1 8.565919655629239 11.638486198403275 5.960760377855752 -1 0 0 +92 1 9.769060714231218 -9.492631803351557 11.102372610406375 0 2 -1 +165 1 -9.212711733999253 -3.259454828813142 7.377981593005203 0 0 0 +199 1 -6.873376106851867 -4.9933518932685566 9.87422952115871 0 -1 1 +70 1 -5.445601633222862 -2.349920544152827 7.807205278865663 0 1 1 +146 1 -1.4368974006040247 -0.5526263308116413 11.329045170425331 2 1 1 +106 1 -1.320489681644758 -2.525949605897458 8.649126125808394 0 0 -1 +52 1 0.6432865601156172 -3.653577986848175 11.390625659771409 0 0 0 +86 1 5.463936380191402 -4.545155299286932 8.600558169678536 -1 0 1 +197 1 1.6297777023246702 -4.6288437196490895 7.127308915254101 -1 0 -1 +185 1 2.117376701545396 -0.6740584604995838 9.981858778655166 -2 1 -2 +190 1 7.391326441541653 -0.2420688149799064 9.912167028101104 0 0 -1 +145 1 7.1433612487852685 -3.600502105720082 -11.787138473864353 -1 -2 0 +131 1 11.237287581981867 -5.265986055819216 6.2884198947288406 1 0 0 +156 1 -5.499196268975016 -0.3842368684419455 11.47923685297254 0 -1 -1 +10 1 -9.091750969544233 -0.8101391784724588 4.798103517685853 0 0 2 +196 1 -9.331229431870144 0.22379652065858124 8.694495890506026 1 2 1 +143 1 -7.138465404537655 3.0174764853722347 8.68001066247089 1 0 0 +13 1 -11.76499693524697 3.321385859999623 6.936314787144568 -1 -1 1 +59 1 -3.4402166179497833 1.730296081472357 9.358944812035546 1 -1 1 +186 1 0.1617283142132493 2.5970365582430226 9.662083422391825 1 1 0 +136 1 3.4199513038280873 2.163828872826315 7.95543255977617 0 -1 -3 +62 1 3.963989117283031 6.890950850270743 8.983560199060738 1 0 0 +192 1 10.513433172209162 2.5350934882928264 9.78265608934408 1 1 1 +113 1 7.161285582100181 2.2124289355489886 6.79272048842973 -1 -1 -1 +74 1 -8.169335431227 9.77557136132564 9.00057456275031 1 -1 0 +118 1 -11.608821137521177 8.521503367814617 7.013321378357836 0 1 0 +117 1 -5.327579617349453 11.314505774662308 7.558097527322893 -1 -1 0 +23 1 -5.129126916477775 5.721102420605024 11.278247239081892 0 0 -2 +171 1 -4.352281149020513 7.112600115001591 7.871167109278595 0 2 -2 +94 1 0.5998107735037941 9.708724091432982 9.014903980367055 -1 0 0 +41 1 5.4449659738536695 11.522021070488632 11.662868284303414 0 0 -1 +141 1 9.872190892571076 5.7761026505659245 8.948318084922565 1 -1 -1 +159 1 9.641274357072867 9.726441601090215 9.76145240542319 0 -1 0 + +Velocities + +39 2.577793097354695 -3.3983788380629387 0.9311775479132861 +57 0.044350439903272976 -2.756321060337954 -1.0428315092461067 +82 -2.504296787676701 -3.6468474399030493 0.2541672097953289 +8 3.6367927137204146 -0.708503612114486 -3.734398328076926 +49 1.8873851156019454 -1.4752561333771483 0.44317628658177016 +54 2.0609459874818237 -3.7591063995516816 6.295629243534251 +114 5.3525465279303015 -3.959388563871946 6.9201302420483755 +128 1.2908060914043953 -2.111376197467554 -0.48873831716967264 +102 -4.571293842871747 8.300052861760934 -2.8260260042769847 +157 0.6864784580965262 2.3741938996988416 3.197851910441299 +20 4.652994650182517 -2.368616661754701 -3.6239824640674376 +147 2.3112278761829046 2.7926157746726785 0.3841905616879638 +169 3.8809056176148298 -3.783797831749185 1.5132762830383186 +123 1.2907138384495385 4.5605260997379515 6.265572889261794 +130 2.3899251274818005 0.27666961403153456 4.415473432866114 +140 1.0077403345435272 3.331618501750946 3.823686801783437 +153 -4.158360194263056 -0.05792314282326738 -0.09170129980331274 +129 -2.0924141264102167 -2.229463311149641 5.774701380963026 +148 4.419535691773222 -2.221801500903651 -1.322900377568077 +119 3.3013302732178436 1.0440417527080033 2.8019660816699443 +174 1.8865107534171663 4.984254074383621 -4.4680569390231515 +134 -3.051462360151183 0.13872483873263985 0.8334720216492622 +189 -1.575075881871396 1.8217362685289014 -2.0444979947436 +28 3.421168174684726 -5.498073809092277 -0.04014458535812704 +1 1.9883484696931384 -5.62737172391044 -0.6897496957906657 +24 -1.2667871307922316 4.30277534955836 -0.9434339008200991 +176 5.33889839399068 -0.7261935889242956 -1.0648636501642632 +182 -1.3434249574772492 -1.2612974855392476 -0.8264254407007674 +137 1.9669241314073078 1.4304166951432975 -0.7941330665668798 +89 3.0037245881229415 0.2485958612228784 0.43340084246330035 +88 -4.773290068397481 -4.145612735120506 2.9587651882723076 +160 3.2238819912540246 1.454427974780249 -0.8931785023147302 +125 -2.027584749577839 0.2846539404784728 -1.9747515011844237 +107 -0.4309962618034694 -3.6977689727188716 -1.9008509957370174 +167 1.1593622921328293 -1.8699221821464713 -0.35243227029296986 +45 3.8023301775972866 1.4226356824680009 0.7412574800338123 +95 -6.444883722807761 -0.36547146467399716 -2.3313614045704956 +111 2.654717565255864 1.4059595144409067 -0.8812624422906502 +37 2.6344865612342447 3.1241557322031097 0.21727945365726709 +53 -1.162490586497141 -1.8114743286402544 -3.3819238034771355 +122 -0.39245032082132514 6.341371204609977 0.15639083036810653 +126 -1.605697227924968 4.594486921923675 2.22444280178021 +72 5.553154164868334 -1.6002168773168566 2.986954509825138 +144 1.3403843285320132 -1.7279031413546053 1.3999311572505995 +135 2.534876793407053 -3.9801581090182863 3.1492981080983657 +183 -4.679242103632781 2.993032322724656 -1.3277928954591556 +155 2.478325342602548 0.096505570078343 0.23454435113676975 +21 -3.5229231861916004 -3.9816529561376006 0.026639755919907415 +66 -4.078355783351698 -0.12178976416838905 3.6922808103625115 +22 -3.6395126219587364 -6.832262596301959 1.5951115669463118 +42 -4.403508549300507 -1.075423056570003 -0.591849033607009 +77 -3.529890611915624 -4.75010415058562 1.6925557776838493 +47 -2.1850961781212535 0.29268584139732723 -6.145825548126078 +46 4.627258609793938 -0.35735610275796525 -4.228603145133978 +18 3.73167019444449 -0.1412650186120299 1.8269713694609548 +14 4.255528637119755 -1.6399584278487664 -2.3670010206718466 +178 -5.547816263652345 -3.2716811779531016 0.3760629173372536 +48 4.425750039051989 -1.6380895084775802 3.0834785539819825 +55 0.9664608309050373 -3.9279561872107216 3.738153737041613 +12 -0.41819517254673283 0.9367025298427245 1.548662259471958 +15 -1.5561256264944465 -1.7138464717908113 -5.214325558070718 +64 -4.340047339400262 -2.22675786620723 -1.8953705605237372 +44 1.1388904606478099 1.1952052434483869 -4.7138321817777165 +188 -0.6813174034115439 -5.349606335139992 -0.5494798369887832 +200 4.5313662932423755 -1.509632335926491 -0.7143667001741889 +198 -0.147474124917653 -4.398760900940008 -1.3829542092135303 +76 3.499335281047853 4.321577651994544 1.8422196851357424 +194 0.40702093571028386 2.536045454224767 -0.25948941675872716 +68 1.095513798887539 6.302453994563069 -0.032465133466722085 +96 -0.8025115532160563 4.133456324521671 -0.3987555142125939 +91 -1.0924701330602116 -4.134760716625712 -2.5476966892452007 +154 -0.6420195815805342 0.5441210237991451 -2.4764714848254394 +19 -6.45757006657402 -1.8917738383254377 -2.2385612755611657 +120 -2.333329676155747 -2.6263663088962446 -0.31608193981125454 +138 -4.2274347886527295 -5.149547905719161 0.18051226809116783 +9 1.9482438581325014 1.836033317169747 4.767132863545005 +150 1.9981648567087547 6.350098740087899 -2.8565846607881165 +38 0.7805411976234249 3.2336875919271204 -5.491325260091564 +172 -1.6067207370017498 -4.025457011374177 3.328473783113818 +152 1.2783569248468387 1.1836235305806408 -2.8398807957375904 +29 0.012522208655832867 -2.202968899510487 1.2653923818179775 +87 2.4301555960867915 -0.3844922649780862 2.3653616101850643 +93 -0.8167645337546143 7.0869554155527865 -0.992159930343214 +195 1.386850643478473 -2.1138124263507945 -2.6343099572277926 +149 -1.9222490388239173 -2.9269314999007365 1.9288615526733388 +25 -3.59971099165819 -1.6866464810245103 1.7143969426226588 +35 1.1068675504822845 2.9570865620910163 1.5489285873628789 +5 -0.06525583154753622 4.64663174535613 0.0051166703840210825 +116 -2.156521693342489 -1.106530196750272 -0.7392284182460408 +112 0.8256766355184204 -3.3427544054629896 2.364051175484082 +132 2.1070952059277808 -0.7636208241660348 -2.901239577070981 +173 0.9555468923097092 0.9205686685241707 -3.199573856104545 +73 1.5067078955449293 -1.4433124895723743 -1.0680684282081363 +161 2.1775187990003184 -2.0432036406877887 -2.502427749527437 +78 0.4277549814794872 0.923985061568942 -4.462582084674592 +11 -0.7883572752861073 -3.298996571191427 5.184829507433079 +84 -0.3908120720288031 0.8981771084266208 2.781123174827333 +90 0.1806374932457661 1.6703751943299625 2.7208543462130645 +36 -1.267739998375956 2.1167954160312523 -2.3987528368253503 +56 0.42755132352919767 0.3105230600944311 -0.03753157138922093 +109 1.9130458422765049 -2.4592218292820647 -3.7955776970359176 +98 2.224412680285525 2.8105570053709483 -6.007751163289515 +115 -2.8264888701698423 -6.77384783439804 -4.5128631453140455 +124 1.0115631212847158 2.197697811017366 -1.4884565302411554 +121 1.819952585372025 2.133685315101777 -0.48009196690211353 +80 3.6825834395072827 2.9369744584874624 0.7772431106319383 +101 3.8152106585296663 -0.7504695117106335 -1.3678083578602058 +4 1.1543968705285124 3.6108919626584783 1.279726012491966 +6 -2.734554328800396 0.45690265044985007 1.7653493310436426 +81 2.173385375162031 -1.545557384488483 -2.635973810143899 +166 -1.239464711076861 1.3504238003340796 -0.49024226288977 +40 1.7898346069542372 -0.4474778752941201 3.4790111502788887 +127 1.6296109635966738 0.6612604860538578 5.807821273928263 +104 -4.901664479006097 1.1052244598202794 3.4465808005881824 +151 -3.983151444075344 -3.2501191110732113 -1.2526584841338049 +60 -1.922006700361108 -0.7785585059363819 -4.390434339117124 +168 -2.788478664171041 3.923738577427861 2.49523972250301 +51 -1.6149322848467969 -3.4296394320723262 4.226459281197094 +97 -1.226730421851149 -2.392775221203476 5.070036120535187 +103 -2.9962982871055357 -2.90339448475708 -1.1348192929647936 +163 0.3128021577268095 -4.112121184421586 2.47129388197539 +175 -4.72131850682648 -1.6008946774115904 -3.6054426092000593 +158 -5.274680729271083 -0.4457302148856164 4.174272671309751 +85 2.9757034033315444 -0.5103121033627565 1.99919210117291 +63 1.600933165736236 1.4604641421860185 5.197681341346513 +133 0.3650834395918216 4.123541846312257 2.1615515366543354 +67 2.0607792864448453 2.3124375339420076 0.21959246817514527 +83 -6.156022387564482 -1.1548915743184078 -0.4948872456362283 +162 -2.1450070724040025 3.9286059442169066 2.007885747151935 +170 1.8166139807691821 -1.95234066921456 -1.8559861240898843 +181 -1.587457433365127 -3.2094890956838205 2.212401241994942 +71 1.7829689662908779 -3.6713609566551657 1.3773962271622693 +31 3.918178411733008 -0.5772484115851036 0.16726508680219976 +139 -4.560722486125075 -0.5471630166750243 5.863010868871481 +3 -3.9686726349917825 3.6173076990026054 2.5273959166862507 +108 0.3042801304200664 4.847444330423647 -0.35518169829313484 +16 -2.4685650045584717 5.98056595230015 0.9384145704518219 +110 -0.6129548866614436 1.8199747299312752 -0.6050782543434758 +50 -1.8884152067915962 -1.4877561250799833 -3.9811275374353494 +191 1.500896458072849 -1.9099553342822155 -5.024921011162899 +187 -2.013243274912701 -0.8604266013822317 -1.038480536601888 +180 1.4966822969502809 2.2104050426784707 3.732721924128324 +30 -2.3551911487538373 -1.0313809690434763 -1.4871503115129143 +2 2.4972367326603697 -1.5125466361921762 1.0762650051734106 +17 0.43112912988867413 -1.9548201848493156 -0.43017998184207773 +7 6.622180146484479 4.7673609572662725 0.19425898871224434 +164 2.301415823751322 0.4827221772498991 4.559127095693677 +69 -3.4364505629674733 -1.1594038113628669 -1.2078137888752072 +61 1.7869953777023173 0.9935547623401149 0.14745693195171444 +34 -0.027807484985171937 -3.1354780466577754 -1.036977576868685 +43 -1.3037743820903311 -5.61028065095172 -4.306710886889687 +177 2.1781720801097206 -1.516912077043328 -2.054689845757315 +179 0.4934049365569875 -4.8639422788504625 -6.225153590664796 +65 2.6970228261721383 0.19294320506195817 6.683323231860031 +27 -1.6731814501881797 0.7519385590564082 3.2183027406212203 +58 -0.7774753429967389 -0.6669437971456971 3.5183225900940927 +32 -5.389835933890947 -0.4954507654154201 0.4594525916972694 +26 0.7382474998065096 -3.102724138188651 -2.185686698723454 +142 -1.944479379421283 -1.2761486898263725 0.72348529709274 +100 -2.739025692998968 -2.6245009262596986 3.182008026346906 +184 1.4210317521782347 3.1395926369797884 5.319543188841913 +105 -1.2308708716614136 -1.2494207925918743 -3.3415190888725443 +75 -1.8835854547991517 -1.3807763884880995 3.052239941977269 +99 2.3501462152911015 -0.09098282020287418 -2.963130739502538 +193 3.2483282921859455 -6.045063326765766 -1.2297831607518321 +33 -1.5552221515820004 2.623852853566988 -0.3953508079233695 +79 2.0518370606822334 1.899510113710928 2.0859744201323727 +92 1.5026700715390955 0.9352029472761221 -5.528904283783295 +165 -2.240438523644089 -0.6103912799862421 0.40653914875448993 +199 -1.2653571662196268 3.710626862073433 1.4730516528440072 +70 1.655492430853343 0.17760859693009826 -1.650919734678463 +146 -1.4225048482747793 2.74232833480091 -3.413198079564811 +106 -1.093901348299414 0.20953760114868714 -0.7298112830112282 +52 6.647000075136453 -0.30141024565553315 1.2035752428962934 +86 0.6741589587443484 4.365068713763016 3.5677961016049315 +197 -0.666824417721529 0.7257967702216201 6.272517109849018 +185 -1.1845876194928404 2.1001111189632264 2.457366035714506 +190 -1.6517508143986053 2.271851696760304 3.7976228734124575 +145 -0.6660913411508007 -2.1887913545610314 1.427073342591097 +131 3.4923356345857024 1.8910870819349503 0.22757964871813297 +156 1.3901143776938099 -0.5912367128957199 -1.945898273856384 +10 -3.3254266550003906 2.363446512042732 -2.8505669909097167 +196 1.9772342503358795 2.9791453967072834 5.0702556945320305 +143 1.3619198656944898 -4.070780999483669 0.554762511858757 +13 -3.6607073229889986 -6.103961980753075 3.3895476442791126 +59 1.3424546798513801 -0.012418821554116527 -1.0607350515292961 +186 -0.19147109350375446 -0.14042042908600805 -5.06183250631794 +136 10.318783006250738 -0.33198398090799297 -3.1695432610471372 +62 -0.9320061937291512 -8.919718141167188 -1.0031472261072583 +192 -6.036717500669019 -0.4626110813075395 -5.283002697165421 +113 -1.9312339562598033 1.2868323831429733 -0.27836767602350954 +74 0.289298974376203 4.639184114550362 -1.3074893268836063 +118 2.3186362762712704 0.014757210175651903 -1.9096714905556824 +117 2.917320124569121 -0.927139463682407 -2.038093079844118 +23 3.445296199640721 -2.484450168397722 6.150025302403371 +171 -1.3488599922862394 -0.40015537573335275 5.541824987776105 +94 2.7016234671889183 -4.500360725821148 -0.3771036206116729 +41 0.040051409073174504 1.3144504850460685 -2.628956804481983 +141 0.8101589418958534 -0.40901282998394567 2.3777914588666906 +159 -2.168905163137191 -3.9077440516609387 3.1238186982134213 diff --git a/examples/PACKAGES/pimd/lj/in.lmp b/examples/PACKAGES/pimd/lj/in.lmp new file mode 100755 index 0000000000..9670225958 --- /dev/null +++ b/examples/PACKAGES/pimd/lj/in.lmp @@ -0,0 +1,28 @@ +variable ibead uloop 99 pad + +units metal +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 9.5251 +read_data data.metalnpt${ibead} + +pair_coeff * * 0.00965188 3.4 +pair_modify shift yes + +mass 1 39.948 + +timestep 0.001 + +velocity all create 0.0 ${ibead} + +fix 1 all pimd/langevin ensemble npt integrator obabo thermostat PILE_L 1234 tau 1.0 temp 113.15 iso 1.0 barostat BZP taup 1.0 fixcom no + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no format line "%d %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f" + +dump dcd all custom 100 ${ibead}.xyz id type xu yu zu vx vy vz ix iy iz fx fy fz +dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 diff --git a/examples/PACKAGES/pimd/lj/run.sh b/examples/PACKAGES/pimd/lj/run.sh new file mode 100644 index 0000000000..2580ef1a41 --- /dev/null +++ b/examples/PACKAGES/pimd/lj/run.sh @@ -0,0 +1 @@ +mpirun -np 4 $LMP -in in.lmp -p 4x1 -log log -screen screen From 0dd8a6aea2e9183a4b88d13cf36de3307851ae9f Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 20 Mar 2023 14:27:58 -0400 Subject: [PATCH 040/448] add document for keywords of fix pimd/langevin --- doc/src/fix_pimd.rst | 48 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 28a5308dd7..d6808add44 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -24,7 +24,7 @@ Syntax *method* value = *pimd* or *nmpimd* or *cmd* *fmass* value = scaling factor on mass *sp* value = scaling factor on Planck constant - *temp* value = temperature (temperarate units) + *temp* value = temperature (temperature units) *nhc* value = Nc = number of chains in Nose-Hoover thermostat * keywords for style *pimd/langevin* @@ -35,8 +35,8 @@ Syntax *integrator* value = *obabo* or *baoab* *fmmode* value = *physical* or *normal* *fmass* value = scaling factor on mass - *temp* value = Temperature (temperarate unit) - Temperature = target temperarate of the thermostat + *temp* value = Temperature (temperature unit) + Temperature = target temperature of the thermostat *thermostat* values = style seed style value = *PILE_L* seed = random number generator seed @@ -180,6 +180,38 @@ The keyword *sp* is a scaling factor on Planck's constant, which can be useful for debugging or other purposes. The default value of 1.0 is appropriate for most situations. +The keyword *ensemble* for fix style *pimd/langevin* determines which ensemble is it +going to sample. The value can be *nve* (microcanonical), *nvt* (canonical), *nph* (isoenthalpic), and *npt* (isothermal-isobaric). + +The keyword *temp* specifies temperature parameter for fix styles *pimd/nvt* and *pimd/langevin*. It should read a +positive floating-point number. +.. note:: + For pimd simulations, a temperature values should be specified even for nve ensemble. Temperature will make a difference + for nve pimd, since the spring elastic frequency between the beads will be affected by the temperature. + +The keyword *thermostat* reads *style* and *seed* of thermostat for fix style *pimd/langevin*. *style* can only +be *PILE_L* (path integral Langevin equation local thermostat, as described in :ref:`(Manolopoulos) `), and *seed* should a positive integer number, which serves as the seed of the pseudo random number generator. + +.. note:: + The fix style *pimd/langevin* uses the stochastic PILE_L thermostat to control temperature. This thermostat works on the normal modes + of the ring polymer. The *tau* parameter controls the centroid mode, and the *scale* parameter controls the non-centroid modes. + +The keyword *tau* specifies the thermostat damping time parameter for fix style *pimd/langevin*. It is in time unit. It only works on the centroid mode. + +The keyword *scale* specifies a scaling parameter for the damping times of the non-centroid modes for fix style *pimd/langevin*. The default +damping time of the non-centroid mode $i$ is $\frac{P}{\beta\hbar}\sqrt{\lambda_i\times\mathrm{fmass}}$ (*fmmode* is *physical*) or $\frac{P}{\beta\hbar}\sqrt{\mathrm{fmass}}$ (*fmmode* is *normal*). The damping times of all non-centroid modes are the default values divided by *scale*. + +The barostat parameters for fix style *pimd/langevin* with *npt* or *nph* ensemble is specified using one of *iso* and *aniso* +keywords. A *pressure* value should be given with pressure unit. The keyword *iso* means couple all 3 diagonal components together when pressure is computed (hydrostatic pressure), and dilate/contract the dimensions together. The keyword *aniso* means x, y, and z dimensions are controlled independently using the Pxx, Pyy, and Pzz components of the stress tensor as the driving forces, and the specified scalar external pressure. + +The keyword *barostat* reads *style* of barostat for fix style *pimd/langevin*. *style* can +be *BZP* (Bussi-Zykova-Parrinello, as described in :ref:`(Parrinello1) `) or *MTTK* (Martyna-Tuckerman-Tobias-Klein, as described in :ref:`(Tuckerman2) `). + +The keyword *taup* specifies the barostat damping time parameter for fix style *pimd/langevin*. It is in time unit. + +The keyword *fixcom* specifies whether the center-of-mass of the extended ring-polymer system is fixed during the pimd simulation. +Once *fixcom* is set te be *yes*, the center-of-mass velocity will be distracted from the centroid-mode velocities in each step. + The PIMD algorithm in LAMMPS is implemented as a hyper-parallel scheme as described in :ref:`(Calhoun) `. In LAMMPS this is done by using :doc:`multi-replica feature ` in LAMMPS, where each @@ -314,4 +346,12 @@ Path Integrals, McGraw-Hill, New York (1965). .. _Manolopoulos: -**(Manolopoulos)** M. Ceriotti, M. Parrinello, T. Markland, D. Manolopoulos, J. Chem. Phys. 133, 124104 (2010). \ No newline at end of file +**(Manolopoulos)** M. Ceriotti, M. Parrinello, T. Markland, D. Manolopoulos, J. Chem. Phys. 133, 124104 (2010). + +.. _Klein: + +**(Klein)** G. Martyna, D. Tobias, M. Klein, J. Chem. Phys. 101, 4177 (1994). + +.. _Tuckerman2: + +**(Tuckerman2)** G. Martyna, A. Hughes, M. Tuckerman, J. Chem. Phys. 110, 3275 (1999). \ No newline at end of file From 3d47c5c6f0fccaf27bf9d81a74df25d29856ab2e Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Tue, 21 Mar 2023 08:38:14 -0400 Subject: [PATCH 041/448] add x/y/z barostating options --- src/REPLICA/fix_pimd_langevin.cpp | 86 ++++++++++++++++++++++--------- src/REPLICA/fix_pimd_langevin.h | 4 +- 2 files changed, 65 insertions(+), 25 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index e1d3960a50..d64d948ecf 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -101,6 +101,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : tau = 1.0; tau_p = 1.0; Pext = 1.0; + pdim = 0; pilescale = 1.0; tstat_flag = 1; pstat_flag = 0; @@ -112,7 +113,11 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : int seed = -1; - for (int i = 0; i < 6; i++) p_flag[i] = 0; + for (int i = 0; i < 6; i++) + { + p_flag[i] = 0; + p_target[i] = 0.0; + } for (int i = 3; i < narg - 1; i += 2) { if (strcmp(arg[i], "method") == 0) { @@ -199,9 +204,29 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : } else if (strcmp(arg[i], "iso") == 0) { pstyle = ISO; Pext = utils::numeric(FLERR, arg[i+1], false, lmp); + p_target[0] = p_target[1] = p_target[2] = Pext; + pdim = 3; } else if (strcmp(arg[i], "aniso") == 0) { pstyle = ANISO; + p_flag[0] = p_flag[1] = p_flag[2] = 1; Pext = utils::numeric(FLERR, arg[i+1], false, lmp); + p_target[0] = p_target[1] = p_target[2] = Pext; + pdim = 3; + } else if (strcmp(arg[i], "x") == 0) { + pstyle = ANISO; + p_flag[0] = 1; + p_target[0] = utils::numeric(FLERR, arg[i+1], false, lmp); + pdim++; + } else if (strcmp(arg[i], "y") == 0) { + pstyle = ANISO; + p_flag[1] = 1; + p_target[1] = utils::numeric(FLERR, arg[i+1], false, lmp); + pdim++; + } else if (strcmp(arg[i], "z") == 0) { + pstyle = ANISO; + p_flag[2] = 1; + p_target[2] = utils::numeric(FLERR, arg[i+1], false, lmp); + pdim++; } else if (strcmp(arg[i], "taup") == 0) { tau_p = utils::numeric(FLERR, arg[i + 1], false, lmp); if (tau_p <= 0.0) error->universe_all(FLERR, "Invalid tau_p value for fix pimd/langevin"); @@ -243,6 +268,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : fixedpoint[0] = 0.5 * (domain->boxlo[0] + domain->boxhi[0]); fixedpoint[1] = 0.5 * (domain->boxlo[1] + domain->boxhi[1]); fixedpoint[2] = 0.5 * (domain->boxlo[2] + domain->boxhi[2]); + if (pstat_flag) { p_hydro = (p_target[0]+p_target[1]+p_target[2])/pdim; } // initialize Marsaglia RNG with processor-unique seed @@ -670,8 +696,15 @@ void FixPIMDLangevin::qc_step() if (barostat == BZP) { for (int i = 0; i < nlocal; i++) { for (int j = 0; j < 3; j++) { - x[i][j] = expq[j] * x[i][j] + (expq[j] - expp[j]) / 2. / vw[j] * v[i][j]; - v[i][j] = expp[j] * v[i][j]; + if (p_flag[j]) + { + x[i][j] = expq[j] * x[i][j] + (expq[j] - expp[j]) / 2. / vw[j] * v[i][j]; + v[i][j] = expp[j] * v[i][j]; + } + else + { + x[i][j] += dtv * v[i][j]; + } } } oldlo = domain->boxlo[0]; @@ -762,7 +795,7 @@ void FixPIMDLangevin::press_v_step() if (pstyle == ISO) { if (barostat == BZP) { - vw[0] += dtv * 3 * (volume * np * (p_cv - Pext) / force->nktv2p + Vcoeff / beta_np) / W; + vw[0] += dtv * 3 * (volume * np * (p_cv - p_hydro) / force->nktv2p + Vcoeff / beta_np) / W; if (universe->iworld == 0) { double dvw_proc = 0.0, dvw = 0.0; for (int i = 0; i < nlocal; i++) { @@ -777,22 +810,25 @@ void FixPIMDLangevin::press_v_step() MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); } else if (barostat == MTTK) { mtk_term1 = 2. / atom->natoms * totke / 3; - f_omega = (volume * np * (p_md - Pext) + mtk_term1) / W; + f_omega = (volume * np * (p_md - p_hydro) + mtk_term1) / W; vw[0] += 0.5 * dtv * f_omega; } } else if (pstyle == ANISO) { compute_stress_tensor(); for (int ii = 0; ii < 3; ii++) { - vw[ii] += - dtv * (volume * np * (stress_tensor[ii] - Pext) / force->nktv2p + Vcoeff / beta_np) / W; - if (universe->iworld == 0) { - double dvw_proc = 0.0, dvw = 0.0; - for (int i = 0; i < nlocal; i++) { - dvw_proc += - dtv2 * f[i][ii] * v[i][ii] / W + dtv3 * f[i][ii] * f[i][ii] / mass[type[i]] / W; + if (p_flag[ii]) + { + vw[ii] += + dtv * (volume * np * (stress_tensor[ii] - p_hydro) / force->nktv2p + Vcoeff / beta_np) / W; + if (universe->iworld == 0) { + double dvw_proc = 0.0, dvw = 0.0; + for (int i = 0; i < nlocal; i++) { + dvw_proc += + dtv2 * f[i][ii] * v[i][ii] / W + dtv3 * f[i][ii] * f[i][ii] / mass[type[i]] / W; + } + MPI_Allreduce(&dvw_proc, &dvw, 1, MPI_DOUBLE, MPI_SUM, world); + vw[ii] += dvw; } - MPI_Allreduce(&dvw_proc, &dvw, 1, MPI_DOUBLE, MPI_SUM, world); - vw[ii] += dvw; } } } @@ -811,12 +847,14 @@ void FixPIMDLangevin::press_o_step() MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); } else if (pstyle == ANISO) { if (universe->me == 0) { - r1 = random->gaussian(); - r2 = random->gaussian(); - r3 = random->gaussian(); - vw[0] = c1 * vw[0] + c2 * sqrt(1.0 / W / beta_np) * r1; - vw[1] = c1 * vw[1] + c2 * sqrt(1.0 / W / beta_np) * r2; - vw[2] = c1 * vw[2] + c2 * sqrt(1.0 / W / beta_np) * r3; + for (int ii=0; ii<3; ii++) + { + if (p_flag[ii]) + { + r1 = random->gaussian(); + vw[ii] = c1 * vw[ii] + c2 * sqrt(1.0 / W / beta_np) * r1; + } + } } MPI_Barrier(universe->uworld); MPI_Bcast(&vw, 3, MPI_DOUBLE, 0, universe->uworld); @@ -1145,7 +1183,7 @@ void FixPIMDLangevin::remove_com_motion(){ int nlocal = atom->nlocal; if (dynamic) masstotal = group->mass(igroup); double vcm[3]; - group->vcm(igroup,masstotal,vcm); + group->vcm(igroup,masstotal,vcm); for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { v[i][0] -= vcm[0]; @@ -1329,15 +1367,15 @@ void FixPIMDLangevin::compute_totenthalpy() volume = domain->xprd * domain->yprd * domain->zprd; if (barostat == BZP) { if (pstyle == ISO) { - totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + Pext * volume / force->nktv2p - + totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + p_hydro * volume / force->nktv2p - Vcoeff * kBT * log(volume); } else if (pstyle == ANISO) { totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + 0.5 * W * vw[1] * vw[1] * inverse_np + 0.5 * W * vw[2] * vw[2] * inverse_np + - Pext * volume / force->nktv2p - Vcoeff * kBT * log(volume); + p_hydro * volume / force->nktv2p - Vcoeff * kBT * log(volume); } } else if (barostat == MTTK) - totenthalpy = tote + 1.5 * W * vw[0] * vw[0] * inverse_np + Pext * (volume - vol0); + totenthalpy = tote + 1.5 * W * vw[0] * vw[0] * inverse_np + p_hydro * (volume - vol0); } /* ---------------------------------------------------------------------- */ diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index b8bed1a10f..6d236718c7 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -126,8 +126,10 @@ class FixPIMDLangevin : public Fix { double f_omega, mtk_term1; int pstat_flag; // pstat_flag = 1 if barostat is used int pstyle; // pstyle = ISO or ANISO (will support TRICLINIC in the future) - double W, tau_p, Pext, totenthalpy, Vcoeff; + double W, tau_p, Pext, p_hydro, totenthalpy, Vcoeff; + int pdim; int p_flag[6]; + double p_target[6]; double vw[6]; // barostat velocity double ke_tensor[6]; // kinetic energy tensor double c_vir_tensor[6]; // centroid-virial tensor From f94bea8d972d1f6f7064ebf599283a2d6b89e9d7 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Tue, 21 Mar 2023 09:22:37 -0400 Subject: [PATCH 042/448] correct fix pimd/langevin example file permission --- examples/PACKAGES/pimd/lj/in.lmp | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 examples/PACKAGES/pimd/lj/in.lmp diff --git a/examples/PACKAGES/pimd/lj/in.lmp b/examples/PACKAGES/pimd/lj/in.lmp old mode 100755 new mode 100644 From 2cb9d2784bd3522911a456029ad3fd7b21f8522a Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Tue, 21 Mar 2023 09:23:04 -0400 Subject: [PATCH 043/448] add false_positive for fix pimd/langevin doc --- doc/utils/sphinx-config/false_positives.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 0f18e6822f..e8544a8975 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -2017,6 +2017,7 @@ Marchetti Marchi Mariella Marinica +Markland Marrink Marroquin Marsaglia @@ -3577,6 +3578,7 @@ THz Tigran Tij Tildesley +Timan timeI timespan timestamp @@ -4071,4 +4073,5 @@ zu zx zy Zybin +Zykova zz From 32efa1a3af3462c740afd90a1c2fdbbd02ef1e91 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Tue, 21 Mar 2023 09:23:22 -0400 Subject: [PATCH 044/448] update fix pimd/langevin doc --- doc/src/fix_pimd.rst | 87 +++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index d6808add44..4d72d7232f 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -30,7 +30,8 @@ Syntax * keywords for style *pimd/langevin* .. parsed-literal:: - *keywords* = *method* or *integrator* or *ensemble* or *fmmode* or *fmass* or *scale* or *temp* or *thermostat* or *tau* or or *iso* or *aniso* or *barostat* or *taup* or *fixcom* or *lj* + *keywords* = *method* or *integrator* or *ensemble* or *fmmode* or *fmass* or *scale* or *temp* or *thermostat* or + *tau*or or *iso* or *aniso* or *barostat* or *taup* or *fixcom* or *lj* *method* value = *nmpimd* *integrator* value = *obabo* or *baoab* *fmmode* value = *physical* or *normal* @@ -43,7 +44,7 @@ Syntax *tau* value = thermostat damping parameter (time unit) *scale* value = scaling factor of the damping times of non-centroid modes of PILE_L thermostat *iso* or *aniso* values = Pressure (pressure unit) - Pressure = scalar external pressure of the barostat + Pressure = scalar external pressure of the barostat *barostat* value = *BZP* or *MTTK* *taup* value = barostat damping parameter (time unit) *fixcom* value = *yes* or *no* @@ -85,7 +86,7 @@ by the following equations: H_{eff} = & \bigg(\sum_{i=1}^P \frac{p_i^2}{2M_i}\bigg) + V_{eff} \\ V_{eff} = & \sum_{i=1}^P \bigg[ \frac{mP}{2\beta^2 \hbar^2} (q_i - q_{i+1})^2 + \frac{1}{P} V(q_i)\bigg] -$M_i$ is the fictitious mass of the $i$-th mode, and m is the actual mass of the atoms. +:math:`M_i` is the fictitious mass of the :math:`i`-th mode, and m is the actual mass of the atoms. The interested user is referred to any of the numerous references on this methodology, but briefly, each quantum particle in a path integral @@ -109,8 +110,9 @@ would be 3 x N x P x Nc. Fix *pimd/nvt* implements a complete velocity-verlet integrator combined with NH massive chain thermostat, so no other time integration fix should be used. + Fix *pimd/langevin* implements a complete velocity-verlet integrator - combined with Langevin thermostat in the normal mode representation, and + combined with Langevin thermostat in the normal mode representation, and also provides a barostat to sample the NPH/NPT ensembles. The *method* keyword determines what style of PIMD is performed. A @@ -136,7 +138,7 @@ normal-mode PIMD. A value of *cmd* is for centroid molecular dynamics the real particle. .. note:: - Fix pimd/langevin only supports *method* value *nmpimd*. This should be enough + Fix pimd/langevin only supports *method* value *nmpimd*. This should be enough for most PIMD applications for quantum thermodynamics purpose. Motion of the centroid can be effectively uncoupled from the other @@ -155,42 +157,51 @@ masses of beads, which can be used for the Partial Adiabatic CMD :ref:`(Hone) `, or to be set as P, which results in the fictitious masses to be equal to the real particle masses. -The keyword *fmmode* of *fix pimd/langevin* determines the mode of fictitious -mass preconditioning. There are two options: *physical* and *normal*. If *fmmode* is +The keyword *fmmode* of *fix pimd/langevin* determines the mode of fictitious +mass preconditioning. There are two options: *physical* and *normal*. If *fmmode* is *physical*, then the physical mass of the particles are used (and then multiplied by -*fmass*). If *fmmode* is *normal*, then the physical mass is first multiplied by the -eigenvalue of each normal mode, and then multiplied by *fmass*. More precisely, the +*fmass*). If *fmmode* is *normal*, then the physical mass is first multiplied by the +eigenvalue of each normal mode, and then multiplied by *fmass*. More precisely, the fictitious mass of *fix pimd/langevin* is determined by two factors: *fmmode* and *fmass*. If *fmmode* is *physical*, then the fictitious mass is -.. math:: - $M_i = \mathrm{fmass} \times m$ - -If *fmmode* is *normal*, then the fictitious mass is -.. math:: - $M_i = \mathrm{fmass} \times \lambda_i \times m$ -where $\lambda_i$ is the eigenvalue of the $i$-th normal mode. +.. math:: + + M_i = \mathrm{fmass} \times m + +If *fmmode* is *normal*, then the fictitious mass is + +.. math:: + + M_i = \mathrm{fmass} \times \lambda_i \times m + +where :math:`\lambda_i` is the eigenvalue of the :math:`i`-th normal mode. + .. note:: + Fictitious mass is only used in the momentum of the equation of motion - ($\bf{p}_i=M_i\bf{v}_i$), and not used in the spring elastic energy - ($\sum_{i=1}^P \frac{1}{2}m\omega_P^2(q_i - q_{i+1})^2$, $m$ is always the - actual mass of the particles). + (:math:`\mathbf{p}_i=M_i\mathbf{v}_i`), and not used in the spring elastic energy + (:math:`\sum_{i=1}^P \frac{1}{2}m\omega_P^2(q_i - q_{i+1})^2`, :math:`m` is always the + actual mass of the particles). The keyword *sp* is a scaling factor on Planck's constant, which can be useful for debugging or other purposes. The default value of 1.0 is appropriate for most situations. -The keyword *ensemble* for fix style *pimd/langevin* determines which ensemble is it -going to sample. The value can be *nve* (microcanonical), *nvt* (canonical), *nph* (isoenthalpic), and *npt* (isothermal-isobaric). +The keyword *ensemble* for fix style *pimd/langevin* determines which ensemble is it +going to sample. The value can be *nve* (microcanonical), *nvt* (canonical), *nph* (isoenthalpic), +and *npt* (isothermal-isobaric). + +The keyword *temp* specifies temperature parameter for fix styles *pimd/nvt* and *pimd/langevin*. It should read +a positive floating-point number. -The keyword *temp* specifies temperature parameter for fix styles *pimd/nvt* and *pimd/langevin*. It should read a -positive floating-point number. .. note:: + For pimd simulations, a temperature values should be specified even for nve ensemble. Temperature will make a difference for nve pimd, since the spring elastic frequency between the beads will be affected by the temperature. The keyword *thermostat* reads *style* and *seed* of thermostat for fix style *pimd/langevin*. *style* can only -be *PILE_L* (path integral Langevin equation local thermostat, as described in :ref:`(Manolopoulos) `), and *seed* should a positive integer number, which serves as the seed of the pseudo random number generator. +be *PILE_L* (path integral Langevin equation local thermostat, as described in :ref:`Ceriotti `), and *seed* should a positive integer number, which serves as the seed of the pseudo random number generator. .. note:: The fix style *pimd/langevin* uses the stochastic PILE_L thermostat to control temperature. This thermostat works on the normal modes @@ -199,21 +210,21 @@ be *PILE_L* (path integral Langevin equation local thermostat, as described in : The keyword *tau* specifies the thermostat damping time parameter for fix style *pimd/langevin*. It is in time unit. It only works on the centroid mode. The keyword *scale* specifies a scaling parameter for the damping times of the non-centroid modes for fix style *pimd/langevin*. The default -damping time of the non-centroid mode $i$ is $\frac{P}{\beta\hbar}\sqrt{\lambda_i\times\mathrm{fmass}}$ (*fmmode* is *physical*) or $\frac{P}{\beta\hbar}\sqrt{\mathrm{fmass}}$ (*fmmode* is *normal*). The damping times of all non-centroid modes are the default values divided by *scale*. +damping time of the non-centroid mode :math:`i` is :math:`\frac{P}{\beta\hbar}\sqrt{\lambda_i\times\mathrm{fmass}}` (*fmmode* is *physical*) or :math:`\frac{P}{\beta\hbar}\sqrt{\mathrm{fmass}}` (*fmmode* is *normal*). The damping times of all non-centroid modes are the default values divided by *scale*. -The barostat parameters for fix style *pimd/langevin* with *npt* or *nph* ensemble is specified using one of *iso* and *aniso* +The barostat parameters for fix style *pimd/langevin* with *npt* or *nph* ensemble is specified using one of *iso* and *aniso* keywords. A *pressure* value should be given with pressure unit. The keyword *iso* means couple all 3 diagonal components together when pressure is computed (hydrostatic pressure), and dilate/contract the dimensions together. The keyword *aniso* means x, y, and z dimensions are controlled independently using the Pxx, Pyy, and Pzz components of the stress tensor as the driving forces, and the specified scalar external pressure. The keyword *barostat* reads *style* of barostat for fix style *pimd/langevin*. *style* can -be *BZP* (Bussi-Zykova-Parrinello, as described in :ref:`(Parrinello1) `) or *MTTK* (Martyna-Tuckerman-Tobias-Klein, as described in :ref:`(Tuckerman2) `). +be *BZP* (Bussi-Zykova-Parrinello, as described in :ref:`Bussi `) or *MTTK* (Martyna-Tuckerman-Tobias-Klein, as described in :ref:`Martyna1 ` and :ref:`Martyna2 `). The keyword *taup* specifies the barostat damping time parameter for fix style *pimd/langevin*. It is in time unit. -The keyword *fixcom* specifies whether the center-of-mass of the extended ring-polymer system is fixed during the pimd simulation. -Once *fixcom* is set te be *yes*, the center-of-mass velocity will be distracted from the centroid-mode velocities in each step. +The keyword *fixcom* specifies whether the center-of-mass of the extended ring-polymer system is fixed during the pimd simulation. +Once *fixcom* is set to be *yes*, the center-of-mass velocity will be distracted from the centroid-mode velocities in each step. The PIMD algorithm in LAMMPS is implemented as a hyper-parallel scheme -as described in :ref:`(Calhoun) `. In LAMMPS this is done by using +as described in :ref:`Calhoun `. In LAMMPS this is done by using :doc:`multi-replica feature ` in LAMMPS, where each quasi-particle system is stored and simulated on a separate partition of processors. The following diagram illustrates this approach. The @@ -340,18 +351,18 @@ Path Integrals, McGraw-Hill, New York (1965). **(Herman)** M. F. Herman, E. J. Bruskin, B. J. Berne, J Chem Phys, 76, 5150 (1982). -.. _Parrinello1: +.. _Bussi: -**(Parrinello1)** G. Bussi, T. Zykova-Timan, M. Parrinello, J Chem Phys, 130, 074101 (2009). +**(Bussi)** G. Bussi, T. Zykova-Timan, M. Parrinello, J Chem Phys, 130, 074101 (2009). -.. _Manolopoulos: +.. _Ceriotti: -**(Manolopoulos)** M. Ceriotti, M. Parrinello, T. Markland, D. Manolopoulos, J. Chem. Phys. 133, 124104 (2010). +**(Ceriotti)** M. Ceriotti, M. Parrinello, T. Markland, D. Manolopoulos, J. Chem. Phys. 133, 124104 (2010). -.. _Klein: +.. _Martyna1: -**(Klein)** G. Martyna, D. Tobias, M. Klein, J. Chem. Phys. 101, 4177 (1994). +**(Martyna1)** G. Martyna, D. Tobias, M. Klein, J. Chem. Phys. 101, 4177 (1994). -.. _Tuckerman2: +.. _Martyna2: -**(Tuckerman2)** G. Martyna, A. Hughes, M. Tuckerman, J. Chem. Phys. 110, 3275 (1999). \ No newline at end of file +**(Martyna2)** G. Martyna, A. Hughes, M. Tuckerman, J. Chem. Phys. 110, 3275 (1999). From 2c0ac8299640305499f46f48b5641b8734456d9f Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Tue, 21 Mar 2023 09:54:29 -0400 Subject: [PATCH 045/448] update doc press -> iso --- doc/src/fix_pimd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 4d72d7232f..75ba85bc96 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -61,7 +61,7 @@ Examples .. code-block:: LAMMPS fix 1 all pimd/nvt method nmpimd fmass 1.0 sp 2.0 temp 300.0 nhc 4 - fix 1 all pimd/langevin ensemble npt integrator obabo temp 113.15 thermostat PILE_L 1234 tau 1.0 press 1.0 barostat BZP taup 1.0 iso + fix 1 all pimd/langevin ensemble npt integrator obabo temp 113.15 thermostat PILE_L 1234 tau 1.0 iso 1.0 barostat BZP taup 1.0 Description """"""""""" From af8d4788b8bd4545ef88e098c6dc99a702862866 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Tue, 21 Mar 2023 10:11:37 -0400 Subject: [PATCH 046/448] fix doc errors --- doc/src/fix_pimd.rst | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 75ba85bc96..db6700633f 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -30,21 +30,20 @@ Syntax * keywords for style *pimd/langevin* .. parsed-literal:: - *keywords* = *method* or *integrator* or *ensemble* or *fmmode* or *fmass* or *scale* or *temp* or *thermostat* or - *tau*or or *iso* or *aniso* or *barostat* or *taup* or *fixcom* or *lj* + *keywords* = *method* or *integrator* or *ensemble* or *fmmode* or *fmass* or *scale* or *temp* or *thermostat* or *tau* or *iso* or *aniso* or *barostat* or *taup* or *fixcom* or *lj* *method* value = *nmpimd* *integrator* value = *obabo* or *baoab* *fmmode* value = *physical* or *normal* *fmass* value = scaling factor on mass - *temp* value = Temperature (temperature unit) - Temperature = target temperature of the thermostat + *temp* value = temperature (temperature unit) + temperature = target temperature of the thermostat *thermostat* values = style seed style value = *PILE_L* seed = random number generator seed *tau* value = thermostat damping parameter (time unit) *scale* value = scaling factor of the damping times of non-centroid modes of PILE_L thermostat - *iso* or *aniso* values = Pressure (pressure unit) - Pressure = scalar external pressure of the barostat + *iso* or *aniso* values = pressure (pressure unit) + pressure = scalar external pressure of the barostat *barostat* value = *BZP* or *MTTK* *taup* value = barostat damping parameter (time unit) *fixcom* value = *yes* or *no* From 6fc17bfa17754b8d55b7dd7bade1a6d46ea59c10 Mon Sep 17 00:00:00 2001 From: jwillma2 <52575231+jwillma2@users.noreply.github.com> Date: Tue, 21 Mar 2023 22:50:17 -0400 Subject: [PATCH 047/448] Add files via upload Coefficient and parameter files for carbon SNAP potential as described in Phys. Rev. B 106, L180101 (2022) --- .../C_Willman_PRB2022.quadratic.snapcoeff | 1602 +++++++++++++++++ .../C_Willman_PRB2022.quadratic.snapparam | 10 + 2 files changed, 1612 insertions(+) create mode 100644 potentials/C_Willman_PRB2022.quadratic.snapcoeff create mode 100644 potentials/C_Willman_PRB2022.quadratic.snapparam diff --git a/potentials/C_Willman_PRB2022.quadratic.snapcoeff b/potentials/C_Willman_PRB2022.quadratic.snapcoeff new file mode 100644 index 0000000000..4ef88ade03 --- /dev/null +++ b/potentials/C_Willman_PRB2022.quadratic.snapcoeff @@ -0,0 +1,1602 @@ +# fitsnap fit generated on 2021-10-15 08:21:38.396384 + +1 1596 +C 0.5 1.0 + -2.7758927591660334 # B[0] + 0.00859216942217639126 # B[1, 0, 0, 0] + 0.16638458601459194 # B[2, 1, 0, 1] + 0.22261822339506554 # B[3, 1, 1, 2] + 0.257355166247009937 # B[4, 2, 0, 2] + 0.802105904460230779 # B[5, 2, 1, 3] + 0.227216469467176801 # B[6, 2, 2, 2] + 0.494646284119575508 # B[7, 2, 2, 4] + 0.276718638025069574 # B[8, 3, 0, 3] + 1.09101782892605392 # B[9, 3, 1, 4] + 0.775283725099378151 # B[10, 3, 2, 3] + -0.232869556477520168 # B[11, 3, 2, 5] + 0.188466708736270222 # B[12, 3, 3, 4] + -0.213463540195325957 # B[13, 3, 3, 6] + 0.285049005401720568 # B[14, 4, 0, 4] + -0.248039138369940321 # B[15, 4, 1, 5] + -0.017694405190132434 # B[16, 4, 2, 4] + -0.513770238875468355 # B[17, 4, 2, 6] + -0.603368424950793791 # B[18, 4, 3, 5] + -0.4245149972360448 # B[19, 4, 3, 7] + -0.149612637312833391 # B[20, 4, 4, 4] + -0.153415086019898006 # B[21, 4, 4, 6] + -0.14513624400298164 # B[22, 4, 4, 8] + -0.0460661393681677661 # B[23, 5, 0, 5] + -0.0512559726916635844 # B[24, 5, 1, 6] + -0.125285455697324882 # B[25, 5, 2, 5] + -0.297464016341802473 # B[26, 5, 2, 7] + -0.219930176940332595 # B[27, 5, 3, 6] + -0.195418601625407001 # B[28, 5, 3, 8] + -0.236454956825408069 # B[29, 5, 4, 5] + -0.247483318285177556 # B[30, 5, 4, 7] + 0.108404148378543994 # B[31, 5, 5, 6] + 0.102786344334006338 # B[32, 5, 5, 8] + -0.0174963987262215619 # B[33, 6, 0, 6] + -0.347663919737827065 # B[34, 6, 1, 7] + -0.308777238806140442 # B[35, 6, 2, 6] + -0.30366671620990171 # B[36, 6, 2, 8] + -0.190992135157848048 # B[37, 6, 3, 7] + -0.212717125362634818 # B[38, 6, 4, 6] + -0.127682310305149815 # B[39, 6, 4, 8] + 0.128955786755968027 # B[40, 6, 5, 7] + 0.108121871413745185 # B[41, 6, 6, 6] + 0.0951564970231452284 # B[42, 6, 6, 8] + -0.0443430969083889667 # B[43, 7, 0, 7] + 0.0394012265947801602 # B[44, 7, 1, 8] + 0.0238287662182333909 # B[45, 7, 2, 7] + -0.0703216614205220136 # B[46, 7, 3, 8] + -0.0229748587995626564 # B[47, 7, 4, 7] + 0.461615758896215367 # B[48, 7, 5, 8] + 0.032037855993324961 # B[49, 7, 6, 7] + 0.105399776101016598 # B[50, 7, 7, 8] + -0.0452778356788145764 # B[51, 8, 0, 8] + -0.0400452652333231421 # B[52, 8, 2, 8] + -0.152415456089667084 # B[53, 8, 4, 8] + 0.0303383368396002995 # B[54, 8, 6, 8] + 0.0660845112300222914 # B[55, 8, 8, 8] + 5.0022584003536763e-06 # B[55, [1, 0, 0, 0], [1, 0, 0, 0]] + 7.12434860521689133e-05 # B[56, [1, 0, 0, 0], [2, 1, 0, 1]] + 0.00410559459459784552 # B[57, [1, 0, 0, 0], [3, 1, 1, 2]] + -0.000152151102822628559 # B[58, [1, 0, 0, 0], [4, 2, 0, 2]] + -0.00104851962847402839 # B[59, [1, 0, 0, 0], [5, 2, 1, 3]] + 0.00174544590749468355 # B[60, [1, 0, 0, 0], [6, 2, 2, 2]] + -0.00039686396723943862 # B[61, [1, 0, 0, 0], [7, 2, 2, 4]] + 0.000344474173032960351 # B[62, [1, 0, 0, 0], [8, 3, 0, 3]] + 5.77832175303926235e-05 # B[63, [1, 0, 0, 0], [9, 3, 1, 4]] + 0.00124014860085090543 # B[64, [1, 0, 0, 0], [10, 3, 2, 3]] + 1.92520730655986946e-05 # B[65, [1, 0, 0, 0], [11, 3, 2, 5]] + -0.000659022869027497959 # B[66, [1, 0, 0, 0], [12, 3, 3, 4]] + -0.000296998157394604001 # B[67, [1, 0, 0, 0], [13, 3, 3, 6]] + 2.13348987737616014e-06 # B[68, [1, 0, 0, 0], [14, 4, 0, 4]] + -0.000377679899824956422 # B[69, [1, 0, 0, 0], [15, 4, 1, 5]] + 0.00045743496488695988 # B[70, [1, 0, 0, 0], [16, 4, 2, 4]] + -0.00047978616167941926 # B[71, [1, 0, 0, 0], [17, 4, 2, 6]] + -0.000346601408372410741 # B[72, [1, 0, 0, 0], [18, 4, 3, 5]] + -0.000216752459512900564 # B[73, [1, 0, 0, 0], [19, 4, 3, 7]] + -0.000153945954064437646 # B[74, [1, 0, 0, 0], [20, 4, 4, 4]] + 0.00029484781857681483 # B[75, [1, 0, 0, 0], [21, 4, 4, 6]] + 1.59236973873017051e-05 # B[76, [1, 0, 0, 0], [22, 4, 4, 8]] + -2.35544935613951623e-05 # B[77, [1, 0, 0, 0], [23, 5, 0, 5]] + 0.000492019807872501325 # B[78, [1, 0, 0, 0], [24, 5, 1, 6]] + 0.000376700986017126233 # B[79, [1, 0, 0, 0], [25, 5, 2, 5]] + -0.000185900021989794662 # B[80, [1, 0, 0, 0], [26, 5, 2, 7]] + 0.000219939447169378507 # B[81, [1, 0, 0, 0], [27, 5, 3, 6]] + -0.000192198129806066265 # B[82, [1, 0, 0, 0], [28, 5, 3, 8]] + 0.000175514531344928004 # B[83, [1, 0, 0, 0], [29, 5, 4, 5]] + 0.000261949015135925535 # B[84, [1, 0, 0, 0], [30, 5, 4, 7]] + 0.00021011408484750832 # B[85, [1, 0, 0, 0], [31, 5, 5, 6]] + -7.47807464450689352e-05 # B[86, [1, 0, 0, 0], [32, 5, 5, 8]] + -1.36809205491805752e-05 # B[87, [1, 0, 0, 0], [33, 6, 0, 6]] + 0.000493576806965066728 # B[88, [1, 0, 0, 0], [34, 6, 1, 7]] + 0.000216301405824667614 # B[89, [1, 0, 0, 0], [35, 6, 2, 6]] + -0.000364540437645548276 # B[90, [1, 0, 0, 0], [36, 6, 2, 8]] + -0.000251411532179113273 # B[91, [1, 0, 0, 0], [37, 6, 3, 7]] + 3.19331690196988927e-05 # B[92, [1, 0, 0, 0], [38, 6, 4, 6]] + -1.56092571080845843e-05 # B[93, [1, 0, 0, 0], [39, 6, 4, 8]] + 2.4859429830464963e-05 # B[94, [1, 0, 0, 0], [40, 6, 5, 7]] + -5.06306418207175257e-05 # B[95, [1, 0, 0, 0], [41, 6, 6, 6]] + -9.75742047871729079e-05 # B[96, [1, 0, 0, 0], [42, 6, 6, 8]] + -4.07774117821002591e-05 # B[97, [1, 0, 0, 0], [43, 7, 0, 7]] + 0.000169705539551909257 # B[98, [1, 0, 0, 0], [44, 7, 1, 8]] + 0.000261792097012429614 # B[99, [1, 0, 0, 0], [45, 7, 2, 7]] + 0.000235813389494382575 # B[100, [1, 0, 0, 0], [46, 7, 3, 8]] + 3.69194385055615637e-05 # B[101, [1, 0, 0, 0], [47, 7, 4, 7]] + 0.000101832840349036502 # B[102, [1, 0, 0, 0], [48, 7, 5, 8]] + 1.87768621704026417e-05 # B[103, [1, 0, 0, 0], [49, 7, 6, 7]] + 6.90123641682582889e-05 # B[104, [1, 0, 0, 0], [50, 7, 7, 8]] + 3.82281861928956967e-05 # B[105, [1, 0, 0, 0], [51, 8, 0, 8]] + 0.00044905358698343889 # B[106, [1, 0, 0, 0], [52, 8, 2, 8]] + 3.83170337754923374e-05 # B[107, [1, 0, 0, 0], [53, 8, 4, 8]] + -4.53472261485315942e-05 # B[108, [1, 0, 0, 0], [54, 8, 6, 8]] + -0.000105793544360549552 # B[109, [1, 0, 0, 0], [55, 8, 8, 8]] + -0.00542851209933992596 # B[110, [2, 1, 0, 1], [2, 1, 0, 1]] + -0.00800035055604917701 # B[111, [2, 1, 0, 1], [3, 1, 1, 2]] + 0.000279580761847972054 # B[112, [2, 1, 0, 1], [4, 2, 0, 2]] + -0.0132643544617690821 # B[113, [2, 1, 0, 1], [5, 2, 1, 3]] + -0.00300637860380324968 # B[114, [2, 1, 0, 1], [6, 2, 2, 2]] + 0.00343216933390476549 # B[115, [2, 1, 0, 1], [7, 2, 2, 4]] + 6.39026040622058672e-05 # B[116, [2, 1, 0, 1], [8, 3, 0, 3]] + -0.0124005148347727506 # B[117, [2, 1, 0, 1], [9, 3, 1, 4]] + -0.0036690465725984691 # B[118, [2, 1, 0, 1], [10, 3, 2, 3]] + -0.0066468850826254932 # B[119, [2, 1, 0, 1], [11, 3, 2, 5]] + -0.00518212543330048934 # B[120, [2, 1, 0, 1], [12, 3, 3, 4]] + -0.00269613907034030407 # B[121, [2, 1, 0, 1], [13, 3, 3, 6]] + -0.000330193583102013615 # B[122, [2, 1, 0, 1], [14, 4, 0, 4]] + -0.000429062486184235686 # B[123, [2, 1, 0, 1], [15, 4, 1, 5]] + -0.000991704717453613382 # B[124, [2, 1, 0, 1], [16, 4, 2, 4]] + 0.00152944521177345071 # B[125, [2, 1, 0, 1], [17, 4, 2, 6]] + -0.00660856033628089406 # B[126, [2, 1, 0, 1], [18, 4, 3, 5]] + 0.00146758746394204951 # B[127, [2, 1, 0, 1], [19, 4, 3, 7]] + -0.00161093753941019967 # B[128, [2, 1, 0, 1], [20, 4, 4, 4]] + -0.00101484284665418574 # B[129, [2, 1, 0, 1], [21, 4, 4, 6]] + 0.00150269420364470413 # B[130, [2, 1, 0, 1], [22, 4, 4, 8]] + -0.000251279508914979688 # B[131, [2, 1, 0, 1], [23, 5, 0, 5]] + 0.00427791921512100763 # B[132, [2, 1, 0, 1], [24, 5, 1, 6]] + -0.00312327633171666707 # B[133, [2, 1, 0, 1], [25, 5, 2, 5]] + 0.00145518956483171066 # B[134, [2, 1, 0, 1], [26, 5, 2, 7]] + -0.00296392629706135422 # B[135, [2, 1, 0, 1], [27, 5, 3, 6]] + 0.00106990236696331148 # B[136, [2, 1, 0, 1], [28, 5, 3, 8]] + 0.000140740776400729824 # B[137, [2, 1, 0, 1], [29, 5, 4, 5]] + -0.000704484148092703912 # B[138, [2, 1, 0, 1], [30, 5, 4, 7]] + 0.000555926138942124939 # B[139, [2, 1, 0, 1], [31, 5, 5, 6]] + 0.000749361142656781065 # B[140, [2, 1, 0, 1], [32, 5, 5, 8]] + -0.000275563231062828096 # B[141, [2, 1, 0, 1], [33, 6, 0, 6]] + 0.00404287546990938183 # B[142, [2, 1, 0, 1], [34, 6, 1, 7]] + -0.00329083016295819491 # B[143, [2, 1, 0, 1], [35, 6, 2, 6]] + 0.00374648670440783874 # B[144, [2, 1, 0, 1], [36, 6, 2, 8]] + -0.000931584323738718183 # B[145, [2, 1, 0, 1], [37, 6, 3, 7]] + 0.001545987588966576 # B[146, [2, 1, 0, 1], [38, 6, 4, 6]] + 0.000136630337825366203 # B[147, [2, 1, 0, 1], [39, 6, 4, 8]] + -0.000338191518470186761 # B[148, [2, 1, 0, 1], [40, 6, 5, 7]] + 0.000383732900037425575 # B[149, [2, 1, 0, 1], [41, 6, 6, 6]] + 0.000891911333988446714 # B[150, [2, 1, 0, 1], [42, 6, 6, 8]] + 0.000372325777048820861 # B[151, [2, 1, 0, 1], [43, 7, 0, 7]] + 0.00203975899324063559 # B[152, [2, 1, 0, 1], [44, 7, 1, 8]] + -0.00366168906366426058 # B[153, [2, 1, 0, 1], [45, 7, 2, 7]] + -0.00217927110231279971 # B[154, [2, 1, 0, 1], [46, 7, 3, 8]] + -0.000355180731966526532 # B[155, [2, 1, 0, 1], [47, 7, 4, 7]] + -0.00190295940654904624 # B[156, [2, 1, 0, 1], [48, 7, 5, 8]] + -0.00045640385432905474 # B[157, [2, 1, 0, 1], [49, 7, 6, 7]] + -0.00123273230096131864 # B[158, [2, 1, 0, 1], [50, 7, 7, 8]] + 2.61749541232737803e-06 # B[159, [2, 1, 0, 1], [51, 8, 0, 8]] + -0.00188736987570012403 # B[160, [2, 1, 0, 1], [52, 8, 2, 8]] + 0.000127235145614493401 # B[161, [2, 1, 0, 1], [53, 8, 4, 8]] + -0.000446185446234578786 # B[162, [2, 1, 0, 1], [54, 8, 6, 8]] + 3.06626149019382718e-05 # B[163, [2, 1, 0, 1], [55, 8, 8, 8]] + 0.00500803145405033512 # B[164, [3, 1, 1, 2], [3, 1, 1, 2]] + 0.0136537265129433767 # B[165, [3, 1, 1, 2], [4, 2, 0, 2]] + 0.00586793418015095231 # B[166, [3, 1, 1, 2], [5, 2, 1, 3]] + 0.0108897828563872673 # B[167, [3, 1, 1, 2], [6, 2, 2, 2]] + 0.000782326392446437181 # B[168, [3, 1, 1, 2], [7, 2, 2, 4]] + -0.00196905235294965193 # B[169, [3, 1, 1, 2], [8, 3, 0, 3]] + -0.00575620599927615263 # B[170, [3, 1, 1, 2], [9, 3, 1, 4]] + -0.0395084171352078836 # B[171, [3, 1, 1, 2], [10, 3, 2, 3]] + -0.0402914809330097226 # B[172, [3, 1, 1, 2], [11, 3, 2, 5]] + -0.031380925125560552 # B[173, [3, 1, 1, 2], [12, 3, 3, 4]] + 0.0074098991236085333 # B[174, [3, 1, 1, 2], [13, 3, 3, 6]] + -0.00144234945688183152 # B[175, [3, 1, 1, 2], [14, 4, 0, 4]] + -0.00715563010950572616 # B[176, [3, 1, 1, 2], [15, 4, 1, 5]] + -0.0068004389765142035 # B[177, [3, 1, 1, 2], [16, 4, 2, 4]] + -0.0397838555572563451 # B[178, [3, 1, 1, 2], [17, 4, 2, 6]] + 0.00335672059516798228 # B[179, [3, 1, 1, 2], [18, 4, 3, 5]] + 0.0148934683418572647 # B[180, [3, 1, 1, 2], [19, 4, 3, 7]] + -0.000967980016249102011 # B[181, [3, 1, 1, 2], [20, 4, 4, 4]] + 0.00772576295059950596 # B[182, [3, 1, 1, 2], [21, 4, 4, 6]] + -0.00450662666899595381 # B[183, [3, 1, 1, 2], [22, 4, 4, 8]] + -0.00395807515027411967 # B[184, [3, 1, 1, 2], [23, 5, 0, 5]] + 0.010414612350238486 # B[185, [3, 1, 1, 2], [24, 5, 1, 6]] + -0.00513372683983254804 # B[186, [3, 1, 1, 2], [25, 5, 2, 5]] + -0.0265398819124704963 # B[187, [3, 1, 1, 2], [26, 5, 2, 7]] + 0.00742434172938952544 # B[188, [3, 1, 1, 2], [27, 5, 3, 6]] + -0.00256386423704287481 # B[189, [3, 1, 1, 2], [28, 5, 3, 8]] + 0.00841179553194743718 # B[190, [3, 1, 1, 2], [29, 5, 4, 5]] + 0.00668617729586690451 # B[191, [3, 1, 1, 2], [30, 5, 4, 7]] + 0.000484464094046739568 # B[192, [3, 1, 1, 2], [31, 5, 5, 6]] + 0.00458460314168420216 # B[193, [3, 1, 1, 2], [32, 5, 5, 8]] + -0.00235318401641824212 # B[194, [3, 1, 1, 2], [33, 6, 0, 6]] + -0.000804392064641467762 # B[195, [3, 1, 1, 2], [34, 6, 1, 7]] + -0.000974349018272668323 # B[196, [3, 1, 1, 2], [35, 6, 2, 6]] + -0.0186467861443154748 # B[197, [3, 1, 1, 2], [36, 6, 2, 8]] + 0.0149394908128317495 # B[198, [3, 1, 1, 2], [37, 6, 3, 7]] + -0.001417773975968062 # B[199, [3, 1, 1, 2], [38, 6, 4, 6]] + 0.00708801668305296916 # B[200, [3, 1, 1, 2], [39, 6, 4, 8]] + 0.00422029817457212405 # B[201, [3, 1, 1, 2], [40, 6, 5, 7]] + 0.00110117813016081525 # B[202, [3, 1, 1, 2], [41, 6, 6, 6]] + -0.00187490884044745794 # B[203, [3, 1, 1, 2], [42, 6, 6, 8]] + -0.00530063898164105998 # B[204, [3, 1, 1, 2], [43, 7, 0, 7]] + 0.0156639815207892212 # B[205, [3, 1, 1, 2], [44, 7, 1, 8]] + 0.0118519420103458811 # B[206, [3, 1, 1, 2], [45, 7, 2, 7]] + 0.00375057568532275679 # B[207, [3, 1, 1, 2], [46, 7, 3, 8]] + 0.00757584350406629962 # B[208, [3, 1, 1, 2], [47, 7, 4, 7]] + 0.0106601777099339986 # B[209, [3, 1, 1, 2], [48, 7, 5, 8]] + -0.0041075690062942552 # B[210, [3, 1, 1, 2], [49, 7, 6, 7]] + 0.00248707997936048041 # B[211, [3, 1, 1, 2], [50, 7, 7, 8]] + -0.0025390217113529746 # B[212, [3, 1, 1, 2], [51, 8, 0, 8]] + 0.00498354453902482165 # B[213, [3, 1, 1, 2], [52, 8, 2, 8]] + 0.00383782774054214912 # B[214, [3, 1, 1, 2], [53, 8, 4, 8]] + 0.00318870204625110783 # B[215, [3, 1, 1, 2], [54, 8, 6, 8]] + -0.00078409267383599678 # B[216, [3, 1, 1, 2], [55, 8, 8, 8]] + 0.00411479420703600093 # B[217, [4, 2, 0, 2], [4, 2, 0, 2]] + -0.00352482696278418658 # B[218, [4, 2, 0, 2], [5, 2, 1, 3]] + 0.00293296373222708129 # B[219, [4, 2, 0, 2], [6, 2, 2, 2]] + -0.00169108240942662173 # B[220, [4, 2, 0, 2], [7, 2, 2, 4]] + -0.00166875839344953099 # B[221, [4, 2, 0, 2], [8, 3, 0, 3]] + -0.00303743189373234653 # B[222, [4, 2, 0, 2], [9, 3, 1, 4]] + -0.00360352002032471395 # B[223, [4, 2, 0, 2], [10, 3, 2, 3]] + -0.00844475258400314774 # B[224, [4, 2, 0, 2], [11, 3, 2, 5]] + -0.00267861760564082688 # B[225, [4, 2, 0, 2], [12, 3, 3, 4]] + 0.00249373694942188646 # B[226, [4, 2, 0, 2], [13, 3, 3, 6]] + 0.00129518789575956 # B[227, [4, 2, 0, 2], [14, 4, 0, 4]] + -0.000616706097657935626 # B[228, [4, 2, 0, 2], [15, 4, 1, 5]] + -0.00374793183827557257 # B[229, [4, 2, 0, 2], [16, 4, 2, 4]] + -0.00725453590077526286 # B[230, [4, 2, 0, 2], [17, 4, 2, 6]] + -0.00328165463874066426 # B[231, [4, 2, 0, 2], [18, 4, 3, 5]] + -0.00387910875571249565 # B[232, [4, 2, 0, 2], [19, 4, 3, 7]] + -0.000691443248665482221 # B[233, [4, 2, 0, 2], [20, 4, 4, 4]] + -0.00364575524119575139 # B[234, [4, 2, 0, 2], [21, 4, 4, 6]] + 0.000579213613942424974 # B[235, [4, 2, 0, 2], [22, 4, 4, 8]] + 0.000382530088889220486 # B[236, [4, 2, 0, 2], [23, 5, 0, 5]] + 0.000700082663528700608 # B[237, [4, 2, 0, 2], [24, 5, 1, 6]] + -0.00303645662419470708 # B[238, [4, 2, 0, 2], [25, 5, 2, 5]] + -0.00412449214914962191 # B[239, [4, 2, 0, 2], [26, 5, 2, 7]] + -0.000863747946010486305 # B[240, [4, 2, 0, 2], [27, 5, 3, 6]] + 0.000597171151136822748 # B[241, [4, 2, 0, 2], [28, 5, 3, 8]] + -0.00290482182317059953 # B[242, [4, 2, 0, 2], [29, 5, 4, 5]] + -0.00218615594313117554 # B[243, [4, 2, 0, 2], [30, 5, 4, 7]] + 0.00120270898159113111 # B[244, [4, 2, 0, 2], [31, 5, 5, 6]] + -0.000439562436330729364 # B[245, [4, 2, 0, 2], [32, 5, 5, 8]] + -0.000155002689849706443 # B[246, [4, 2, 0, 2], [33, 6, 0, 6]] + -0.00203784613220199399 # B[247, [4, 2, 0, 2], [34, 6, 1, 7]] + -0.00251933129878168221 # B[248, [4, 2, 0, 2], [35, 6, 2, 6]] + -0.00227857345941180406 # B[249, [4, 2, 0, 2], [36, 6, 2, 8]] + 0.00307391827986236085 # B[250, [4, 2, 0, 2], [37, 6, 3, 7]] + -0.000435707916552085118 # B[251, [4, 2, 0, 2], [38, 6, 4, 6]] + -0.00141960729594133419 # B[252, [4, 2, 0, 2], [39, 6, 4, 8]] + -0.000275734648504752638 # B[253, [4, 2, 0, 2], [40, 6, 5, 7]] + 0.000703286595409794617 # B[254, [4, 2, 0, 2], [41, 6, 6, 6]] + -5.55751922647368824e-05 # B[255, [4, 2, 0, 2], [42, 6, 6, 8]] + -0.000401816924228297345 # B[256, [4, 2, 0, 2], [43, 7, 0, 7]] + -0.000554714661495172429 # B[257, [4, 2, 0, 2], [44, 7, 1, 8]] + 0.00088244559527147267 # B[258, [4, 2, 0, 2], [45, 7, 2, 7]] + 0.000429487284537406104 # B[259, [4, 2, 0, 2], [46, 7, 3, 8]] + 0.000160720016534536374 # B[260, [4, 2, 0, 2], [47, 7, 4, 7]] + -0.000116046064898544729 # B[261, [4, 2, 0, 2], [48, 7, 5, 8]] + 0.00077812424584384446 # B[262, [4, 2, 0, 2], [49, 7, 6, 7]] + 0.0014223009786123353 # B[263, [4, 2, 0, 2], [50, 7, 7, 8]] + 5.45987148103492526e-05 # B[264, [4, 2, 0, 2], [51, 8, 0, 8]] + -0.00229888217343966316 # B[265, [4, 2, 0, 2], [52, 8, 2, 8]] + -0.00144376280980788169 # B[266, [4, 2, 0, 2], [53, 8, 4, 8]] + 0.000240138800657541986 # B[267, [4, 2, 0, 2], [54, 8, 6, 8]] + -4.09764373741731969e-05 # B[268, [4, 2, 0, 2], [55, 8, 8, 8]] + 0.0453826120189535706 # B[269, [5, 2, 1, 3], [5, 2, 1, 3]] + 0.00337080799390409615 # B[270, [5, 2, 1, 3], [6, 2, 2, 2]] + 0.0339316309546992961 # B[271, [5, 2, 1, 3], [7, 2, 2, 4]] + 0.00483677443671226039 # B[272, [5, 2, 1, 3], [8, 3, 0, 3]] + 0.00174954019608989774 # B[273, [5, 2, 1, 3], [9, 3, 1, 4]] + 0.00420306320210527603 # B[274, [5, 2, 1, 3], [10, 3, 2, 3]] + -0.0179939258962366969 # B[275, [5, 2, 1, 3], [11, 3, 2, 5]] + -0.01997198698308544 # B[276, [5, 2, 1, 3], [12, 3, 3, 4]] + -0.0136471344704570501 # B[277, [5, 2, 1, 3], [13, 3, 3, 6]] + -0.00203572867299816902 # B[278, [5, 2, 1, 3], [14, 4, 0, 4]] + 0.0113893698593142377 # B[279, [5, 2, 1, 3], [15, 4, 1, 5]] + -0.00283495847488346529 # B[280, [5, 2, 1, 3], [16, 4, 2, 4]] + -0.0209899506178404249 # B[281, [5, 2, 1, 3], [17, 4, 2, 6]] + 0.00307893999573658839 # B[282, [5, 2, 1, 3], [18, 4, 3, 5]] + 0.00625880909518397067 # B[283, [5, 2, 1, 3], [19, 4, 3, 7]] + 0.00109461945578659598 # B[284, [5, 2, 1, 3], [20, 4, 4, 4]] + 0.00213752786441095705 # B[285, [5, 2, 1, 3], [21, 4, 4, 6]] + -0.00379774849562602296 # B[286, [5, 2, 1, 3], [22, 4, 4, 8]] + -0.0013508169978871552 # B[287, [5, 2, 1, 3], [23, 5, 0, 5]] + 0.00921730935112183292 # B[288, [5, 2, 1, 3], [24, 5, 1, 6]] + -0.0029427132897584694 # B[289, [5, 2, 1, 3], [25, 5, 2, 5]] + 0.0013497580216050211 # B[290, [5, 2, 1, 3], [26, 5, 2, 7]] + -0.0130362734683665445 # B[291, [5, 2, 1, 3], [27, 5, 3, 6]] + 0.000858369129835153365 # B[292, [5, 2, 1, 3], [28, 5, 3, 8]] + 0.0129288669947052737 # B[293, [5, 2, 1, 3], [29, 5, 4, 5]] + -0.00373719468786774291 # B[294, [5, 2, 1, 3], [30, 5, 4, 7]] + -0.00885030928727506203 # B[295, [5, 2, 1, 3], [31, 5, 5, 6]] + 0.00285083482960970039 # B[296, [5, 2, 1, 3], [32, 5, 5, 8]] + 0.00351819863542377799 # B[297, [5, 2, 1, 3], [33, 6, 0, 6]] + -0.00783526064954031404 # B[298, [5, 2, 1, 3], [34, 6, 1, 7]] + -0.00257460837433342703 # B[299, [5, 2, 1, 3], [35, 6, 2, 6]] + -0.00421680657028429638 # B[300, [5, 2, 1, 3], [36, 6, 2, 8]] + -0.00918753516813325399 # B[301, [5, 2, 1, 3], [37, 6, 3, 7]] + -0.00316878171100497871 # B[302, [5, 2, 1, 3], [38, 6, 4, 6]] + 0.000939804682159322766 # B[303, [5, 2, 1, 3], [39, 6, 4, 8]] + -0.00618801787900946643 # B[304, [5, 2, 1, 3], [40, 6, 5, 7]] + -0.00623545765495540482 # B[305, [5, 2, 1, 3], [41, 6, 6, 6]] + 0.00519552954815065936 # B[306, [5, 2, 1, 3], [42, 6, 6, 8]] + 0.0042213652228506697 # B[307, [5, 2, 1, 3], [43, 7, 0, 7]] + 0.0113944611011103838 # B[308, [5, 2, 1, 3], [44, 7, 1, 8]] + -0.00104197865751114085 # B[309, [5, 2, 1, 3], [45, 7, 2, 7]] + -0.0087446191630695079 # B[310, [5, 2, 1, 3], [46, 7, 3, 8]] + -0.00196327596558909696 # B[311, [5, 2, 1, 3], [47, 7, 4, 7]] + -0.00447686867642808298 # B[312, [5, 2, 1, 3], [48, 7, 5, 8]] + -0.00474469665733750351 # B[313, [5, 2, 1, 3], [49, 7, 6, 7]] + -0.0059004868061462868 # B[314, [5, 2, 1, 3], [50, 7, 7, 8]] + 2.22874717926892923e-05 # B[315, [5, 2, 1, 3], [51, 8, 0, 8]] + -0.00154741089157206784 # B[316, [5, 2, 1, 3], [52, 8, 2, 8]] + 0.00417852330669051582 # B[317, [5, 2, 1, 3], [53, 8, 4, 8]] + 0.00134060860138395356 # B[318, [5, 2, 1, 3], [54, 8, 6, 8]] + -4.29219459423162489e-05 # B[319, [5, 2, 1, 3], [55, 8, 8, 8]] + 0.000319124100064731785 # B[320, [6, 2, 2, 2], [6, 2, 2, 2]] + -0.00839561599135440172 # B[321, [6, 2, 2, 2], [7, 2, 2, 4]] + -0.00326195850510992494 # B[322, [6, 2, 2, 2], [8, 3, 0, 3]] + 0.0194547426296311776 # B[323, [6, 2, 2, 2], [9, 3, 1, 4]] + -0.020516093722439413 # B[324, [6, 2, 2, 2], [10, 3, 2, 3]] + -0.00901624473884381043 # B[325, [6, 2, 2, 2], [11, 3, 2, 5]] + 0.0129026669830971837 # B[326, [6, 2, 2, 2], [12, 3, 3, 4]] + 0.00463182910296210636 # B[327, [6, 2, 2, 2], [13, 3, 3, 6]] + -0.00261498466108737743 # B[328, [6, 2, 2, 2], [14, 4, 0, 4]] + 0.0215819608660451426 # B[329, [6, 2, 2, 2], [15, 4, 1, 5]] + 0.000767688854520869957 # B[330, [6, 2, 2, 2], [16, 4, 2, 4]] + -0.00666111439578009716 # B[331, [6, 2, 2, 2], [17, 4, 2, 6]] + 0.0112705725443772303 # B[332, [6, 2, 2, 2], [18, 4, 3, 5]] + 0.00228839615631495127 # B[333, [6, 2, 2, 2], [19, 4, 3, 7]] + 0.00124148748415313414 # B[334, [6, 2, 2, 2], [20, 4, 4, 4]] + 0.00353391028977510834 # B[335, [6, 2, 2, 2], [21, 4, 4, 6]] + -0.00310464569903003834 # B[336, [6, 2, 2, 2], [22, 4, 4, 8]] + -0.001770681064288395 # B[337, [6, 2, 2, 2], [23, 5, 0, 5]] + 0.000554784469018851215 # B[338, [6, 2, 2, 2], [24, 5, 1, 6]] + -0.000102008183116791319 # B[339, [6, 2, 2, 2], [25, 5, 2, 5]] + -0.00128750706249572758 # B[340, [6, 2, 2, 2], [26, 5, 2, 7]] + 0.0046490656013451568 # B[341, [6, 2, 2, 2], [27, 5, 3, 6]] + 0.0034506831073765681 # B[342, [6, 2, 2, 2], [28, 5, 3, 8]] + 0.00501652811902741046 # B[343, [6, 2, 2, 2], [29, 5, 4, 5]] + -1.88389891915279224e-05 # B[344, [6, 2, 2, 2], [30, 5, 4, 7]] + -0.00246586719805504942 # B[345, [6, 2, 2, 2], [31, 5, 5, 6]] + -0.00339629261051872756 # B[346, [6, 2, 2, 2], [32, 5, 5, 8]] + -1.22729584505151552e-05 # B[347, [6, 2, 2, 2], [33, 6, 0, 6]] + -0.0055646406349652653 # B[348, [6, 2, 2, 2], [34, 6, 1, 7]] + 0.00216606634250279383 # B[349, [6, 2, 2, 2], [35, 6, 2, 6]] + -0.000140725603696151627 # B[350, [6, 2, 2, 2], [36, 6, 2, 8]] + -0.01190136261487338 # B[351, [6, 2, 2, 2], [37, 6, 3, 7]] + -0.000996588010308921109 # B[352, [6, 2, 2, 2], [38, 6, 4, 6]] + -0.0040124728576705895 # B[353, [6, 2, 2, 2], [39, 6, 4, 8]] + 0.000422679331586792552 # B[354, [6, 2, 2, 2], [40, 6, 5, 7]] + 0.000548939662545001959 # B[355, [6, 2, 2, 2], [41, 6, 6, 6]] + 0.00256895119228900404 # B[356, [6, 2, 2, 2], [42, 6, 6, 8]] + -0.000615139781019174688 # B[357, [6, 2, 2, 2], [43, 7, 0, 7]] + -0.00404941774617198578 # B[358, [6, 2, 2, 2], [44, 7, 1, 8]] + 0.00466754848324051064 # B[359, [6, 2, 2, 2], [45, 7, 2, 7]] + 0.00150461796185176488 # B[360, [6, 2, 2, 2], [46, 7, 3, 8]] + 0.0037489054114537468 # B[361, [6, 2, 2, 2], [47, 7, 4, 7]] + 0.00285804436398595782 # B[362, [6, 2, 2, 2], [48, 7, 5, 8]] + -0.00287521518361254919 # B[363, [6, 2, 2, 2], [49, 7, 6, 7]] + 0.000969520968104660755 # B[364, [6, 2, 2, 2], [50, 7, 7, 8]] + -0.000716125857042927043 # B[365, [6, 2, 2, 2], [51, 8, 0, 8]] + -0.00157385185114507437 # B[366, [6, 2, 2, 2], [52, 8, 2, 8]] + 0.002689243736875038 # B[367, [6, 2, 2, 2], [53, 8, 4, 8]] + -0.000661038690452418623 # B[368, [6, 2, 2, 2], [54, 8, 6, 8]] + 0.00157186481624649321 # B[369, [6, 2, 2, 2], [55, 8, 8, 8]] + -0.0134601349926017494 # B[370, [7, 2, 2, 4], [7, 2, 2, 4]] + -0.000918558149715113011 # B[371, [7, 2, 2, 4], [8, 3, 0, 3]] + -0.00377418701166061087 # B[372, [7, 2, 2, 4], [9, 3, 1, 4]] + 0.0148168734486278948 # B[373, [7, 2, 2, 4], [10, 3, 2, 3]] + -0.00535328606426562371 # B[374, [7, 2, 2, 4], [11, 3, 2, 5]] + 0.00804271469408427385 # B[375, [7, 2, 2, 4], [12, 3, 3, 4]] + 0.00136329663181449737 # B[376, [7, 2, 2, 4], [13, 3, 3, 6]] + 0.000218608555253111195 # B[377, [7, 2, 2, 4], [14, 4, 0, 4]] + 0.00767165886258287799 # B[378, [7, 2, 2, 4], [15, 4, 1, 5]] + -0.0022580429604385833 # B[379, [7, 2, 2, 4], [16, 4, 2, 4]] + -0.0050991924246220309 # B[380, [7, 2, 2, 4], [17, 4, 2, 6]] + -0.00308509180848093572 # B[381, [7, 2, 2, 4], [18, 4, 3, 5]] + -0.000900097231895549623 # B[382, [7, 2, 2, 4], [19, 4, 3, 7]] + -0.0063557020842957869 # B[383, [7, 2, 2, 4], [20, 4, 4, 4]] + -0.000409569358807882096 # B[384, [7, 2, 2, 4], [21, 4, 4, 6]] + 0.00254581400782049119 # B[385, [7, 2, 2, 4], [22, 4, 4, 8]] + 0.000657951401298526029 # B[386, [7, 2, 2, 4], [23, 5, 0, 5]] + -0.00940269729352927013 # B[387, [7, 2, 2, 4], [24, 5, 1, 6]] + 0.00333566383730494239 # B[388, [7, 2, 2, 4], [25, 5, 2, 5]] + 0.00896493308698088215 # B[389, [7, 2, 2, 4], [26, 5, 2, 7]] + 0.00132812590751918685 # B[390, [7, 2, 2, 4], [27, 5, 3, 6]] + -0.00127282140780485189 # B[391, [7, 2, 2, 4], [28, 5, 3, 8]] + -0.00435358176352772068 # B[392, [7, 2, 2, 4], [29, 5, 4, 5]] + -0.00226566527245459885 # B[393, [7, 2, 2, 4], [30, 5, 4, 7]] + 0.00326597657188156627 # B[394, [7, 2, 2, 4], [31, 5, 5, 6]] + -0.00247993076825692074 # B[395, [7, 2, 2, 4], [32, 5, 5, 8]] + -0.00138012806761597748 # B[396, [7, 2, 2, 4], [33, 6, 0, 6]] + -0.00296559266178312566 # B[397, [7, 2, 2, 4], [34, 6, 1, 7]] + -0.00345134318647404535 # B[398, [7, 2, 2, 4], [35, 6, 2, 6]] + 0.00604122282441024554 # B[399, [7, 2, 2, 4], [36, 6, 2, 8]] + -0.00602530276328681197 # B[400, [7, 2, 2, 4], [37, 6, 3, 7]] + 0.00113230868581531974 # B[401, [7, 2, 2, 4], [38, 6, 4, 6]] + 0.00132069580529702024 # B[402, [7, 2, 2, 4], [39, 6, 4, 8]] + -0.00355708848499901743 # B[403, [7, 2, 2, 4], [40, 6, 5, 7]] + 0.00103954578232134899 # B[404, [7, 2, 2, 4], [41, 6, 6, 6]] + 0.00138660655783935638 # B[405, [7, 2, 2, 4], [42, 6, 6, 8]] + 0.00122312383058832339 # B[406, [7, 2, 2, 4], [43, 7, 0, 7]] + 0.00122422070912251465 # B[407, [7, 2, 2, 4], [44, 7, 1, 8]] + -0.00497379521097694472 # B[408, [7, 2, 2, 4], [45, 7, 2, 7]] + -0.00811974704425355749 # B[409, [7, 2, 2, 4], [46, 7, 3, 8]] + 0.00114732010903773659 # B[410, [7, 2, 2, 4], [47, 7, 4, 7]] + -0.00569074628354063975 # B[411, [7, 2, 2, 4], [48, 7, 5, 8]] + 0.00235624642317577588 # B[412, [7, 2, 2, 4], [49, 7, 6, 7]] + 7.98437182146268919e-05 # B[413, [7, 2, 2, 4], [50, 7, 7, 8]] + 0.00113891921332402897 # B[414, [7, 2, 2, 4], [51, 8, 0, 8]] + -0.00492469555442132112 # B[415, [7, 2, 2, 4], [52, 8, 2, 8]] + 0.000792980352556455804 # B[416, [7, 2, 2, 4], [53, 8, 4, 8]] + 0.00153854887229367375 # B[417, [7, 2, 2, 4], [54, 8, 6, 8]] + -0.000881221748445243022 # B[418, [7, 2, 2, 4], [55, 8, 8, 8]] + -0.00136471788502227735 # B[419, [8, 3, 0, 3], [8, 3, 0, 3]] + 0.00246251727263488776 # B[420, [8, 3, 0, 3], [9, 3, 1, 4]] + 0.000996613519267240677 # B[421, [8, 3, 0, 3], [10, 3, 2, 3]] + -0.00207976146372090831 # B[422, [8, 3, 0, 3], [11, 3, 2, 5]] + -9.97509064182486305e-05 # B[423, [8, 3, 0, 3], [12, 3, 3, 4]] + 0.000656935135924852087 # B[424, [8, 3, 0, 3], [13, 3, 3, 6]] + -0.000492474229225159377 # B[425, [8, 3, 0, 3], [14, 4, 0, 4]] + 0.0032189163248994351 # B[426, [8, 3, 0, 3], [15, 4, 1, 5]] + -0.00115555104609991501 # B[427, [8, 3, 0, 3], [16, 4, 2, 4]] + -0.000101151026370576574 # B[428, [8, 3, 0, 3], [17, 4, 2, 6]] + 0.00020301152740384229 # B[429, [8, 3, 0, 3], [18, 4, 3, 5]] + -0.000285445107860462371 # B[430, [8, 3, 0, 3], [19, 4, 3, 7]] + 0.000462665925556146607 # B[431, [8, 3, 0, 3], [20, 4, 4, 4]] + -2.75652763320703015e-05 # B[432, [8, 3, 0, 3], [21, 4, 4, 6]] + -0.000358778647317398169 # B[433, [8, 3, 0, 3], [22, 4, 4, 8]] + -0.000397176131748222527 # B[434, [8, 3, 0, 3], [23, 5, 0, 5]] + -0.00026950177456114624 # B[435, [8, 3, 0, 3], [24, 5, 1, 6]] + 0.00119424632084062527 # B[436, [8, 3, 0, 3], [25, 5, 2, 5]] + 0.000922347152199163439 # B[437, [8, 3, 0, 3], [26, 5, 2, 7]] + -0.000340838509282952173 # B[438, [8, 3, 0, 3], [27, 5, 3, 6]] + 0.00128847730890532808 # B[439, [8, 3, 0, 3], [28, 5, 3, 8]] + -0.00044582191494569115 # B[440, [8, 3, 0, 3], [29, 5, 4, 5]] + -0.00114898350718379422 # B[441, [8, 3, 0, 3], [30, 5, 4, 7]] + -0.000530499767100067743 # B[442, [8, 3, 0, 3], [31, 5, 5, 6]] + 1.68864176486992895e-05 # B[443, [8, 3, 0, 3], [32, 5, 5, 8]] + -0.000312292146951373417 # B[444, [8, 3, 0, 3], [33, 6, 0, 6]] + -0.00186273440079770883 # B[445, [8, 3, 0, 3], [34, 6, 1, 7]] + -0.000475625961442131123 # B[446, [8, 3, 0, 3], [35, 6, 2, 6]] + 0.000505090975521763769 # B[447, [8, 3, 0, 3], [36, 6, 2, 8]] + 0.000128630083375533277 # B[448, [8, 3, 0, 3], [37, 6, 3, 7]] + -0.000431369283499544176 # B[449, [8, 3, 0, 3], [38, 6, 4, 6]] + 0.000461881443708941908 # B[450, [8, 3, 0, 3], [39, 6, 4, 8]] + 0.000867550860200114182 # B[451, [8, 3, 0, 3], [40, 6, 5, 7]] + 0.000179604539903628624 # B[452, [8, 3, 0, 3], [41, 6, 6, 6]] + -0.000405383988192370426 # B[453, [8, 3, 0, 3], [42, 6, 6, 8]] + -0.000305572243426546764 # B[454, [8, 3, 0, 3], [43, 7, 0, 7]] + -0.0010766931736053021 # B[455, [8, 3, 0, 3], [44, 7, 1, 8]] + 0.000701859051866787764 # B[456, [8, 3, 0, 3], [45, 7, 2, 7]] + -1.5413662061584954e-05 # B[457, [8, 3, 0, 3], [46, 7, 3, 8]] + 0.000428834666348756888 # B[458, [8, 3, 0, 3], [47, 7, 4, 7]] + 0.000468098667731533385 # B[459, [8, 3, 0, 3], [48, 7, 5, 8]] + 0.000158467988956009775 # B[460, [8, 3, 0, 3], [49, 7, 6, 7]] + 2.77948419442784408e-05 # B[461, [8, 3, 0, 3], [50, 7, 7, 8]] + -0.000282655955044820717 # B[462, [8, 3, 0, 3], [51, 8, 0, 8]] + 0.000100300940760145348 # B[463, [8, 3, 0, 3], [52, 8, 2, 8]] + 0.000314947671131902973 # B[464, [8, 3, 0, 3], [53, 8, 4, 8]] + 0.000144842823919437078 # B[465, [8, 3, 0, 3], [54, 8, 6, 8]] + 7.00050428864840146e-05 # B[466, [8, 3, 0, 3], [55, 8, 8, 8]] + 0.0118411448561217512 # B[467, [9, 3, 1, 4], [9, 3, 1, 4]] + 0.0158809314732707603 # B[468, [9, 3, 1, 4], [10, 3, 2, 3]] + -0.00690506493475962109 # B[469, [9, 3, 1, 4], [11, 3, 2, 5]] + 0.0085626937099196887 # B[470, [9, 3, 1, 4], [12, 3, 3, 4]] + -0.00387686964925252654 # B[471, [9, 3, 1, 4], [13, 3, 3, 6]] + 0.00015029200549142481 # B[472, [9, 3, 1, 4], [14, 4, 0, 4]] + -0.000142532963490632015 # B[473, [9, 3, 1, 4], [15, 4, 1, 5]] + 0.00921427022949583042 # B[474, [9, 3, 1, 4], [16, 4, 2, 4]] + -0.0112717231196791407 # B[475, [9, 3, 1, 4], [17, 4, 2, 6]] + -0.0122014182952103704 # B[476, [9, 3, 1, 4], [18, 4, 3, 5]] + -0.0111571557686284996 # B[477, [9, 3, 1, 4], [19, 4, 3, 7]] + -0.00276180055211498916 # B[478, [9, 3, 1, 4], [20, 4, 4, 4]] + -0.00444456405006457382 # B[479, [9, 3, 1, 4], [21, 4, 4, 6]] + -0.00248162623330630983 # B[480, [9, 3, 1, 4], [22, 4, 4, 8]] + 0.000238830840202226575 # B[481, [9, 3, 1, 4], [23, 5, 0, 5]] + 0.0106883008114137777 # B[482, [9, 3, 1, 4], [24, 5, 1, 6]] + -0.00176293319638371826 # B[483, [9, 3, 1, 4], [25, 5, 2, 5]] + -0.000706186990249144109 # B[484, [9, 3, 1, 4], [26, 5, 2, 7]] + -0.000957413082652629373 # B[485, [9, 3, 1, 4], [27, 5, 3, 6]] + -0.00485998335666546887 # B[486, [9, 3, 1, 4], [28, 5, 3, 8]] + -0.000739967956913101287 # B[487, [9, 3, 1, 4], [29, 5, 4, 5]] + -0.00656002591947351353 # B[488, [9, 3, 1, 4], [30, 5, 4, 7]] + -0.00191607250770065712 # B[489, [9, 3, 1, 4], [31, 5, 5, 6]] + -0.000375150046930213714 # B[490, [9, 3, 1, 4], [32, 5, 5, 8]] + 0.000379540253919751804 # B[491, [9, 3, 1, 4], [33, 6, 0, 6]] + 0.0103809997405371179 # B[492, [9, 3, 1, 4], [34, 6, 1, 7]] + -0.00167937900508645203 # B[493, [9, 3, 1, 4], [35, 6, 2, 6]] + -0.000942453027264282192 # B[494, [9, 3, 1, 4], [36, 6, 2, 8]] + -0.00358794660355351257 # B[495, [9, 3, 1, 4], [37, 6, 3, 7]] + 0.00367542903060237222 # B[496, [9, 3, 1, 4], [38, 6, 4, 6]] + -0.00605874518215254298 # B[497, [9, 3, 1, 4], [39, 6, 4, 8]] + -0.0053364107721741022 # B[498, [9, 3, 1, 4], [40, 6, 5, 7]] + -0.00220303686176452889 # B[499, [9, 3, 1, 4], [41, 6, 6, 6]] + 0.000240224733534942676 # B[500, [9, 3, 1, 4], [42, 6, 6, 8]] + 0.00118204722287629585 # B[501, [9, 3, 1, 4], [43, 7, 0, 7]] + 0.00391606544218769514 # B[502, [9, 3, 1, 4], [44, 7, 1, 8]] + -0.00190557542057654024 # B[503, [9, 3, 1, 4], [45, 7, 2, 7]] + -0.0010749256928406746 # B[504, [9, 3, 1, 4], [46, 7, 3, 8]] + 6.24186835188134462e-05 # B[505, [9, 3, 1, 4], [47, 7, 4, 7]] + -0.00250872188348977114 # B[506, [9, 3, 1, 4], [48, 7, 5, 8]] + -0.00164710314956706405 # B[507, [9, 3, 1, 4], [49, 7, 6, 7]] + -0.0029144992153610676 # B[508, [9, 3, 1, 4], [50, 7, 7, 8]] + 0.000712015267242259442 # B[509, [9, 3, 1, 4], [51, 8, 0, 8]] + -0.00179539873092394715 # B[510, [9, 3, 1, 4], [52, 8, 2, 8]] + 0.00203000698298521493 # B[511, [9, 3, 1, 4], [53, 8, 4, 8]] + -0.00103477100047664442 # B[512, [9, 3, 1, 4], [54, 8, 6, 8]] + -0.000727628763147338854 # B[513, [9, 3, 1, 4], [55, 8, 8, 8]] + 0.0163451466486591972 # B[514, [10, 3, 2, 3], [10, 3, 2, 3]] + -0.00145259448176927441 # B[515, [10, 3, 2, 3], [11, 3, 2, 5]] + -0.00808947571520425568 # B[516, [10, 3, 2, 3], [12, 3, 3, 4]] + -0.00693599935022420205 # B[517, [10, 3, 2, 3], [13, 3, 3, 6]] + -0.00419683318703741731 # B[518, [10, 3, 2, 3], [14, 4, 0, 4]] + 0.00927666204585274323 # B[519, [10, 3, 2, 3], [15, 4, 1, 5]] + -0.0138962541759877663 # B[520, [10, 3, 2, 3], [16, 4, 2, 4]] + 0.0115061801390417759 # B[521, [10, 3, 2, 3], [17, 4, 2, 6]] + 0.0118559077356181798 # B[522, [10, 3, 2, 3], [18, 4, 3, 5]] + 0.00193270595871023604 # B[523, [10, 3, 2, 3], [19, 4, 3, 7]] + 0.00156708209719190472 # B[524, [10, 3, 2, 3], [20, 4, 4, 4]] + 0.0030286948486105119 # B[525, [10, 3, 2, 3], [21, 4, 4, 6]] + -6.03736466163237034e-05 # B[526, [10, 3, 2, 3], [22, 4, 4, 8]] + -0.00147218391304548835 # B[527, [10, 3, 2, 3], [23, 5, 0, 5]] + 0.000931966019926808685 # B[528, [10, 3, 2, 3], [24, 5, 1, 6]] + 0.0153667638164197012 # B[529, [10, 3, 2, 3], [25, 5, 2, 5]] + -0.0023105273691670326 # B[530, [10, 3, 2, 3], [26, 5, 2, 7]] + 0.0018873267014898696 # B[531, [10, 3, 2, 3], [27, 5, 3, 6]] + -0.00221592978134090707 # B[532, [10, 3, 2, 3], [28, 5, 3, 8]] + 0.00175823978838723916 # B[533, [10, 3, 2, 3], [29, 5, 4, 5]] + 0.00134986143361107494 # B[534, [10, 3, 2, 3], [30, 5, 4, 7]] + -0.00280444330034939227 # B[535, [10, 3, 2, 3], [31, 5, 5, 6]] + -0.000446159575940244073 # B[536, [10, 3, 2, 3], [32, 5, 5, 8]] + 0.000126573802730074736 # B[537, [10, 3, 2, 3], [33, 6, 0, 6]] + 7.95217271451070795e-05 # B[538, [10, 3, 2, 3], [34, 6, 1, 7]] + -0.000615992203402992468 # B[539, [10, 3, 2, 3], [35, 6, 2, 6]] + -0.0106304231235931409 # B[540, [10, 3, 2, 3], [36, 6, 2, 8]] + -0.00513102234934090934 # B[541, [10, 3, 2, 3], [37, 6, 3, 7]] + 0.00086364506858761271 # B[542, [10, 3, 2, 3], [38, 6, 4, 6]] + -0.00427816275089007263 # B[543, [10, 3, 2, 3], [39, 6, 4, 8]] + -0.00709876751806875171 # B[544, [10, 3, 2, 3], [40, 6, 5, 7]] + -0.00107679083671011894 # B[545, [10, 3, 2, 3], [41, 6, 6, 6]] + -0.0014022801302571164 # B[546, [10, 3, 2, 3], [42, 6, 6, 8]] + 0.00032001340322446864 # B[547, [10, 3, 2, 3], [43, 7, 0, 7]] + 0.0099494513037338677 # B[548, [10, 3, 2, 3], [44, 7, 1, 8]] + 0.00657164457459321564 # B[549, [10, 3, 2, 3], [45, 7, 2, 7]] + -0.00193909086513409032 # B[550, [10, 3, 2, 3], [46, 7, 3, 8]] + -0.000661327911070458407 # B[551, [10, 3, 2, 3], [47, 7, 4, 7]] + -0.00236609840279333045 # B[552, [10, 3, 2, 3], [48, 7, 5, 8]] + 0.000323126961361372422 # B[553, [10, 3, 2, 3], [49, 7, 6, 7]] + 0.00156411007472663857 # B[554, [10, 3, 2, 3], [50, 7, 7, 8]] + -0.000413410696562647312 # B[555, [10, 3, 2, 3], [51, 8, 0, 8]] + 0.00151556635054790959 # B[556, [10, 3, 2, 3], [52, 8, 2, 8]] + 0.0032252808357782943 # B[557, [10, 3, 2, 3], [53, 8, 4, 8]] + 0.00431814581620697767 # B[558, [10, 3, 2, 3], [54, 8, 6, 8]] + 0.000198535493268348594 # B[559, [10, 3, 2, 3], [55, 8, 8, 8]] + 0.0156540432654675432 # B[560, [11, 3, 2, 5], [11, 3, 2, 5]] + 0.00979845476873780416 # B[561, [11, 3, 2, 5], [12, 3, 3, 4]] + 0.00873265456764509701 # B[562, [11, 3, 2, 5], [13, 3, 3, 6]] + -0.00355250352643814854 # B[563, [11, 3, 2, 5], [14, 4, 0, 4]] + 0.0197388975583387243 # B[564, [11, 3, 2, 5], [15, 4, 1, 5]] + 0.0158965586216084157 # B[565, [11, 3, 2, 5], [16, 4, 2, 4]] + 0.0126440348146513917 # B[566, [11, 3, 2, 5], [17, 4, 2, 6]] + 0.00588822462217037865 # B[567, [11, 3, 2, 5], [18, 4, 3, 5]] + 0.00465829809814364074 # B[568, [11, 3, 2, 5], [19, 4, 3, 7]] + 0.00460100330976275125 # B[569, [11, 3, 2, 5], [20, 4, 4, 4]] + 0.00507979510261629894 # B[570, [11, 3, 2, 5], [21, 4, 4, 6]] + -0.000978147842247499566 # B[571, [11, 3, 2, 5], [22, 4, 4, 8]] + 0.000175648698607325238 # B[572, [11, 3, 2, 5], [23, 5, 0, 5]] + 0.00701365729786882983 # B[573, [11, 3, 2, 5], [24, 5, 1, 6]] + 0.0124121871279893672 # B[574, [11, 3, 2, 5], [25, 5, 2, 5]] + 0.0133268604743271169 # B[575, [11, 3, 2, 5], [26, 5, 2, 7]] + -0.00306906262974302943 # B[576, [11, 3, 2, 5], [27, 5, 3, 6]] + 0.00411586711144847073 # B[577, [11, 3, 2, 5], [28, 5, 3, 8]] + -0.00483702208096517539 # B[578, [11, 3, 2, 5], [29, 5, 4, 5]] + 0.000232830853394127776 # B[579, [11, 3, 2, 5], [30, 5, 4, 7]] + -0.00500644765401524715 # B[580, [11, 3, 2, 5], [31, 5, 5, 6]] + -0.000732991087538808345 # B[581, [11, 3, 2, 5], [32, 5, 5, 8]] + 0.0028290195015726223 # B[582, [11, 3, 2, 5], [33, 6, 0, 6]] + 0.000660043236562475252 # B[583, [11, 3, 2, 5], [34, 6, 1, 7]] + 0.00858014820620479901 # B[584, [11, 3, 2, 5], [35, 6, 2, 6]] + 0.00979420830127970127 # B[585, [11, 3, 2, 5], [36, 6, 2, 8]] + -0.00276929529868128257 # B[586, [11, 3, 2, 5], [37, 6, 3, 7]] + -0.00462592209123751513 # B[587, [11, 3, 2, 5], [38, 6, 4, 6]] + 0.000957159367659247626 # B[588, [11, 3, 2, 5], [39, 6, 4, 8]] + -0.00289923459154850169 # B[589, [11, 3, 2, 5], [40, 6, 5, 7]] + -0.00605668820795574915 # B[590, [11, 3, 2, 5], [41, 6, 6, 6]] + -0.00571070540762017888 # B[591, [11, 3, 2, 5], [42, 6, 6, 8]] + 0.00247733408975375075 # B[592, [11, 3, 2, 5], [43, 7, 0, 7]] + 0.00452000165177812024 # B[593, [11, 3, 2, 5], [44, 7, 1, 8]] + 0.00267833963693382693 # B[594, [11, 3, 2, 5], [45, 7, 2, 7]] + -0.00558917145621175976 # B[595, [11, 3, 2, 5], [46, 7, 3, 8]] + -0.00228097422335522999 # B[596, [11, 3, 2, 5], [47, 7, 4, 7]] + -0.00366604043706369575 # B[597, [11, 3, 2, 5], [48, 7, 5, 8]] + -0.00340088281218112534 # B[598, [11, 3, 2, 5], [49, 7, 6, 7]] + -0.00355022426643257852 # B[599, [11, 3, 2, 5], [50, 7, 7, 8]] + 0.00124080314205340242 # B[600, [11, 3, 2, 5], [51, 8, 0, 8]] + 0.00287261267197001097 # B[601, [11, 3, 2, 5], [52, 8, 2, 8]] + 0.000744815191487350516 # B[602, [11, 3, 2, 5], [53, 8, 4, 8]] + -0.000112288931147085103 # B[603, [11, 3, 2, 5], [54, 8, 6, 8]] + -0.000128712309023326903 # B[604, [11, 3, 2, 5], [55, 8, 8, 8]] + -0.00238666366477884723 # B[605, [12, 3, 3, 4], [12, 3, 3, 4]] + 0.000248696286071804773 # B[606, [12, 3, 3, 4], [13, 3, 3, 6]] + -0.000479775127143412111 # B[607, [12, 3, 3, 4], [14, 4, 0, 4]] + 0.00175952173341571141 # B[608, [12, 3, 3, 4], [15, 4, 1, 5]] + 0.000197368498788095745 # B[609, [12, 3, 3, 4], [16, 4, 2, 4]] + 0.00726401135600521306 # B[610, [12, 3, 3, 4], [17, 4, 2, 6]] + -0.00118096336629036625 # B[611, [12, 3, 3, 4], [18, 4, 3, 5]] + 0.00702896514440041337 # B[612, [12, 3, 3, 4], [19, 4, 3, 7]] + -0.00236026619914155369 # B[613, [12, 3, 3, 4], [20, 4, 4, 4]] + -0.00341152672753146672 # B[614, [12, 3, 3, 4], [21, 4, 4, 6]] + 0.00348613231611557411 # B[615, [12, 3, 3, 4], [22, 4, 4, 8]] + 0.00244457707345889508 # B[616, [12, 3, 3, 4], [23, 5, 0, 5]] + -0.000822727235681003019 # B[617, [12, 3, 3, 4], [24, 5, 1, 6]] + -0.00248763810919495551 # B[618, [12, 3, 3, 4], [25, 5, 2, 5]] + 0.00796413115978647848 # B[619, [12, 3, 3, 4], [26, 5, 2, 7]] + -0.00179317048488774472 # B[620, [12, 3, 3, 4], [27, 5, 3, 6]] + 0.00454384820995466787 # B[621, [12, 3, 3, 4], [28, 5, 3, 8]] + -0.00425365149530766012 # B[622, [12, 3, 3, 4], [29, 5, 4, 5]] + -0.000569152560526600682 # B[623, [12, 3, 3, 4], [30, 5, 4, 7]] + -0.00506501220127485163 # B[624, [12, 3, 3, 4], [31, 5, 5, 6]] + -0.00142637122228714969 # B[625, [12, 3, 3, 4], [32, 5, 5, 8]] + 0.00190739239349446005 # B[626, [12, 3, 3, 4], [33, 6, 0, 6]] + 0.00215429853006474104 # B[627, [12, 3, 3, 4], [34, 6, 1, 7]] + 0.00512135793044871807 # B[628, [12, 3, 3, 4], [35, 6, 2, 6]] + 0.00479344551680733165 # B[629, [12, 3, 3, 4], [36, 6, 2, 8]] + -0.000813733007282164966 # B[630, [12, 3, 3, 4], [37, 6, 3, 7]] + -0.00162747725274282884 # B[631, [12, 3, 3, 4], [38, 6, 4, 6]] + -0.00440004969635155417 # B[632, [12, 3, 3, 4], [39, 6, 4, 8]] + -0.00939941153506137356 # B[633, [12, 3, 3, 4], [40, 6, 5, 7]] + -0.00314893787689287524 # B[634, [12, 3, 3, 4], [41, 6, 6, 6]] + -0.00125776748984993136 # B[635, [12, 3, 3, 4], [42, 6, 6, 8]] + 0.00129112127843685615 # B[636, [12, 3, 3, 4], [43, 7, 0, 7]] + 0.00564724346615860621 # B[637, [12, 3, 3, 4], [44, 7, 1, 8]] + -0.0018460571659526942 # B[638, [12, 3, 3, 4], [45, 7, 2, 7]] + -0.000300525523225368685 # B[639, [12, 3, 3, 4], [46, 7, 3, 8]] + -0.00277157581435865698 # B[640, [12, 3, 3, 4], [47, 7, 4, 7]] + -0.00975210406554173105 # B[641, [12, 3, 3, 4], [48, 7, 5, 8]] + -0.00233845213984289896 # B[642, [12, 3, 3, 4], [49, 7, 6, 7]] + -0.00138723239922117561 # B[643, [12, 3, 3, 4], [50, 7, 7, 8]] + 0.000864866797073243071 # B[644, [12, 3, 3, 4], [51, 8, 0, 8]] + -0.000747563068773752452 # B[645, [12, 3, 3, 4], [52, 8, 2, 8]] + 0.000965474694725087373 # B[646, [12, 3, 3, 4], [53, 8, 4, 8]] + -0.00140612646390263218 # B[647, [12, 3, 3, 4], [54, 8, 6, 8]] + -0.00149643617894318522 # B[648, [12, 3, 3, 4], [55, 8, 8, 8]] + 0.00149153681612450295 # B[649, [13, 3, 3, 6], [13, 3, 3, 6]] + -0.000954556711257832646 # B[650, [13, 3, 3, 6], [14, 4, 0, 4]] + 0.00120983585813713799 # B[651, [13, 3, 3, 6], [15, 4, 1, 5]] + 0.00300317867570911888 # B[652, [13, 3, 3, 6], [16, 4, 2, 4]] + 0.00236443796053106663 # B[653, [13, 3, 3, 6], [17, 4, 2, 6]] + 0.00415524139600132597 # B[654, [13, 3, 3, 6], [18, 4, 3, 5]] + -0.000123573851697839077 # B[655, [13, 3, 3, 6], [19, 4, 3, 7]] + 0.000470359195248265527 # B[656, [13, 3, 3, 6], [20, 4, 4, 4]] + 0.000635927641249957321 # B[657, [13, 3, 3, 6], [21, 4, 4, 6]] + 0.000747673754939660613 # B[658, [13, 3, 3, 6], [22, 4, 4, 8]] + 0.00074188846631736971 # B[659, [13, 3, 3, 6], [23, 5, 0, 5]] + 0.00463957097737913854 # B[660, [13, 3, 3, 6], [24, 5, 1, 6]] + -0.00271105182543343939 # B[661, [13, 3, 3, 6], [25, 5, 2, 5]] + 6.90411348413036419e-06 # B[662, [13, 3, 3, 6], [26, 5, 2, 7]] + 0.000911354980270381865 # B[663, [13, 3, 3, 6], [27, 5, 3, 6]] + -0.0028545746938972022 # B[664, [13, 3, 3, 6], [28, 5, 3, 8]] + -1.76062828863947363e-05 # B[665, [13, 3, 3, 6], [29, 5, 4, 5]] + -1.51206672011107435e-05 # B[666, [13, 3, 3, 6], [30, 5, 4, 7]] + -0.000798318879555708766 # B[667, [13, 3, 3, 6], [31, 5, 5, 6]] + -0.0015978026047660434 # B[668, [13, 3, 3, 6], [32, 5, 5, 8]] + 0.00034244751324807865 # B[669, [13, 3, 3, 6], [33, 6, 0, 6]] + 0.00338996797689858353 # B[670, [13, 3, 3, 6], [34, 6, 1, 7]] + 0.000289281476490772793 # B[671, [13, 3, 3, 6], [35, 6, 2, 6]] + -0.000559772151149058594 # B[672, [13, 3, 3, 6], [36, 6, 2, 8]] + -0.000650724286175463629 # B[673, [13, 3, 3, 6], [37, 6, 3, 7]] + 0.00148244897292096334 # B[674, [13, 3, 3, 6], [38, 6, 4, 6]] + 0.000183404639618602733 # B[675, [13, 3, 3, 6], [39, 6, 4, 8]] + -0.00185779692530890772 # B[676, [13, 3, 3, 6], [40, 6, 5, 7]] + -0.000708322215432564961 # B[677, [13, 3, 3, 6], [41, 6, 6, 6]] + -0.000491831969715535167 # B[678, [13, 3, 3, 6], [42, 6, 6, 8]] + 0.000833818016036214082 # B[679, [13, 3, 3, 6], [43, 7, 0, 7]] + -0.00256922900730601443 # B[680, [13, 3, 3, 6], [44, 7, 1, 8]] + -0.00112433206588518839 # B[681, [13, 3, 3, 6], [45, 7, 2, 7]] + 6.43716101358243753e-05 # B[682, [13, 3, 3, 6], [46, 7, 3, 8]] + -0.00126304972485289518 # B[683, [13, 3, 3, 6], [47, 7, 4, 7]] + -0.00210937996313975001 # B[684, [13, 3, 3, 6], [48, 7, 5, 8]] + -0.00126022676030809744 # B[685, [13, 3, 3, 6], [49, 7, 6, 7]] + -0.000555039709846411045 # B[686, [13, 3, 3, 6], [50, 7, 7, 8]] + 0.000790824100586496465 # B[687, [13, 3, 3, 6], [51, 8, 0, 8]] + -0.000844206812343649936 # B[688, [13, 3, 3, 6], [52, 8, 2, 8]] + 0.000195900027714517901 # B[689, [13, 3, 3, 6], [53, 8, 4, 8]] + -0.000823274415849936658 # B[690, [13, 3, 3, 6], [54, 8, 6, 8]] + -0.000330474595809105917 # B[691, [13, 3, 3, 6], [55, 8, 8, 8]] + -3.04835503155357485e-05 # B[692, [14, 4, 0, 4], [14, 4, 0, 4]] + -0.000825475145007361147 # B[693, [14, 4, 0, 4], [15, 4, 1, 5]] + -0.00244887111925138484 # B[694, [14, 4, 0, 4], [16, 4, 2, 4]] + -0.00122050568127611732 # B[695, [14, 4, 0, 4], [17, 4, 2, 6]] + -0.00226655265247485693 # B[696, [14, 4, 0, 4], [18, 4, 3, 5]] + -0.000767631950688907327 # B[697, [14, 4, 0, 4], [19, 4, 3, 7]] + -0.000547575812124723171 # B[698, [14, 4, 0, 4], [20, 4, 4, 4]] + -0.00121783548699544442 # B[699, [14, 4, 0, 4], [21, 4, 4, 6]] + 6.68947985199286332e-05 # B[700, [14, 4, 0, 4], [22, 4, 4, 8]] + -9.6030771921717939e-05 # B[701, [14, 4, 0, 4], [23, 5, 0, 5]] + -0.000544408900336967871 # B[702, [14, 4, 0, 4], [24, 5, 1, 6]] + -0.00139019051437529293 # B[703, [14, 4, 0, 4], [25, 5, 2, 5]] + -0.000281919324988699413 # B[704, [14, 4, 0, 4], [26, 5, 2, 7]] + -0.00125721115437776171 # B[705, [14, 4, 0, 4], [27, 5, 3, 6]] + -0.000282797770993010317 # B[706, [14, 4, 0, 4], [28, 5, 3, 8]] + -0.00139320549871079641 # B[707, [14, 4, 0, 4], [29, 5, 4, 5]] + -0.000628813518841068401 # B[708, [14, 4, 0, 4], [30, 5, 4, 7]] + -0.000607292163329276047 # B[709, [14, 4, 0, 4], [31, 5, 5, 6]] + 0.000242807689929189566 # B[710, [14, 4, 0, 4], [32, 5, 5, 8]] + -0.000100536983796830487 # B[711, [14, 4, 0, 4], [33, 6, 0, 6]] + 0.00111838401982674706 # B[712, [14, 4, 0, 4], [34, 6, 1, 7]] + -0.0012014113032742873 # B[713, [14, 4, 0, 4], [35, 6, 2, 6]] + -1.32311363260466386e-05 # B[714, [14, 4, 0, 4], [36, 6, 2, 8]] + 0.000753146180409180327 # B[715, [14, 4, 0, 4], [37, 6, 3, 7]] + -0.000270332227596856156 # B[716, [14, 4, 0, 4], [38, 6, 4, 6]] + -0.000293750660311472775 # B[717, [14, 4, 0, 4], [39, 6, 4, 8]] + 6.52480591955099942e-05 # B[718, [14, 4, 0, 4], [40, 6, 5, 7]] + -4.70588815947581285e-05 # B[719, [14, 4, 0, 4], [41, 6, 6, 6]] + 0.000244731448919628669 # B[720, [14, 4, 0, 4], [42, 6, 6, 8]] + -9.3149326930830334e-05 # B[721, [14, 4, 0, 4], [43, 7, 0, 7]] + 0.000731947904616598796 # B[722, [14, 4, 0, 4], [44, 7, 1, 8]] + -0.00107463735030771668 # B[723, [14, 4, 0, 4], [45, 7, 2, 7]] + 0.000139861959076940934 # B[724, [14, 4, 0, 4], [46, 7, 3, 8]] + 0.000101877532936889281 # B[725, [14, 4, 0, 4], [47, 7, 4, 7]] + -0.000196888502333611437 # B[726, [14, 4, 0, 4], [48, 7, 5, 8]] + 6.12030178565765859e-05 # B[727, [14, 4, 0, 4], [49, 7, 6, 7]] + -0.000223986590912481076 # B[728, [14, 4, 0, 4], [50, 7, 7, 8]] + -6.56819431667232667e-05 # B[729, [14, 4, 0, 4], [51, 8, 0, 8]] + -0.000970632773483491584 # B[730, [14, 4, 0, 4], [52, 8, 2, 8]] + -0.000182189294658170395 # B[731, [14, 4, 0, 4], [53, 8, 4, 8]] + -3.45215935849477185e-05 # B[732, [14, 4, 0, 4], [54, 8, 6, 8]] + 6.19739521221795986e-05 # B[733, [14, 4, 0, 4], [55, 8, 8, 8]] + 0.000242753902013392972 # B[734, [15, 4, 1, 5], [15, 4, 1, 5]] + 0.00729727211034517358 # B[735, [15, 4, 1, 5], [16, 4, 2, 4]] + -0.0024545495000649507 # B[736, [15, 4, 1, 5], [17, 4, 2, 6]] + -0.00265559618939786597 # B[737, [15, 4, 1, 5], [18, 4, 3, 5]] + 0.00473045463551583639 # B[738, [15, 4, 1, 5], [19, 4, 3, 7]] + -0.000140785797905494323 # B[739, [15, 4, 1, 5], [20, 4, 4, 4]] + 0.00179841698526277474 # B[740, [15, 4, 1, 5], [21, 4, 4, 6]] + 0.00129773534161339073 # B[741, [15, 4, 1, 5], [22, 4, 4, 8]] + 0.00172905697138841467 # B[742, [15, 4, 1, 5], [23, 5, 0, 5]] + -0.00408304027381215483 # B[743, [15, 4, 1, 5], [24, 5, 1, 6]] + -0.00205043992851699228 # B[744, [15, 4, 1, 5], [25, 5, 2, 5]] + 0.000756591579123801249 # B[745, [15, 4, 1, 5], [26, 5, 2, 7]] + -0.00421238291006168549 # B[746, [15, 4, 1, 5], [27, 5, 3, 6]] + -0.00196911327032830725 # B[747, [15, 4, 1, 5], [28, 5, 3, 8]] + 0.000729488918071528446 # B[748, [15, 4, 1, 5], [29, 5, 4, 5]] + -0.00177843604064341788 # B[749, [15, 4, 1, 5], [30, 5, 4, 7]] + -0.00130376966915328159 # B[750, [15, 4, 1, 5], [31, 5, 5, 6]] + -0.00198695656227435707 # B[751, [15, 4, 1, 5], [32, 5, 5, 8]] + 0.000608914142072050635 # B[752, [15, 4, 1, 5], [33, 6, 0, 6]] + -0.00109469344681823767 # B[753, [15, 4, 1, 5], [34, 6, 1, 7]] + -0.00451953523789613495 # B[754, [15, 4, 1, 5], [35, 6, 2, 6]] + 0.00279449892877900279 # B[755, [15, 4, 1, 5], [36, 6, 2, 8]] + -0.00435984465194903283 # B[756, [15, 4, 1, 5], [37, 6, 3, 7]] + 0.00275969130186590542 # B[757, [15, 4, 1, 5], [38, 6, 4, 6]] + 0.00154021904971430755 # B[758, [15, 4, 1, 5], [39, 6, 4, 8]] + -0.00146163413862035289 # B[759, [15, 4, 1, 5], [40, 6, 5, 7]] + -0.000333421796264918996 # B[760, [15, 4, 1, 5], [41, 6, 6, 6]] + -0.00139958818201657261 # B[761, [15, 4, 1, 5], [42, 6, 6, 8]] + 0.000750502250600797172 # B[762, [15, 4, 1, 5], [43, 7, 0, 7]] + 0.00476052216726493421 # B[763, [15, 4, 1, 5], [44, 7, 1, 8]] + -0.00155321215408361565 # B[764, [15, 4, 1, 5], [45, 7, 2, 7]] + -0.00351167160511536933 # B[765, [15, 4, 1, 5], [46, 7, 3, 8]] + 0.00268907735535169144 # B[766, [15, 4, 1, 5], [47, 7, 4, 7]] + -0.00296394481906553462 # B[767, [15, 4, 1, 5], [48, 7, 5, 8]] + -0.00115945739998543369 # B[768, [15, 4, 1, 5], [49, 7, 6, 7]] + -0.0011498694923236445 # B[769, [15, 4, 1, 5], [50, 7, 7, 8]] + 0.000691127444573572114 # B[770, [15, 4, 1, 5], [51, 8, 0, 8]] + 0.00149148321917135169 # B[771, [15, 4, 1, 5], [52, 8, 2, 8]] + 0.00226549729687968923 # B[772, [15, 4, 1, 5], [53, 8, 4, 8]] + -0.00127955154911817224 # B[773, [15, 4, 1, 5], [54, 8, 6, 8]] + -0.0006680598304007173 # B[774, [15, 4, 1, 5], [55, 8, 8, 8]] + 0.00773393138113156846 # B[775, [16, 4, 2, 4], [16, 4, 2, 4]] + 0.00481567776445743917 # B[776, [16, 4, 2, 4], [17, 4, 2, 6]] + 0.00646602315581837339 # B[777, [16, 4, 2, 4], [18, 4, 3, 5]] + 0.00401373256364237051 # B[778, [16, 4, 2, 4], [19, 4, 3, 7]] + -0.000224833927917125753 # B[779, [16, 4, 2, 4], [20, 4, 4, 4]] + 0.0030532060451974926 # B[780, [16, 4, 2, 4], [21, 4, 4, 6]] + -0.000126777823410560014 # B[781, [16, 4, 2, 4], [22, 4, 4, 8]] + 0.00109512376860463863 # B[782, [16, 4, 2, 4], [23, 5, 0, 5]] + 0.0014906978453806609 # B[783, [16, 4, 2, 4], [24, 5, 1, 6]] + 0.00278609484035531206 # B[784, [16, 4, 2, 4], [25, 5, 2, 5]] + 0.00720611209490516682 # B[785, [16, 4, 2, 4], [26, 5, 2, 7]] + 0.00230880055683394415 # B[786, [16, 4, 2, 4], [27, 5, 3, 6]] + 0.00492114792718315389 # B[787, [16, 4, 2, 4], [28, 5, 3, 8]] + 0.00102265649585190407 # B[788, [16, 4, 2, 4], [29, 5, 4, 5]] + -0.000348239317084679881 # B[789, [16, 4, 2, 4], [30, 5, 4, 7]] + -0.00394431438420023671 # B[790, [16, 4, 2, 4], [31, 5, 5, 6]] + -0.00362914461095884553 # B[791, [16, 4, 2, 4], [32, 5, 5, 8]] + 0.000172019923347470349 # B[792, [16, 4, 2, 4], [33, 6, 0, 6]] + -0.000316455135754767445 # B[793, [16, 4, 2, 4], [34, 6, 1, 7]] + 0.00107098215861984453 # B[794, [16, 4, 2, 4], [35, 6, 2, 6]] + -0.000907131668137324478 # B[795, [16, 4, 2, 4], [36, 6, 2, 8]] + -0.000367695081353409058 # B[796, [16, 4, 2, 4], [37, 6, 3, 7]] + 0.00181370580350630889 # B[797, [16, 4, 2, 4], [38, 6, 4, 6]] + 0.000820930060826967692 # B[798, [16, 4, 2, 4], [39, 6, 4, 8]] + -0.00466238776474962348 # B[799, [16, 4, 2, 4], [40, 6, 5, 7]] + -0.0024305728850557008 # B[800, [16, 4, 2, 4], [41, 6, 6, 6]] + -0.00165013696151081928 # B[801, [16, 4, 2, 4], [42, 6, 6, 8]] + 0.000760058338755045804 # B[802, [16, 4, 2, 4], [43, 7, 0, 7]] + -0.00203289214112462729 # B[803, [16, 4, 2, 4], [44, 7, 1, 8]] + -0.00103057221789182719 # B[804, [16, 4, 2, 4], [45, 7, 2, 7]] + 0.00188720556649034019 # B[805, [16, 4, 2, 4], [46, 7, 3, 8]] + -0.000348979964538542048 # B[806, [16, 4, 2, 4], [47, 7, 4, 7]] + -0.00595514004121479486 # B[807, [16, 4, 2, 4], [48, 7, 5, 8]] + -0.00122307692783891336 # B[808, [16, 4, 2, 4], [49, 7, 6, 7]] + -0.00161626528708522232 # B[809, [16, 4, 2, 4], [50, 7, 7, 8]] + 0.000683658453003721522 # B[810, [16, 4, 2, 4], [51, 8, 0, 8]] + 0.000169503544911074264 # B[811, [16, 4, 2, 4], [52, 8, 2, 8]] + 0.00163132840171071117 # B[812, [16, 4, 2, 4], [53, 8, 4, 8]] + -0.000633742642666999118 # B[813, [16, 4, 2, 4], [54, 8, 6, 8]] + -0.000861029784191980584 # B[814, [16, 4, 2, 4], [55, 8, 8, 8]] + 0.0101724317893582689 # B[815, [17, 4, 2, 6], [17, 4, 2, 6]] + 0.00963074903115390332 # B[816, [17, 4, 2, 6], [18, 4, 3, 5]] + 0.00792776812488414986 # B[817, [17, 4, 2, 6], [19, 4, 3, 7]] + 0.00129789596639547263 # B[818, [17, 4, 2, 6], [20, 4, 4, 4]] + 0.0025280260724625768 # B[819, [17, 4, 2, 6], [21, 4, 4, 6]] + -0.00130604081814601758 # B[820, [17, 4, 2, 6], [22, 4, 4, 8]] + 0.00061656245411057832 # B[821, [17, 4, 2, 6], [23, 5, 0, 5]] + 0.00256026791937838134 # B[822, [17, 4, 2, 6], [24, 5, 1, 6]] + 0.00833728674660196879 # B[823, [17, 4, 2, 6], [25, 5, 2, 5]] + 0.00819332084025456604 # B[824, [17, 4, 2, 6], [26, 5, 2, 7]] + 0.00199258058679730159 # B[825, [17, 4, 2, 6], [27, 5, 3, 6]] + -0.00235687406293394464 # B[826, [17, 4, 2, 6], [28, 5, 3, 8]] + 0.00172306590551023903 # B[827, [17, 4, 2, 6], [29, 5, 4, 5]] + 0.00273320921325834404 # B[828, [17, 4, 2, 6], [30, 5, 4, 7]] + 0.00124490813870011289 # B[829, [17, 4, 2, 6], [31, 5, 5, 6]] + -0.00239829497882970916 # B[830, [17, 4, 2, 6], [32, 5, 5, 8]] + 0.000403489881901454572 # B[831, [17, 4, 2, 6], [33, 6, 0, 6]] + 0.0115977289566935714 # B[832, [17, 4, 2, 6], [34, 6, 1, 7]] + 0.00631330244272786285 # B[833, [17, 4, 2, 6], [35, 6, 2, 6]] + 0.00745951676374975552 # B[834, [17, 4, 2, 6], [36, 6, 2, 8]] + 0.00129555462014044158 # B[835, [17, 4, 2, 6], [37, 6, 3, 7]] + 0.0031708889242759988 # B[836, [17, 4, 2, 6], [38, 6, 4, 6]] + 0.00314059501950873093 # B[837, [17, 4, 2, 6], [39, 6, 4, 8]] + -0.00157311519106628078 # B[838, [17, 4, 2, 6], [40, 6, 5, 7]] + -0.000535633835711041804 # B[839, [17, 4, 2, 6], [41, 6, 6, 6]] + -0.00106218347026977491 # B[840, [17, 4, 2, 6], [42, 6, 6, 8]] + 0.00171130648037900839 # B[841, [17, 4, 2, 6], [43, 7, 0, 7]] + 0.00318381348777509654 # B[842, [17, 4, 2, 6], [44, 7, 1, 8]] + 0.00121186975917000981 # B[843, [17, 4, 2, 6], [45, 7, 2, 7]] + -0.00505226933268299559 # B[844, [17, 4, 2, 6], [46, 7, 3, 8]] + 0.000505489038324865442 # B[845, [17, 4, 2, 6], [47, 7, 4, 7]] + -0.00260650572816220009 # B[846, [17, 4, 2, 6], [48, 7, 5, 8]] + -0.00458388666826989831 # B[847, [17, 4, 2, 6], [49, 7, 6, 7]] + -0.0030323259618317824 # B[848, [17, 4, 2, 6], [50, 7, 7, 8]] + 0.000919810997489799165 # B[849, [17, 4, 2, 6], [51, 8, 0, 8]] + 0.00153843620323466154 # B[850, [17, 4, 2, 6], [52, 8, 2, 8]] + 0.00177452104337356975 # B[851, [17, 4, 2, 6], [53, 8, 4, 8]] + -0.00133363365246129796 # B[852, [17, 4, 2, 6], [54, 8, 6, 8]] + 0.000497168699576265929 # B[853, [17, 4, 2, 6], [55, 8, 8, 8]] + 0.00916493227652732945 # B[854, [18, 4, 3, 5], [18, 4, 3, 5]] + 0.00662893191875722591 # B[855, [18, 4, 3, 5], [19, 4, 3, 7]] + 0.00102473567933248147 # B[856, [18, 4, 3, 5], [20, 4, 4, 4]] + 0.000661293664462594619 # B[857, [18, 4, 3, 5], [21, 4, 4, 6]] + 0.00302383517430961438 # B[858, [18, 4, 3, 5], [22, 4, 4, 8]] + 0.00182134236384280147 # B[859, [18, 4, 3, 5], [23, 5, 0, 5]] + 0.00481003527044247467 # B[860, [18, 4, 3, 5], [24, 5, 1, 6]] + 0.00472221587821478311 # B[861, [18, 4, 3, 5], [25, 5, 2, 5]] + 0.00204855894682247092 # B[862, [18, 4, 3, 5], [26, 5, 2, 7]] + 0.00108437129165206425 # B[863, [18, 4, 3, 5], [27, 5, 3, 6]] + 0.000188071259560827417 # B[864, [18, 4, 3, 5], [28, 5, 3, 8]] + 0.000402244806083140727 # B[865, [18, 4, 3, 5], [29, 5, 4, 5]] + 0.00350511561101824257 # B[866, [18, 4, 3, 5], [30, 5, 4, 7]] + -0.00196731170271619883 # B[867, [18, 4, 3, 5], [31, 5, 5, 6]] + -0.000854471064769226317 # B[868, [18, 4, 3, 5], [32, 5, 5, 8]] + 0.00163753590726098495 # B[869, [18, 4, 3, 5], [33, 6, 0, 6]] + 0.00678767470498069323 # B[870, [18, 4, 3, 5], [34, 6, 1, 7]] + 0.00671898362129526739 # B[871, [18, 4, 3, 5], [35, 6, 2, 6]] + 0.00504150139406711259 # B[872, [18, 4, 3, 5], [36, 6, 2, 8]] + -0.00150058947564556469 # B[873, [18, 4, 3, 5], [37, 6, 3, 7]] + 0.00126561580055304518 # B[874, [18, 4, 3, 5], [38, 6, 4, 6]] + -0.000556565865268397481 # B[875, [18, 4, 3, 5], [39, 6, 4, 8]] + -0.00527488386402661519 # B[876, [18, 4, 3, 5], [40, 6, 5, 7]] + -0.00214157468754809163 # B[877, [18, 4, 3, 5], [41, 6, 6, 6]] + -0.0020431148178264337 # B[878, [18, 4, 3, 5], [42, 6, 6, 8]] + 0.00142704628054338232 # B[879, [18, 4, 3, 5], [43, 7, 0, 7]] + 0.00368882624306161085 # B[880, [18, 4, 3, 5], [44, 7, 1, 8]] + -0.000742447358153045661 # B[881, [18, 4, 3, 5], [45, 7, 2, 7]] + -0.00158678830901623838 # B[882, [18, 4, 3, 5], [46, 7, 3, 8]] + -0.00107876302160130055 # B[883, [18, 4, 3, 5], [47, 7, 4, 7]] + -0.00701537311445033646 # B[884, [18, 4, 3, 5], [48, 7, 5, 8]] + -0.00184801443295596127 # B[885, [18, 4, 3, 5], [49, 7, 6, 7]] + -0.00127678697871524667 # B[886, [18, 4, 3, 5], [50, 7, 7, 8]] + 0.00105641109188138113 # B[887, [18, 4, 3, 5], [51, 8, 0, 8]] + 0.000718098622203026428 # B[888, [18, 4, 3, 5], [52, 8, 2, 8]] + 0.00219486004289275692 # B[889, [18, 4, 3, 5], [53, 8, 4, 8]] + -0.00158748993130468905 # B[890, [18, 4, 3, 5], [54, 8, 6, 8]] + -0.00105128398142791644 # B[891, [18, 4, 3, 5], [55, 8, 8, 8]] + -0.00705876763301777586 # B[892, [19, 4, 3, 7], [19, 4, 3, 7]] + 0.00377186011578763136 # B[893, [19, 4, 3, 7], [20, 4, 4, 4]] + 0.00351225097737749986 # B[894, [19, 4, 3, 7], [21, 4, 4, 6]] + -0.00323798036048509805 # B[895, [19, 4, 3, 7], [22, 4, 4, 8]] + 0.00126225430824061444 # B[896, [19, 4, 3, 7], [23, 5, 0, 5]] + -0.00132900767543010258 # B[897, [19, 4, 3, 7], [24, 5, 1, 6]] + 0.000212743875668733318 # B[898, [19, 4, 3, 7], [25, 5, 2, 5]] + -8.93559293989563963e-05 # B[899, [19, 4, 3, 7], [26, 5, 2, 7]] + 0.00401415269432878544 # B[900, [19, 4, 3, 7], [27, 5, 3, 6]] + -0.00422923196125859352 # B[901, [19, 4, 3, 7], [28, 5, 3, 8]] + 0.00252733635050122335 # B[902, [19, 4, 3, 7], [29, 5, 4, 5]] + -0.00020969110581340808 # B[903, [19, 4, 3, 7], [30, 5, 4, 7]] + -0.000969147769818896193 # B[904, [19, 4, 3, 7], [31, 5, 5, 6]] + -0.00249817386761041864 # B[905, [19, 4, 3, 7], [32, 5, 5, 8]] + 7.71120512828363247e-05 # B[906, [19, 4, 3, 7], [33, 6, 0, 6]] + 0.00560302176075209817 # B[907, [19, 4, 3, 7], [34, 6, 1, 7]] + 0.00342833731167378752 # B[908, [19, 4, 3, 7], [35, 6, 2, 6]] + 0.00116548365936076578 # B[909, [19, 4, 3, 7], [36, 6, 2, 8]] + 0.00499590856190199745 # B[910, [19, 4, 3, 7], [37, 6, 3, 7]] + 0.00391644837067879614 # B[911, [19, 4, 3, 7], [38, 6, 4, 6]] + 0.00116606811408420229 # B[912, [19, 4, 3, 7], [39, 6, 4, 8]] + -0.000563820914290556058 # B[913, [19, 4, 3, 7], [40, 6, 5, 7]] + -0.000251464925992161276 # B[914, [19, 4, 3, 7], [41, 6, 6, 6]] + -0.000718753250305587815 # B[915, [19, 4, 3, 7], [42, 6, 6, 8]] + 0.000453024387943248494 # B[916, [19, 4, 3, 7], [43, 7, 0, 7]] + -0.00146422451962339994 # B[917, [19, 4, 3, 7], [44, 7, 1, 8]] + 0.00271974781140060795 # B[918, [19, 4, 3, 7], [45, 7, 2, 7]] + 0.00151707017829591159 # B[919, [19, 4, 3, 7], [46, 7, 3, 8]] + 0.00202377896423465691 # B[920, [19, 4, 3, 7], [47, 7, 4, 7]] + -0.00131185948123999779 # B[921, [19, 4, 3, 7], [48, 7, 5, 8]] + 0.000239464941185672797 # B[922, [19, 4, 3, 7], [49, 7, 6, 7]] + -0.000667571478871501964 # B[923, [19, 4, 3, 7], [50, 7, 7, 8]] + 0.000666789360176615192 # B[924, [19, 4, 3, 7], [51, 8, 0, 8]] + 0.00179543252151156355 # B[925, [19, 4, 3, 7], [52, 8, 2, 8]] + 0.000954396542852647967 # B[926, [19, 4, 3, 7], [53, 8, 4, 8]] + 0.000593331439814590023 # B[927, [19, 4, 3, 7], [54, 8, 6, 8]] + -0.000292670120459602445 # B[928, [19, 4, 3, 7], [55, 8, 8, 8]] + -0.000303353861178074294 # B[929, [20, 4, 4, 4], [20, 4, 4, 4]] + -6.41585335468541906e-05 # B[930, [20, 4, 4, 4], [21, 4, 4, 6]] + 0.00145464895340288725 # B[931, [20, 4, 4, 4], [22, 4, 4, 8]] + 0.000557677559397141802 # B[932, [20, 4, 4, 4], [23, 5, 0, 5]] + 0.00214733001664968188 # B[933, [20, 4, 4, 4], [24, 5, 1, 6]] + 0.000196804226194771757 # B[934, [20, 4, 4, 4], [25, 5, 2, 5]] + 0.00169621771662652795 # B[935, [20, 4, 4, 4], [26, 5, 2, 7]] + -0.00126951106424718924 # B[936, [20, 4, 4, 4], [27, 5, 3, 6]] + 0.00156201190059711802 # B[937, [20, 4, 4, 4], [28, 5, 3, 8]] + -0.000188505112089858498 # B[938, [20, 4, 4, 4], [29, 5, 4, 5]] + 0.00101485096974841295 # B[939, [20, 4, 4, 4], [30, 5, 4, 7]] + -0.000254023094278113288 # B[940, [20, 4, 4, 4], [31, 5, 5, 6]] + -0.000332430225508446864 # B[941, [20, 4, 4, 4], [32, 5, 5, 8]] + 0.000393172799404761797 # B[942, [20, 4, 4, 4], [33, 6, 0, 6]] + -0.000945851456653874594 # B[943, [20, 4, 4, 4], [34, 6, 1, 7]] + 0.000937118523093692299 # B[944, [20, 4, 4, 4], [35, 6, 2, 6]] + 0.00108463610451345858 # B[945, [20, 4, 4, 4], [36, 6, 2, 8]] + -0.00167878968186336089 # B[946, [20, 4, 4, 4], [37, 6, 3, 7]] + 0.000109649976457827647 # B[947, [20, 4, 4, 4], [38, 6, 4, 6]] + 0.000205908523746248934 # B[948, [20, 4, 4, 4], [39, 6, 4, 8]] + -0.000952641271225448949 # B[949, [20, 4, 4, 4], [40, 6, 5, 7]] + -0.000386842165161269298 # B[950, [20, 4, 4, 4], [41, 6, 6, 6]] + -0.000662992329463731739 # B[951, [20, 4, 4, 4], [42, 6, 6, 8]] + 0.000368522676488847178 # B[952, [20, 4, 4, 4], [43, 7, 0, 7]] + -0.000181924614212486402 # B[953, [20, 4, 4, 4], [44, 7, 1, 8]] + -0.00119374010493299761 # B[954, [20, 4, 4, 4], [45, 7, 2, 7]] + -0.000775398926021152179 # B[955, [20, 4, 4, 4], [46, 7, 3, 8]] + -0.000670782103704289923 # B[956, [20, 4, 4, 4], [47, 7, 4, 7]] + -0.00192682764111087456 # B[957, [20, 4, 4, 4], [48, 7, 5, 8]] + -0.000648663865567958298 # B[958, [20, 4, 4, 4], [49, 7, 6, 7]] + -0.000387954189232417312 # B[959, [20, 4, 4, 4], [50, 7, 7, 8]] + 0.000302370648048068055 # B[960, [20, 4, 4, 4], [51, 8, 0, 8]] + -0.00085980088667597307 # B[961, [20, 4, 4, 4], [52, 8, 2, 8]] + 0.000568399123124077588 # B[962, [20, 4, 4, 4], [53, 8, 4, 8]] + -0.000482151590861096269 # B[963, [20, 4, 4, 4], [54, 8, 6, 8]] + -0.000405828455879983507 # B[964, [20, 4, 4, 4], [55, 8, 8, 8]] + 0.00165997230068267755 # B[965, [21, 4, 4, 6], [21, 4, 4, 6]] + 0.000963896255597472551 # B[966, [21, 4, 4, 6], [22, 4, 4, 8]] + 0.0002094521100325826 # B[967, [21, 4, 4, 6], [23, 5, 0, 5]] + 0.000534879644705995444 # B[968, [21, 4, 4, 6], [24, 5, 1, 6]] + 0.00292236533791157905 # B[969, [21, 4, 4, 6], [25, 5, 2, 5]] + 0.00151524368635043427 # B[970, [21, 4, 4, 6], [26, 5, 2, 7]] + -0.00101689007388491501 # B[971, [21, 4, 4, 6], [27, 5, 3, 6]] + 0.000738459806183821427 # B[972, [21, 4, 4, 6], [28, 5, 3, 8]] + 0.00148643764242684627 # B[973, [21, 4, 4, 6], [29, 5, 4, 5]] + 0.0011556877894129472 # B[974, [21, 4, 4, 6], [30, 5, 4, 7]] + -0.000208381440186615127 # B[975, [21, 4, 4, 6], [31, 5, 5, 6]] + -0.00143743030752817389 # B[976, [21, 4, 4, 6], [32, 5, 5, 8]] + -0.00016600302639456152 # B[977, [21, 4, 4, 6], [33, 6, 0, 6]] + 0.00172160125073629253 # B[978, [21, 4, 4, 6], [34, 6, 1, 7]] + 0.00344812165058533751 # B[979, [21, 4, 4, 6], [35, 6, 2, 6]] + 0.000544104512334869089 # B[980, [21, 4, 4, 6], [36, 6, 2, 8]] + -0.00182558144376257503 # B[981, [21, 4, 4, 6], [37, 6, 3, 7]] + 0.00101065848983370246 # B[982, [21, 4, 4, 6], [38, 6, 4, 6]] + 0.00103400096073465869 # B[983, [21, 4, 4, 6], [39, 6, 4, 8]] + -0.000235944095127582111 # B[984, [21, 4, 4, 6], [40, 6, 5, 7]] + 0.000154580830205655606 # B[985, [21, 4, 4, 6], [41, 6, 6, 6]] + -0.000488680460493023505 # B[986, [21, 4, 4, 6], [42, 6, 6, 8]] + 3.83739714257189113e-05 # B[987, [21, 4, 4, 6], [43, 7, 0, 7]] + -0.000275037336268196993 # B[988, [21, 4, 4, 6], [44, 7, 1, 8]] + 0.0017878021157122859 # B[989, [21, 4, 4, 6], [45, 7, 2, 7]] + -0.00110857713686632331 # B[990, [21, 4, 4, 6], [46, 7, 3, 8]] + -0.000126074852562767237 # B[991, [21, 4, 4, 6], [47, 7, 4, 7]] + -0.00125862858469075189 # B[992, [21, 4, 4, 6], [48, 7, 5, 8]] + -0.000277638160776805254 # B[993, [21, 4, 4, 6], [49, 7, 6, 7]] + 0.000163335859971639602 # B[994, [21, 4, 4, 6], [50, 7, 7, 8]] + 0.000151747507838979889 # B[995, [21, 4, 4, 6], [51, 8, 0, 8]] + 0.00156180455186682998 # B[996, [21, 4, 4, 6], [52, 8, 2, 8]] + 0.00112614353705531994 # B[997, [21, 4, 4, 6], [53, 8, 4, 8]] + -0.000376140365477903652 # B[998, [21, 4, 4, 6], [54, 8, 6, 8]] + -0.000378786757414536351 # B[999, [21, 4, 4, 6], [55, 8, 8, 8]] + -0.00186381195965971969 # B[1000, [22, 4, 4, 8], [22, 4, 4, 8]] + 0.000334060235611270684 # B[1001, [22, 4, 4, 8], [23, 5, 0, 5]] + -0.000182139490643212255 # B[1002, [22, 4, 4, 8], [24, 5, 1, 6]] + -0.000866414678376911532 # B[1003, [22, 4, 4, 8], [25, 5, 2, 5]] + -0.000713836573909394211 # B[1004, [22, 4, 4, 8], [26, 5, 2, 7]] + 0.00340359387460056721 # B[1005, [22, 4, 4, 8], [27, 5, 3, 6]] + -0.0025631762232975969 # B[1006, [22, 4, 4, 8], [28, 5, 3, 8]] + 0.00154837338005092001 # B[1007, [22, 4, 4, 8], [29, 5, 4, 5]] + -0.000713785025005329171 # B[1008, [22, 4, 4, 8], [30, 5, 4, 7]] + -6.17852167664190155e-06 # B[1009, [22, 4, 4, 8], [31, 5, 5, 6]] + -0.000925788250245492385 # B[1010, [22, 4, 4, 8], [32, 5, 5, 8]] + -0.000220618203180443506 # B[1011, [22, 4, 4, 8], [33, 6, 0, 6]] + 0.00158760304062654546 # B[1012, [22, 4, 4, 8], [34, 6, 1, 7]] + -0.00201296543384867077 # B[1013, [22, 4, 4, 8], [35, 6, 2, 6]] + -0.000153111573438037551 # B[1014, [22, 4, 4, 8], [36, 6, 2, 8]] + 0.001936342943994784 # B[1015, [22, 4, 4, 8], [37, 6, 3, 7]] + 0.0014724303902098404 # B[1016, [22, 4, 4, 8], [38, 6, 4, 6]] + 0.000412977919829218137 # B[1017, [22, 4, 4, 8], [39, 6, 4, 8]] + 0.000243129124011996767 # B[1018, [22, 4, 4, 8], [40, 6, 5, 7]] + 0.000433542078585167322 # B[1019, [22, 4, 4, 8], [41, 6, 6, 6]] + 5.87712210821707964e-05 # B[1020, [22, 4, 4, 8], [42, 6, 6, 8]] + -2.13873587015245281e-05 # B[1021, [22, 4, 4, 8], [43, 7, 0, 7]] + -0.00121671500578664389 # B[1022, [22, 4, 4, 8], [44, 7, 1, 8]] + 0.00185443425860575776 # B[1023, [22, 4, 4, 8], [45, 7, 2, 7]] + 0.00153976874095648406 # B[1024, [22, 4, 4, 8], [46, 7, 3, 8]] + 0.00100585852984078766 # B[1025, [22, 4, 4, 8], [47, 7, 4, 7]] + 0.000146502145157426621 # B[1026, [22, 4, 4, 8], [48, 7, 5, 8]] + 0.00026572798098887726 # B[1027, [22, 4, 4, 8], [49, 7, 6, 7]] + 0.000239744529446223043 # B[1028, [22, 4, 4, 8], [50, 7, 7, 8]] + 3.13331575558552233e-05 # B[1029, [22, 4, 4, 8], [51, 8, 0, 8]] + 0.0005761629631739415 # B[1030, [22, 4, 4, 8], [52, 8, 2, 8]] + 0.00020451472183747807 # B[1031, [22, 4, 4, 8], [53, 8, 4, 8]] + 0.000761501707699011737 # B[1032, [22, 4, 4, 8], [54, 8, 6, 8]] + 4.7608269104475881e-05 # B[1033, [22, 4, 4, 8], [55, 8, 8, 8]] + 0.00010288893231941848 # B[1034, [23, 5, 0, 5], [23, 5, 0, 5]] + -0.000598160679614365143 # B[1035, [23, 5, 0, 5], [24, 5, 1, 6]] + -0.000125600887517359969 # B[1036, [23, 5, 0, 5], [25, 5, 2, 5]] + -0.000541602347577959872 # B[1037, [23, 5, 0, 5], [26, 5, 2, 7]] + 0.000138742295315047448 # B[1038, [23, 5, 0, 5], [27, 5, 3, 6]] + 0.000320496112291311641 # B[1039, [23, 5, 0, 5], [28, 5, 3, 8]] + 9.77076363189860464e-05 # B[1040, [23, 5, 0, 5], [29, 5, 4, 5]] + -0.00018519393057754574 # B[1041, [23, 5, 0, 5], [30, 5, 4, 7]] + -0.000314308790209320843 # B[1042, [23, 5, 0, 5], [31, 5, 5, 6]] + -2.03507196530547385e-05 # B[1043, [23, 5, 0, 5], [32, 5, 5, 8]] + -8.76692912155085935e-08 # B[1044, [23, 5, 0, 5], [33, 6, 0, 6]] + -0.000208914241663854874 # B[1045, [23, 5, 0, 5], [34, 6, 1, 7]] + 0.000289191305925793653 # B[1046, [23, 5, 0, 5], [35, 6, 2, 6]] + 0.000292827060287376498 # B[1047, [23, 5, 0, 5], [36, 6, 2, 8]] + -0.000195999965143696386 # B[1048, [23, 5, 0, 5], [37, 6, 3, 7]] + 0.000122837407081860615 # B[1049, [23, 5, 0, 5], [38, 6, 4, 6]] + 0.000238061673948679331 # B[1050, [23, 5, 0, 5], [39, 6, 4, 8]] + 6.23458911314621333e-06 # B[1051, [23, 5, 0, 5], [40, 6, 5, 7]] + 0.000153645644536796327 # B[1052, [23, 5, 0, 5], [41, 6, 6, 6]] + 0.000208144485879115104 # B[1053, [23, 5, 0, 5], [42, 6, 6, 8]] + 0.000107382317423423967 # B[1054, [23, 5, 0, 5], [43, 7, 0, 7]] + -3.16437877474207152e-05 # B[1055, [23, 5, 0, 5], [44, 7, 1, 8]] + 5.2567890411161361e-05 # B[1056, [23, 5, 0, 5], [45, 7, 2, 7]] + -0.000407365287815795313 # B[1057, [23, 5, 0, 5], [46, 7, 3, 8]] + -0.000277007442936893014 # B[1058, [23, 5, 0, 5], [47, 7, 4, 7]] + -0.000163960409271388802 # B[1059, [23, 5, 0, 5], [48, 7, 5, 8]] + -0.00018222236229294142 # B[1060, [23, 5, 0, 5], [49, 7, 6, 7]] + -8.93725149996096868e-05 # B[1061, [23, 5, 0, 5], [50, 7, 7, 8]] + -4.59835267753172516e-05 # B[1062, [23, 5, 0, 5], [51, 8, 0, 8]] + -3.00980967951527262e-05 # B[1063, [23, 5, 0, 5], [52, 8, 2, 8]] + -0.00011786089545340328 # B[1064, [23, 5, 0, 5], [53, 8, 4, 8]] + 6.24840877215676604e-05 # B[1065, [23, 5, 0, 5], [54, 8, 6, 8]] + 0.000151333518371397913 # B[1066, [23, 5, 0, 5], [55, 8, 8, 8]] + -0.00373509601310103353 # B[1067, [24, 5, 1, 6], [24, 5, 1, 6]] + 0.00250350668234289742 # B[1068, [24, 5, 1, 6], [25, 5, 2, 5]] + -0.00141763987470412255 # B[1069, [24, 5, 1, 6], [26, 5, 2, 7]] + -0.000458490741576836162 # B[1070, [24, 5, 1, 6], [27, 5, 3, 6]] + 0.000169432811229417585 # B[1071, [24, 5, 1, 6], [28, 5, 3, 8]] + -0.000531768848310092699 # B[1072, [24, 5, 1, 6], [29, 5, 4, 5]] + 0.0019269207337581605 # B[1073, [24, 5, 1, 6], [30, 5, 4, 7]] + 0.000623468915929115824 # B[1074, [24, 5, 1, 6], [31, 5, 5, 6]] + 0.000262459747020924762 # B[1075, [24, 5, 1, 6], [32, 5, 5, 8]] + 0.000319464830252011445 # B[1076, [24, 5, 1, 6], [33, 6, 0, 6]] + 0.00250974732963905444 # B[1077, [24, 5, 1, 6], [34, 6, 1, 7]] + 0.00423653007687384807 # B[1078, [24, 5, 1, 6], [35, 6, 2, 6]] + 0.00144771358428595707 # B[1079, [24, 5, 1, 6], [36, 6, 2, 8]] + 0.00255496505633429419 # B[1080, [24, 5, 1, 6], [37, 6, 3, 7]] + -0.000923899857380450218 # B[1081, [24, 5, 1, 6], [38, 6, 4, 6]] + -0.000308666389289608337 # B[1082, [24, 5, 1, 6], [39, 6, 4, 8]] + 0.00222537659577300671 # B[1083, [24, 5, 1, 6], [40, 6, 5, 7]] + -0.00107541311587263343 # B[1084, [24, 5, 1, 6], [41, 6, 6, 6]] + -0.00278767944085371068 # B[1085, [24, 5, 1, 6], [42, 6, 6, 8]] + -0.000867530969177243705 # B[1086, [24, 5, 1, 6], [43, 7, 0, 7]] + 0.00357297895621819196 # B[1087, [24, 5, 1, 6], [44, 7, 1, 8]] + 0.00383976572090019216 # B[1088, [24, 5, 1, 6], [45, 7, 2, 7]] + -0.000580234942856992786 # B[1089, [24, 5, 1, 6], [46, 7, 3, 8]] + 0.00102888910081111798 # B[1090, [24, 5, 1, 6], [47, 7, 4, 7]] + 0.00132107614311613355 # B[1091, [24, 5, 1, 6], [48, 7, 5, 8]] + 0.00101848252621374036 # B[1092, [24, 5, 1, 6], [49, 7, 6, 7]] + 0.00160018234143227862 # B[1093, [24, 5, 1, 6], [50, 7, 7, 8]] + -5.52824024903572631e-05 # B[1094, [24, 5, 1, 6], [51, 8, 0, 8]] + 4.59186780197786033e-05 # B[1095, [24, 5, 1, 6], [52, 8, 2, 8]] + -0.000153436254581188554 # B[1096, [24, 5, 1, 6], [53, 8, 4, 8]] + -0.000546750998621967597 # B[1097, [24, 5, 1, 6], [54, 8, 6, 8]] + 0.000595956738118895348 # B[1098, [24, 5, 1, 6], [55, 8, 8, 8]] + 0.0083807047595118693 # B[1099, [25, 5, 2, 5], [25, 5, 2, 5]] + -0.000170544318645505719 # B[1100, [25, 5, 2, 5], [26, 5, 2, 7]] + 0.00235544441902155004 # B[1101, [25, 5, 2, 5], [27, 5, 3, 6]] + -0.00340197827063909962 # B[1102, [25, 5, 2, 5], [28, 5, 3, 8]] + 0.00311335525578198104 # B[1103, [25, 5, 2, 5], [29, 5, 4, 5]] + 0.00185214714164834123 # B[1104, [25, 5, 2, 5], [30, 5, 4, 7]] + -0.00328905913600528992 # B[1105, [25, 5, 2, 5], [31, 5, 5, 6]] + -0.00141866010082636025 # B[1106, [25, 5, 2, 5], [32, 5, 5, 8]] + 0.000176317033907393006 # B[1107, [25, 5, 2, 5], [33, 6, 0, 6]] + 0.00648328973805229608 # B[1108, [25, 5, 2, 5], [34, 6, 1, 7]] + 4.8980528358618259e-05 # B[1109, [25, 5, 2, 5], [35, 6, 2, 6]] + -0.00616971046300731144 # B[1110, [25, 5, 2, 5], [36, 6, 2, 8]] + -0.00135942372726050205 # B[1111, [25, 5, 2, 5], [37, 6, 3, 7]] + 0.000572735024796908881 # B[1112, [25, 5, 2, 5], [38, 6, 4, 6]] + -0.00229752149848994405 # B[1113, [25, 5, 2, 5], [39, 6, 4, 8]] + 0.0003485310815041524 # B[1114, [25, 5, 2, 5], [40, 6, 5, 7]] + -0.0011437361439647427 # B[1115, [25, 5, 2, 5], [41, 6, 6, 6]] + -0.000604819873822432311 # B[1116, [25, 5, 2, 5], [42, 6, 6, 8]] + 9.06237770597643696e-05 # B[1117, [25, 5, 2, 5], [43, 7, 0, 7]] + -0.000382141545017884894 # B[1118, [25, 5, 2, 5], [44, 7, 1, 8]] + -0.000842464094047663554 # B[1119, [25, 5, 2, 5], [45, 7, 2, 7]] + 0.000461973830441065811 # B[1120, [25, 5, 2, 5], [46, 7, 3, 8]] + 2.86192620363814355e-06 # B[1121, [25, 5, 2, 5], [47, 7, 4, 7]] + -0.0023436531447123838 # B[1122, [25, 5, 2, 5], [48, 7, 5, 8]] + 0.00134025173860287308 # B[1123, [25, 5, 2, 5], [49, 7, 6, 7]] + -0.000520013981518205846 # B[1124, [25, 5, 2, 5], [50, 7, 7, 8]] + 0.000515782740310496285 # B[1125, [25, 5, 2, 5], [51, 8, 0, 8]] + 0.00421651313615256564 # B[1126, [25, 5, 2, 5], [52, 8, 2, 8]] + 0.000755327719218409519 # B[1127, [25, 5, 2, 5], [53, 8, 4, 8]] + 0.000182937308412391315 # B[1128, [25, 5, 2, 5], [54, 8, 6, 8]] + 8.10383680097163071e-05 # B[1129, [25, 5, 2, 5], [55, 8, 8, 8]] + 0.000177735296666065024 # B[1130, [26, 5, 2, 7], [26, 5, 2, 7]] + -0.000642334677407747565 # B[1131, [26, 5, 2, 7], [27, 5, 3, 6]] + 0.000205172894139061396 # B[1132, [26, 5, 2, 7], [28, 5, 3, 8]] + -0.000537004220752698019 # B[1133, [26, 5, 2, 7], [29, 5, 4, 5]] + 5.14115941491347442e-05 # B[1134, [26, 5, 2, 7], [30, 5, 4, 7]] + 0.000417673445165051005 # B[1135, [26, 5, 2, 7], [31, 5, 5, 6]] + 0.00158446769775330391 # B[1136, [26, 5, 2, 7], [32, 5, 5, 8]] + 0.00121383407410429606 # B[1137, [26, 5, 2, 7], [33, 6, 0, 6]] + -0.00111992976945914785 # B[1138, [26, 5, 2, 7], [34, 6, 1, 7]] + 0.00398972286341117699 # B[1139, [26, 5, 2, 7], [35, 6, 2, 6]] + 0.00454565411209783762 # B[1140, [26, 5, 2, 7], [36, 6, 2, 8]] + -0.00300928796618537761 # B[1141, [26, 5, 2, 7], [37, 6, 3, 7]] + -0.00280024702462813163 # B[1142, [26, 5, 2, 7], [38, 6, 4, 6]] + 0.00182097597359056305 # B[1143, [26, 5, 2, 7], [39, 6, 4, 8]] + 0.00247143387165752772 # B[1144, [26, 5, 2, 7], [40, 6, 5, 7]] + -0.00143698477566456435 # B[1145, [26, 5, 2, 7], [41, 6, 6, 6]] + -0.00105878554545993375 # B[1146, [26, 5, 2, 7], [42, 6, 6, 8]] + 0.000650619036842032747 # B[1147, [26, 5, 2, 7], [43, 7, 0, 7]] + 8.72947879012740853e-05 # B[1148, [26, 5, 2, 7], [44, 7, 1, 8]] + -0.0002084941102769855 # B[1149, [26, 5, 2, 7], [45, 7, 2, 7]] + -0.000924608969529588931 # B[1150, [26, 5, 2, 7], [46, 7, 3, 8]] + -0.000320719808114693777 # B[1151, [26, 5, 2, 7], [47, 7, 4, 7]] + 0.00241998856780361801 # B[1152, [26, 5, 2, 7], [48, 7, 5, 8]] + -0.00171923440812344827 # B[1153, [26, 5, 2, 7], [49, 7, 6, 7]] + -0.000301390241580377569 # B[1154, [26, 5, 2, 7], [50, 7, 7, 8]] + -6.37461557401481499e-05 # B[1155, [26, 5, 2, 7], [51, 8, 0, 8]] + 0.00161644303684405446 # B[1156, [26, 5, 2, 7], [52, 8, 2, 8]] + 0.00104379414920739667 # B[1157, [26, 5, 2, 7], [53, 8, 4, 8]] + -0.00119795702190159808 # B[1158, [26, 5, 2, 7], [54, 8, 6, 8]] + 0.000604059138156293803 # B[1159, [26, 5, 2, 7], [55, 8, 8, 8]] + 0.000513459633959805622 # B[1160, [27, 5, 3, 6], [27, 5, 3, 6]] + -0.000172334638360790993 # B[1161, [27, 5, 3, 6], [28, 5, 3, 8]] + 1.60719061511648345e-05 # B[1162, [27, 5, 3, 6], [29, 5, 4, 5]] + 0.00440279299288983371 # B[1163, [27, 5, 3, 6], [30, 5, 4, 7]] + 0.000549761981236742206 # B[1164, [27, 5, 3, 6], [31, 5, 5, 6]] + 0.000424619689378998542 # B[1165, [27, 5, 3, 6], [32, 5, 5, 8]] + 0.000247367934895610653 # B[1166, [27, 5, 3, 6], [33, 6, 0, 6]] + 0.00400569055534595944 # B[1167, [27, 5, 3, 6], [34, 6, 1, 7]] + 0.00274378194299987679 # B[1168, [27, 5, 3, 6], [35, 6, 2, 6]] + 0.00368141326251353665 # B[1169, [27, 5, 3, 6], [36, 6, 2, 8]] + 0.00160469169395054817 # B[1170, [27, 5, 3, 6], [37, 6, 3, 7]] + 0.000105807739550402985 # B[1171, [27, 5, 3, 6], [38, 6, 4, 6]] + -0.000682801438033796976 # B[1172, [27, 5, 3, 6], [39, 6, 4, 8]] + -0.00121964915110857504 # B[1173, [27, 5, 3, 6], [40, 6, 5, 7]] + -0.000817665263990522556 # B[1174, [27, 5, 3, 6], [41, 6, 6, 6]] + 0.000534593784435832137 # B[1175, [27, 5, 3, 6], [42, 6, 6, 8]] + 0.000116542343021167755 # B[1176, [27, 5, 3, 6], [43, 7, 0, 7]] + 0.00351267154418699948 # B[1177, [27, 5, 3, 6], [44, 7, 1, 8]] + -0.00189934642995405814 # B[1178, [27, 5, 3, 6], [45, 7, 2, 7]] + 0.000751906974843792597 # B[1179, [27, 5, 3, 6], [46, 7, 3, 8]] + -0.000446808189773967301 # B[1180, [27, 5, 3, 6], [47, 7, 4, 7]] + -0.00324699511848197502 # B[1181, [27, 5, 3, 6], [48, 7, 5, 8]] + 2.53540837371335481e-05 # B[1182, [27, 5, 3, 6], [49, 7, 6, 7]] + 7.5273388360289073e-07 # B[1183, [27, 5, 3, 6], [50, 7, 7, 8]] + 0.00023346363571073725 # B[1184, [27, 5, 3, 6], [51, 8, 0, 8]] + 0.000490008984593369619 # B[1185, [27, 5, 3, 6], [52, 8, 2, 8]] + 0.000205260233742234413 # B[1186, [27, 5, 3, 6], [53, 8, 4, 8]] + -7.84984665939646165e-05 # B[1187, [27, 5, 3, 6], [54, 8, 6, 8]] + -0.000299454037036409743 # B[1188, [27, 5, 3, 6], [55, 8, 8, 8]] + -0.00411961786705090406 # B[1189, [28, 5, 3, 8], [28, 5, 3, 8]] + 0.00256764268592788759 # B[1190, [28, 5, 3, 8], [29, 5, 4, 5]] + -0.000267820435572239945 # B[1191, [28, 5, 3, 8], [30, 5, 4, 7]] + 0.000545048575291992229 # B[1192, [28, 5, 3, 8], [31, 5, 5, 6]] + -0.000141236037433873154 # B[1193, [28, 5, 3, 8], [32, 5, 5, 8]] + -8.17647193563642016e-05 # B[1194, [28, 5, 3, 8], [33, 6, 0, 6]] + 0.00184594470809960887 # B[1195, [28, 5, 3, 8], [34, 6, 1, 7]] + 0.000715653691449843685 # B[1196, [28, 5, 3, 8], [35, 6, 2, 6]] + -0.000371782729873919304 # B[1197, [28, 5, 3, 8], [36, 6, 2, 8]] + 0.00184451560473704312 # B[1198, [28, 5, 3, 8], [37, 6, 3, 7]] + 0.00298992898894900189 # B[1199, [28, 5, 3, 8], [38, 6, 4, 6]] + 0.00087474408278464047 # B[1200, [28, 5, 3, 8], [39, 6, 4, 8]] + 0.00115889056554823421 # B[1201, [28, 5, 3, 8], [40, 6, 5, 7]] + -0.000209440071593354482 # B[1202, [28, 5, 3, 8], [41, 6, 6, 6]] + 0.000707847416081031772 # B[1203, [28, 5, 3, 8], [42, 6, 6, 8]] + 0.00025922895119332573 # B[1204, [28, 5, 3, 8], [43, 7, 0, 7]] + -0.00210744601505012327 # B[1205, [28, 5, 3, 8], [44, 7, 1, 8]] + -0.00187401632149015486 # B[1206, [28, 5, 3, 8], [45, 7, 2, 7]] + 0.000616682247583759391 # B[1207, [28, 5, 3, 8], [46, 7, 3, 8]] + 0.00142526179781785924 # B[1208, [28, 5, 3, 8], [47, 7, 4, 7]] + -9.1619163886703936e-06 # B[1209, [28, 5, 3, 8], [48, 7, 5, 8]] + -0.000300978843055903222 # B[1210, [28, 5, 3, 8], [49, 7, 6, 7]] + -0.000124034381208077554 # B[1211, [28, 5, 3, 8], [50, 7, 7, 8]] + 0.000249158311162858692 # B[1212, [28, 5, 3, 8], [51, 8, 0, 8]] + -0.000970252220622513538 # B[1213, [28, 5, 3, 8], [52, 8, 2, 8]] + 0.000840312328335843066 # B[1214, [28, 5, 3, 8], [53, 8, 4, 8]] + 0.000145361901756495965 # B[1215, [28, 5, 3, 8], [54, 8, 6, 8]] + 0.00013163551986085896 # B[1216, [28, 5, 3, 8], [55, 8, 8, 8]] + 0.00265810885844912576 # B[1217, [29, 5, 4, 5], [29, 5, 4, 5]] + 0.00191793603428468823 # B[1218, [29, 5, 4, 5], [30, 5, 4, 7]] + 0.000446118694394436605 # B[1219, [29, 5, 4, 5], [31, 5, 5, 6]] + -9.59445098255573559e-05 # B[1220, [29, 5, 4, 5], [32, 5, 5, 8]] + 0.000369255428727587043 # B[1221, [29, 5, 4, 5], [33, 6, 0, 6]] + -0.000553149628059141762 # B[1222, [29, 5, 4, 5], [34, 6, 1, 7]] + 0.00315275275750991242 # B[1223, [29, 5, 4, 5], [35, 6, 2, 6]] + 0.00138540352181828336 # B[1224, [29, 5, 4, 5], [36, 6, 2, 8]] + 0.000776256233303879162 # B[1225, [29, 5, 4, 5], [37, 6, 3, 7]] + 0.000594477884906325672 # B[1226, [29, 5, 4, 5], [38, 6, 4, 6]] + 0.000757712543509288586 # B[1227, [29, 5, 4, 5], [39, 6, 4, 8]] + -0.000917903532807641184 # B[1228, [29, 5, 4, 5], [40, 6, 5, 7]] + -0.000915313398456763742 # B[1229, [29, 5, 4, 5], [41, 6, 6, 6]] + -0.00116732293566375843 # B[1230, [29, 5, 4, 5], [42, 6, 6, 8]] + 0.000172432189541951719 # B[1231, [29, 5, 4, 5], [43, 7, 0, 7]] + 0.000845370011774060912 # B[1232, [29, 5, 4, 5], [44, 7, 1, 8]] + 0.00178029205661471915 # B[1233, [29, 5, 4, 5], [45, 7, 2, 7]] + 0.00129739636685697463 # B[1234, [29, 5, 4, 5], [46, 7, 3, 8]] + 0.000282865369400489564 # B[1235, [29, 5, 4, 5], [47, 7, 4, 7]] + -0.00178988233479955398 # B[1236, [29, 5, 4, 5], [48, 7, 5, 8]] + 0.00023603474784275949 # B[1237, [29, 5, 4, 5], [49, 7, 6, 7]] + -0.000461436431325358207 # B[1238, [29, 5, 4, 5], [50, 7, 7, 8]] + 0.000234131705926524103 # B[1239, [29, 5, 4, 5], [51, 8, 0, 8]] + 0.00216254821351878363 # B[1240, [29, 5, 4, 5], [52, 8, 2, 8]] + 0.000831658742681578439 # B[1241, [29, 5, 4, 5], [53, 8, 4, 8]] + -0.00046318901257626742 # B[1242, [29, 5, 4, 5], [54, 8, 6, 8]] + -0.000607580535321294163 # B[1243, [29, 5, 4, 5], [55, 8, 8, 8]] + 0.00158347719827001653 # B[1244, [30, 5, 4, 7], [30, 5, 4, 7]] + 0.00120733638068271261 # B[1245, [30, 5, 4, 7], [31, 5, 5, 6]] + -0.000191610125195333311 # B[1246, [30, 5, 4, 7], [32, 5, 5, 8]] + -0.000363280761575070915 # B[1247, [30, 5, 4, 7], [33, 6, 0, 6]] + 0.0015080393447339897 # B[1248, [30, 5, 4, 7], [34, 6, 1, 7]] + 0.00144737958774105498 # B[1249, [30, 5, 4, 7], [35, 6, 2, 6]] + -0.000191256340607337365 # B[1250, [30, 5, 4, 7], [36, 6, 2, 8]] + 0.00324542123326504103 # B[1251, [30, 5, 4, 7], [37, 6, 3, 7]] + 0.00135369467391198949 # B[1252, [30, 5, 4, 7], [38, 6, 4, 6]] + 0.00077393986417062131 # B[1253, [30, 5, 4, 7], [39, 6, 4, 8]] + 0.00187057819081324836 # B[1254, [30, 5, 4, 7], [40, 6, 5, 7]] + 4.06728949024891956e-05 # B[1255, [30, 5, 4, 7], [41, 6, 6, 6]] + -0.000100060243024913467 # B[1256, [30, 5, 4, 7], [42, 6, 6, 8]] + -0.000170624797097965186 # B[1257, [30, 5, 4, 7], [43, 7, 0, 7]] + -0.00157200294852092963 # B[1258, [30, 5, 4, 7], [44, 7, 1, 8]] + -5.099465391029262e-05 # B[1259, [30, 5, 4, 7], [45, 7, 2, 7]] + 0.00166973065524506255 # B[1260, [30, 5, 4, 7], [46, 7, 3, 8]] + 0.000976468235486894175 # B[1261, [30, 5, 4, 7], [47, 7, 4, 7]] + -0.000570830124590235299 # B[1262, [30, 5, 4, 7], [48, 7, 5, 8]] + 0.000667250794893839427 # B[1263, [30, 5, 4, 7], [49, 7, 6, 7]] + -0.000273376565753529832 # B[1264, [30, 5, 4, 7], [50, 7, 7, 8]] + 0.000206233716860107844 # B[1265, [30, 5, 4, 7], [51, 8, 0, 8]] + 0.00260342927157033218 # B[1266, [30, 5, 4, 7], [52, 8, 2, 8]] + 0.000943954042545826558 # B[1267, [30, 5, 4, 7], [53, 8, 4, 8]] + -0.00022781927635321525 # B[1268, [30, 5, 4, 7], [54, 8, 6, 8]] + -0.000448456045604168733 # B[1269, [30, 5, 4, 7], [55, 8, 8, 8]] + 0.00102985782764508475 # B[1270, [31, 5, 5, 6], [31, 5, 5, 6]] + -8.89908688742153606e-05 # B[1271, [31, 5, 5, 6], [32, 5, 5, 8]] + -0.000162481274467801695 # B[1272, [31, 5, 5, 6], [33, 6, 0, 6]] + 0.00263772603538907271 # B[1273, [31, 5, 5, 6], [34, 6, 1, 7]] + -0.00223528099165903275 # B[1274, [31, 5, 5, 6], [35, 6, 2, 6]] + 0.000441657599119526373 # B[1275, [31, 5, 5, 6], [36, 6, 2, 8]] + 0.00165514785004864176 # B[1276, [31, 5, 5, 6], [37, 6, 3, 7]] + 0.000898928585103351413 # B[1277, [31, 5, 5, 6], [38, 6, 4, 6]] + -0.00026071204606309753 # B[1278, [31, 5, 5, 6], [39, 6, 4, 8]] + -0.000251612913047311385 # B[1279, [31, 5, 5, 6], [40, 6, 5, 7]] + -0.00022773870089292346 # B[1280, [31, 5, 5, 6], [41, 6, 6, 6]] + -0.000449951686975022525 # B[1281, [31, 5, 5, 6], [42, 6, 6, 8]] + -0.000252400784021909741 # B[1282, [31, 5, 5, 6], [43, 7, 0, 7]] + 0.000574433272355396977 # B[1283, [31, 5, 5, 6], [44, 7, 1, 8]] + -0.0014040949400035245 # B[1284, [31, 5, 5, 6], [45, 7, 2, 7]] + 0.00124516802775002586 # B[1285, [31, 5, 5, 6], [46, 7, 3, 8]] + 0.000875572292146320832 # B[1286, [31, 5, 5, 6], [47, 7, 4, 7]] + -0.000509730931921630048 # B[1287, [31, 5, 5, 6], [48, 7, 5, 8]] + 0.000422266146488117777 # B[1288, [31, 5, 5, 6], [49, 7, 6, 7]] + -0.000239146684560266956 # B[1289, [31, 5, 5, 6], [50, 7, 7, 8]] + 9.95899703990707486e-05 # B[1290, [31, 5, 5, 6], [51, 8, 0, 8]] + -0.0020784147827535588 # B[1291, [31, 5, 5, 6], [52, 8, 2, 8]] + 0.000735684723224858811 # B[1292, [31, 5, 5, 6], [53, 8, 4, 8]] + -0.000248804810033285279 # B[1293, [31, 5, 5, 6], [54, 8, 6, 8]] + -0.000598263607047986451 # B[1294, [31, 5, 5, 6], [55, 8, 8, 8]] + 0.000131065920905359436 # B[1295, [32, 5, 5, 8], [32, 5, 5, 8]] + 0.000100196796943449913 # B[1296, [32, 5, 5, 8], [33, 6, 0, 6]] + -0.00173991171955805834 # B[1297, [32, 5, 5, 8], [34, 6, 1, 7]] + -0.000490539010579770906 # B[1298, [32, 5, 5, 8], [35, 6, 2, 6]] + 0.000676191083650941674 # B[1299, [32, 5, 5, 8], [36, 6, 2, 8]] + 0.000446932761165407325 # B[1300, [32, 5, 5, 8], [37, 6, 3, 7]] + -0.000153107558622965576 # B[1301, [32, 5, 5, 8], [38, 6, 4, 6]] + 1.67752859932734574e-05 # B[1302, [32, 5, 5, 8], [39, 6, 4, 8]] + 0.000215146896189506113 # B[1303, [32, 5, 5, 8], [40, 6, 5, 7]] + -0.000188466441880926362 # B[1304, [32, 5, 5, 8], [41, 6, 6, 6]] + -4.80917708388720055e-06 # B[1305, [32, 5, 5, 8], [42, 6, 6, 8]] + -5.04429979448911547e-05 # B[1306, [32, 5, 5, 8], [43, 7, 0, 7]] + -0.000494944862407609067 # B[1307, [32, 5, 5, 8], [44, 7, 1, 8]] + -0.000424473825928651724 # B[1308, [32, 5, 5, 8], [45, 7, 2, 7]] + 0.000417544384337296959 # B[1309, [32, 5, 5, 8], [46, 7, 3, 8]] + 0.000431586591455488614 # B[1310, [32, 5, 5, 8], [47, 7, 4, 7]] + 0.000187341827588022357 # B[1311, [32, 5, 5, 8], [48, 7, 5, 8]] + -6.87669988055673864e-05 # B[1312, [32, 5, 5, 8], [49, 7, 6, 7]] + 0.000147867669408649482 # B[1313, [32, 5, 5, 8], [50, 7, 7, 8]] + -7.32201679551347517e-06 # B[1314, [32, 5, 5, 8], [51, 8, 0, 8]] + -0.000392519615947300787 # B[1315, [32, 5, 5, 8], [52, 8, 2, 8]] + 8.78465325612771269e-05 # B[1316, [32, 5, 5, 8], [53, 8, 4, 8]] + -6.3960070015590606e-05 # B[1317, [32, 5, 5, 8], [54, 8, 6, 8]] + -7.97839909379757101e-06 # B[1318, [32, 5, 5, 8], [55, 8, 8, 8]] + 3.95695067041609838e-05 # B[1319, [33, 6, 0, 6], [33, 6, 0, 6]] + -0.000611658005184461534 # B[1320, [33, 6, 0, 6], [34, 6, 1, 7]] + -0.000277914808470863806 # B[1321, [33, 6, 0, 6], [35, 6, 2, 6]] + 0.000987938388973043716 # B[1322, [33, 6, 0, 6], [36, 6, 2, 8]] + 0.000198558948919527745 # B[1323, [33, 6, 0, 6], [37, 6, 3, 7]] + 9.76274805398642809e-05 # B[1324, [33, 6, 0, 6], [38, 6, 4, 6]] + 9.92197766131464043e-05 # B[1325, [33, 6, 0, 6], [39, 6, 4, 8]] + -4.16996931875308896e-05 # B[1326, [33, 6, 0, 6], [40, 6, 5, 7]] + -5.3495059095630057e-05 # B[1327, [33, 6, 0, 6], [41, 6, 6, 6]] + 1.0720822351671655e-05 # B[1328, [33, 6, 0, 6], [42, 6, 6, 8]] + 0.000114464898537391946 # B[1329, [33, 6, 0, 6], [43, 7, 0, 7]] + -0.00033593422820483651 # B[1330, [33, 6, 0, 6], [44, 7, 1, 8]] + -0.00061665800523461739 # B[1331, [33, 6, 0, 6], [45, 7, 2, 7]] + -0.000258302532232180387 # B[1332, [33, 6, 0, 6], [46, 7, 3, 8]] + 3.78181072490033077e-05 # B[1333, [33, 6, 0, 6], [47, 7, 4, 7]] + -0.000326273283142861775 # B[1334, [33, 6, 0, 6], [48, 7, 5, 8]] + 1.74277156155672186e-05 # B[1335, [33, 6, 0, 6], [49, 7, 6, 7]] + -0.000206600107910874173 # B[1336, [33, 6, 0, 6], [50, 7, 7, 8]] + 2.12855018918572947e-05 # B[1337, [33, 6, 0, 6], [51, 8, 0, 8]] + -0.000696835386532819456 # B[1338, [33, 6, 0, 6], [52, 8, 2, 8]] + 8.06841007746916805e-05 # B[1339, [33, 6, 0, 6], [53, 8, 4, 8]] + 1.96129469472779844e-05 # B[1340, [33, 6, 0, 6], [54, 8, 6, 8]] + 7.35114191380559223e-05 # B[1341, [33, 6, 0, 6], [55, 8, 8, 8]] + 0.00360109138862139185 # B[1342, [34, 6, 1, 7], [34, 6, 1, 7]] + 0.00304872474261531218 # B[1343, [34, 6, 1, 7], [35, 6, 2, 6]] + -0.00546316824530662139 # B[1344, [34, 6, 1, 7], [36, 6, 2, 8]] + 0.000721988419001898946 # B[1345, [34, 6, 1, 7], [37, 6, 3, 7]] + -0.00254968694435141717 # B[1346, [34, 6, 1, 7], [38, 6, 4, 6]] + -0.00102187793811427596 # B[1347, [34, 6, 1, 7], [39, 6, 4, 8]] + 0.000977866285507509106 # B[1348, [34, 6, 1, 7], [40, 6, 5, 7]] + 0.00129156024637028417 # B[1349, [34, 6, 1, 7], [41, 6, 6, 6]] + 8.43980229575398005e-05 # B[1350, [34, 6, 1, 7], [42, 6, 6, 8]] + -0.000854491821273548058 # B[1351, [34, 6, 1, 7], [43, 7, 0, 7]] + -0.00229655360277009144 # B[1352, [34, 6, 1, 7], [44, 7, 1, 8]] + 0.00392740594657482126 # B[1353, [34, 6, 1, 7], [45, 7, 2, 7]] + 0.00282086313880587115 # B[1354, [34, 6, 1, 7], [46, 7, 3, 8]] + -0.00269367822401865922 # B[1355, [34, 6, 1, 7], [47, 7, 4, 7]] + 0.00120544917432826269 # B[1356, [34, 6, 1, 7], [48, 7, 5, 8]] + 0.00137213082032611872 # B[1357, [34, 6, 1, 7], [49, 7, 6, 7]] + 0.00278774897747785522 # B[1358, [34, 6, 1, 7], [50, 7, 7, 8]] + -1.00075929411755707e-05 # B[1359, [34, 6, 1, 7], [51, 8, 0, 8]] + 0.00331402709384703321 # B[1360, [34, 6, 1, 7], [52, 8, 2, 8]] + -0.00220016465090739841 # B[1361, [34, 6, 1, 7], [53, 8, 4, 8]] + 0.000794479619849004434 # B[1362, [34, 6, 1, 7], [54, 8, 6, 8]] + 0.000207117210070053084 # B[1363, [34, 6, 1, 7], [55, 8, 8, 8]] + 0.000547206364960122621 # B[1364, [35, 6, 2, 6], [35, 6, 2, 6]] + 0.00243529980905243717 # B[1365, [35, 6, 2, 6], [36, 6, 2, 8]] + 0.000346076245330416421 # B[1366, [35, 6, 2, 6], [37, 6, 3, 7]] + 0.00220550296989585788 # B[1367, [35, 6, 2, 6], [38, 6, 4, 6]] + 0.00101934408216735467 # B[1368, [35, 6, 2, 6], [39, 6, 4, 8]] + 6.76995447894471192e-05 # B[1369, [35, 6, 2, 6], [40, 6, 5, 7]] + -4.61734905116591154e-05 # B[1370, [35, 6, 2, 6], [41, 6, 6, 6]] + 0.000809543629624515093 # B[1371, [35, 6, 2, 6], [42, 6, 6, 8]] + 0.000219078295465409238 # B[1372, [35, 6, 2, 6], [43, 7, 0, 7]] + -0.00316872925249137884 # B[1373, [35, 6, 2, 6], [44, 7, 1, 8]] + 0.000676713636760976206 # B[1374, [35, 6, 2, 6], [45, 7, 2, 7]] + -0.00100477918211841141 # B[1375, [35, 6, 2, 6], [46, 7, 3, 8]] + 0.000400524978896980161 # B[1376, [35, 6, 2, 6], [47, 7, 4, 7]] + -0.00197634098305848622 # B[1377, [35, 6, 2, 6], [48, 7, 5, 8]] + 0.000367979983554051621 # B[1378, [35, 6, 2, 6], [49, 7, 6, 7]] + -0.00126672502130457942 # B[1379, [35, 6, 2, 6], [50, 7, 7, 8]] + 0.000161373464169148675 # B[1380, [35, 6, 2, 6], [51, 8, 0, 8]] + 0.00258770627559228462 # B[1381, [35, 6, 2, 6], [52, 8, 2, 8]] + 0.000816135012742828661 # B[1382, [35, 6, 2, 6], [53, 8, 4, 8]] + -3.28991122771973843e-05 # B[1383, [35, 6, 2, 6], [54, 8, 6, 8]] + -4.18127338362338707e-05 # B[1384, [35, 6, 2, 6], [55, 8, 8, 8]] + 0.00658745572292138409 # B[1385, [36, 6, 2, 8], [36, 6, 2, 8]] + -0.00238764687643479301 # B[1386, [36, 6, 2, 8], [37, 6, 3, 7]] + -0.000831950910425274803 # B[1387, [36, 6, 2, 8], [38, 6, 4, 6]] + 0.00351737364404769177 # B[1388, [36, 6, 2, 8], [39, 6, 4, 8]] + -0.00276293358095670936 # B[1389, [36, 6, 2, 8], [40, 6, 5, 7]] + -0.00115031008308692437 # B[1390, [36, 6, 2, 8], [41, 6, 6, 6]] + -0.000921624256609663434 # B[1391, [36, 6, 2, 8], [42, 6, 6, 8]] + 0.000810924380859275734 # B[1392, [36, 6, 2, 8], [43, 7, 0, 7]] + -0.00488922361819911239 # B[1393, [36, 6, 2, 8], [44, 7, 1, 8]] + 0.00170426259508682162 # B[1394, [36, 6, 2, 8], [45, 7, 2, 7]] + -0.000698037236981145087 # B[1395, [36, 6, 2, 8], [46, 7, 3, 8]] + -0.00159293071425275958 # B[1396, [36, 6, 2, 8], [47, 7, 4, 7]] + 0.00145526568566858513 # B[1397, [36, 6, 2, 8], [48, 7, 5, 8]] + -0.0034526631911915729 # B[1398, [36, 6, 2, 8], [49, 7, 6, 7]] + 0.00136118079841816148 # B[1399, [36, 6, 2, 8], [50, 7, 7, 8]] + -0.000519558666561149851 # B[1400, [36, 6, 2, 8], [51, 8, 0, 8]] + -0.00125430728243427136 # B[1401, [36, 6, 2, 8], [52, 8, 2, 8]] + 0.000225746730173992209 # B[1402, [36, 6, 2, 8], [53, 8, 4, 8]] + 0.000144081610870761424 # B[1403, [36, 6, 2, 8], [54, 8, 6, 8]] + 0.000848192939185923693 # B[1404, [36, 6, 2, 8], [55, 8, 8, 8]] + 0.00209760366601450393 # B[1405, [37, 6, 3, 7], [37, 6, 3, 7]] + -0.00114098142783233825 # B[1406, [37, 6, 3, 7], [38, 6, 4, 6]] + -0.00012482798433224862 # B[1407, [37, 6, 3, 7], [39, 6, 4, 8]] + 0.000414303981445450498 # B[1408, [37, 6, 3, 7], [40, 6, 5, 7]] + -2.06949976952613968e-05 # B[1409, [37, 6, 3, 7], [41, 6, 6, 6]] + 0.000986658381613915447 # B[1410, [37, 6, 3, 7], [42, 6, 6, 8]] + 0.000196361012595618056 # B[1411, [37, 6, 3, 7], [43, 7, 0, 7]] + 0.000421620511108736218 # B[1412, [37, 6, 3, 7], [44, 7, 1, 8]] + -0.00121366957406692996 # B[1413, [37, 6, 3, 7], [45, 7, 2, 7]] + 0.000319772245183778947 # B[1414, [37, 6, 3, 7], [46, 7, 3, 8]] + -0.00189440310525268441 # B[1415, [37, 6, 3, 7], [47, 7, 4, 7]] + -0.000420808921505540223 # B[1416, [37, 6, 3, 7], [48, 7, 5, 8]] + -0.000833056882638676111 # B[1417, [37, 6, 3, 7], [49, 7, 6, 7]] + -0.000210394181928773294 # B[1418, [37, 6, 3, 7], [50, 7, 7, 8]] + 4.67415997983874898e-05 # B[1419, [37, 6, 3, 7], [51, 8, 0, 8]] + -0.000629437221263145228 # B[1420, [37, 6, 3, 7], [52, 8, 2, 8]] + -0.000561739301858470846 # B[1421, [37, 6, 3, 7], [53, 8, 4, 8]] + -0.000244403089656959616 # B[1422, [37, 6, 3, 7], [54, 8, 6, 8]] + 0.000170058213410727299 # B[1423, [37, 6, 3, 7], [55, 8, 8, 8]] + 0.000190580820336867102 # B[1424, [38, 6, 4, 6], [38, 6, 4, 6]] + -5.17086422710446442e-05 # B[1425, [38, 6, 4, 6], [39, 6, 4, 8]] + -0.000870479233908965505 # B[1426, [38, 6, 4, 6], [40, 6, 5, 7]] + 8.56431173592298034e-05 # B[1427, [38, 6, 4, 6], [41, 6, 6, 6]] + -0.000219028113680014638 # B[1428, [38, 6, 4, 6], [42, 6, 6, 8]] + 6.99094597341239771e-05 # B[1429, [38, 6, 4, 6], [43, 7, 0, 7]] + -0.00217214753267054063 # B[1430, [38, 6, 4, 6], [44, 7, 1, 8]] + 0.00103452950595812193 # B[1431, [38, 6, 4, 6], [45, 7, 2, 7]] + 0.000131158053198399821 # B[1432, [38, 6, 4, 6], [46, 7, 3, 8]] + -0.000991288929959081421 # B[1433, [38, 6, 4, 6], [47, 7, 4, 7]] + -0.000321058899826150157 # B[1434, [38, 6, 4, 6], [48, 7, 5, 8]] + -0.000126379357764709599 # B[1435, [38, 6, 4, 6], [49, 7, 6, 7]] + 0.000513859397020456632 # B[1436, [38, 6, 4, 6], [50, 7, 7, 8]] + -2.72482190626921472e-05 # B[1437, [38, 6, 4, 6], [51, 8, 0, 8]] + 0.000742781076179950886 # B[1438, [38, 6, 4, 6], [52, 8, 2, 8]] + -9.17701606060090935e-05 # B[1439, [38, 6, 4, 6], [53, 8, 4, 8]] + 1.49768390447675703e-05 # B[1440, [38, 6, 4, 6], [54, 8, 6, 8]] + -5.94521118466549703e-05 # B[1441, [38, 6, 4, 6], [55, 8, 8, 8]] + 0.00161400415689978271 # B[1442, [39, 6, 4, 8], [39, 6, 4, 8]] + -0.000149892220376375129 # B[1443, [39, 6, 4, 8], [40, 6, 5, 7]] + -0.000242832088631229209 # B[1444, [39, 6, 4, 8], [41, 6, 6, 6]] + -4.23223006292567511e-05 # B[1445, [39, 6, 4, 8], [42, 6, 6, 8]] + 0.000145544599928226076 # B[1446, [39, 6, 4, 8], [43, 7, 0, 7]] + -0.000846976149028450323 # B[1447, [39, 6, 4, 8], [44, 7, 1, 8]] + 0.000313402576083809947 # B[1448, [39, 6, 4, 8], [45, 7, 2, 7]] + -0.00105304559168569421 # B[1449, [39, 6, 4, 8], [46, 7, 3, 8]] + -0.000563622717067245593 # B[1450, [39, 6, 4, 8], [47, 7, 4, 7]] + -0.000176248327800098206 # B[1451, [39, 6, 4, 8], [48, 7, 5, 8]] + -0.000523005481859822874 # B[1452, [39, 6, 4, 8], [49, 7, 6, 7]] + 0.000327425878709725754 # B[1453, [39, 6, 4, 8], [50, 7, 7, 8]] + -0.000214075091648432969 # B[1454, [39, 6, 4, 8], [51, 8, 0, 8]] + 0.000892962890338189208 # B[1455, [39, 6, 4, 8], [52, 8, 2, 8]] + 0.000483016760753301674 # B[1456, [39, 6, 4, 8], [53, 8, 4, 8]] + 0.000385986009520520711 # B[1457, [39, 6, 4, 8], [54, 8, 6, 8]] + 0.000210387221014841225 # B[1458, [39, 6, 4, 8], [55, 8, 8, 8]] + 0.000423894835630976054 # B[1459, [40, 6, 5, 7], [40, 6, 5, 7]] + 2.52152593651043533e-05 # B[1460, [40, 6, 5, 7], [41, 6, 6, 6]] + 0.0001406783760301792 # B[1461, [40, 6, 5, 7], [42, 6, 6, 8]] + -0.000402862939603353815 # B[1462, [40, 6, 5, 7], [43, 7, 0, 7]] + -0.000764679971924708997 # B[1463, [40, 6, 5, 7], [44, 7, 1, 8]] + 0.000690122720081854865 # B[1464, [40, 6, 5, 7], [45, 7, 2, 7]] + 0.00135911524951161378 # B[1465, [40, 6, 5, 7], [46, 7, 3, 8]] + 5.52075818169902449e-06 # B[1466, [40, 6, 5, 7], [47, 7, 4, 7]] + -0.000149902773226399076 # B[1467, [40, 6, 5, 7], [48, 7, 5, 8]] + 0.000389894625400750289 # B[1468, [40, 6, 5, 7], [49, 7, 6, 7]] + 0.000257807843360047251 # B[1469, [40, 6, 5, 7], [50, 7, 7, 8]] + -3.67912373811542237e-05 # B[1470, [40, 6, 5, 7], [51, 8, 0, 8]] + -0.000174743024771516643 # B[1471, [40, 6, 5, 7], [52, 8, 2, 8]] + 0.000276798622678277838 # B[1472, [40, 6, 5, 7], [53, 8, 4, 8]] + 0.000152459620483783032 # B[1473, [40, 6, 5, 7], [54, 8, 6, 8]] + -0.000616599602238733502 # B[1474, [40, 6, 5, 7], [55, 8, 8, 8]] + -5.12324624723156652e-05 # B[1475, [41, 6, 6, 6], [41, 6, 6, 6]] + -4.23334509430418893e-05 # B[1476, [41, 6, 6, 6], [42, 6, 6, 8]] + -0.000111212733055157664 # B[1477, [41, 6, 6, 6], [43, 7, 0, 7]] + 0.000882360189618891337 # B[1478, [41, 6, 6, 6], [44, 7, 1, 8]] + -0.000581964842687935843 # B[1479, [41, 6, 6, 6], [45, 7, 2, 7]] + 0.000211138997961872465 # B[1480, [41, 6, 6, 6], [46, 7, 3, 8]] + 7.79906436828414068e-05 # B[1481, [41, 6, 6, 6], [47, 7, 4, 7]] + -0.000201461425275273331 # B[1482, [41, 6, 6, 6], [48, 7, 5, 8]] + 6.87828589884392771e-05 # B[1483, [41, 6, 6, 6], [49, 7, 6, 7]] + 0.000150653067204437052 # B[1484, [41, 6, 6, 6], [50, 7, 7, 8]] + 3.87532549918634395e-05 # B[1485, [41, 6, 6, 6], [51, 8, 0, 8]] + 0.000361299779465781672 # B[1486, [41, 6, 6, 6], [52, 8, 2, 8]] + -0.000217385549744270783 # B[1487, [41, 6, 6, 6], [53, 8, 4, 8]] + 6.09508622621875856e-05 # B[1488, [41, 6, 6, 6], [54, 8, 6, 8]] + -0.000174447165900721429 # B[1489, [41, 6, 6, 6], [55, 8, 8, 8]] + 4.08451735536830007e-05 # B[1490, [42, 6, 6, 8], [42, 6, 6, 8]] + -0.000100109250872669128 # B[1491, [42, 6, 6, 8], [43, 7, 0, 7]] + 0.000543796967600337564 # B[1492, [42, 6, 6, 8], [44, 7, 1, 8]] + 0.000744432946735457124 # B[1493, [42, 6, 6, 8], [45, 7, 2, 7]] + 0.0010803210667922683 # B[1494, [42, 6, 6, 8], [46, 7, 3, 8]] + 0.000151445105968722347 # B[1495, [42, 6, 6, 8], [47, 7, 4, 7]] + -0.000100848877598445907 # B[1496, [42, 6, 6, 8], [48, 7, 5, 8]] + -0.000109088350721993355 # B[1497, [42, 6, 6, 8], [49, 7, 6, 7]] + -0.000287924009882135207 # B[1498, [42, 6, 6, 8], [50, 7, 7, 8]] + 1.48405987461727729e-05 # B[1499, [42, 6, 6, 8], [51, 8, 0, 8]] + 0.00133229142431166023 # B[1500, [42, 6, 6, 8], [52, 8, 2, 8]] + -0.00019157481902659472 # B[1501, [42, 6, 6, 8], [53, 8, 4, 8]] + -0.000214414469154704246 # B[1502, [42, 6, 6, 8], [54, 8, 6, 8]] + -0.000145460173238021184 # B[1503, [42, 6, 6, 8], [55, 8, 8, 8]] + 0.000122164068846408735 # B[1504, [43, 7, 0, 7], [43, 7, 0, 7]] + -0.000271198052548764657 # B[1505, [43, 7, 0, 7], [44, 7, 1, 8]] + -7.53020792218089818e-05 # B[1506, [43, 7, 0, 7], [45, 7, 2, 7]] + -0.000522043739406908344 # B[1507, [43, 7, 0, 7], [46, 7, 3, 8]] + -4.818852612961666e-05 # B[1508, [43, 7, 0, 7], [47, 7, 4, 7]] + -0.000220542438614808323 # B[1509, [43, 7, 0, 7], [48, 7, 5, 8]] + -0.000160998835878327362 # B[1510, [43, 7, 0, 7], [49, 7, 6, 7]] + -2.41628428966911279e-05 # B[1511, [43, 7, 0, 7], [50, 7, 7, 8]] + -1.41474469189661889e-05 # B[1512, [43, 7, 0, 7], [51, 8, 0, 8]] + -0.000160534811881916234 # B[1513, [43, 7, 0, 7], [52, 8, 2, 8]] + -1.73735621299461046e-05 # B[1514, [43, 7, 0, 7], [53, 8, 4, 8]] + 4.73251016045242445e-05 # B[1515, [43, 7, 0, 7], [54, 8, 6, 8]] + 0.000182463508348683356 # B[1516, [43, 7, 0, 7], [55, 8, 8, 8]] + -0.000629134879565343137 # B[1517, [44, 7, 1, 8], [44, 7, 1, 8]] + -0.00207361578267727673 # B[1518, [44, 7, 1, 8], [45, 7, 2, 7]] + 0.0031686999001355326 # B[1519, [44, 7, 1, 8], [46, 7, 3, 8]] + -0.000405403647932546952 # B[1520, [44, 7, 1, 8], [47, 7, 4, 7]] + -0.000111251617971438489 # B[1521, [44, 7, 1, 8], [48, 7, 5, 8]] + 0.0014482690523848242 # B[1522, [44, 7, 1, 8], [49, 7, 6, 7]] + 0.000818892450912583197 # B[1523, [44, 7, 1, 8], [50, 7, 7, 8]] + 0.000100422502558870572 # B[1524, [44, 7, 1, 8], [51, 8, 0, 8]] + -0.000412863674396233161 # B[1525, [44, 7, 1, 8], [52, 8, 2, 8]] + -0.000905494278120194153 # B[1526, [44, 7, 1, 8], [53, 8, 4, 8]] + 0.00126932173443552359 # B[1527, [44, 7, 1, 8], [54, 8, 6, 8]] + -0.000374814469421512735 # B[1528, [44, 7, 1, 8], [55, 8, 8, 8]] + -0.00330341133748704441 # B[1529, [45, 7, 2, 7], [45, 7, 2, 7]] + 0.00131616674488897398 # B[1530, [45, 7, 2, 7], [46, 7, 3, 8]] + -0.000483635326292886428 # B[1531, [45, 7, 2, 7], [47, 7, 4, 7]] + -0.00177550615332965067 # B[1532, [45, 7, 2, 7], [48, 7, 5, 8]] + 0.00226091969304176299 # B[1533, [45, 7, 2, 7], [49, 7, 6, 7]] + -0.00142635978155006456 # B[1534, [45, 7, 2, 7], [50, 7, 7, 8]] + 0.000289476939908078768 # B[1535, [45, 7, 2, 7], [51, 8, 0, 8]] + 0.000582488578419503846 # B[1536, [45, 7, 2, 7], [52, 8, 2, 8]] + -0.000228795123723987606 # B[1537, [45, 7, 2, 7], [53, 8, 4, 8]] + 0.000478658611037000373 # B[1538, [45, 7, 2, 7], [54, 8, 6, 8]] + -0.00101956994563059782 # B[1539, [45, 7, 2, 7], [55, 8, 8, 8]] + 0.00268648192223141895 # B[1540, [46, 7, 3, 8], [46, 7, 3, 8]] + 0.000515570689344949529 # B[1541, [46, 7, 3, 8], [47, 7, 4, 7]] + 0.000903689215066725768 # B[1542, [46, 7, 3, 8], [48, 7, 5, 8]] + 0.00180650309403464215 # B[1543, [46, 7, 3, 8], [49, 7, 6, 7]] + -7.48574841450792838e-05 # B[1544, [46, 7, 3, 8], [50, 7, 7, 8]] + -2.90930360741237237e-05 # B[1545, [46, 7, 3, 8], [51, 8, 0, 8]] + 0.00139057844941538594 # B[1546, [46, 7, 3, 8], [52, 8, 2, 8]] + -0.000263907165716330272 # B[1547, [46, 7, 3, 8], [53, 8, 4, 8]] + -5.74521512815137289e-05 # B[1548, [46, 7, 3, 8], [54, 8, 6, 8]] + -0.00030234445629373323 # B[1549, [46, 7, 3, 8], [55, 8, 8, 8]] + -0.000842080339294604824 # B[1550, [47, 7, 4, 7], [47, 7, 4, 7]] + -1.8677234631915389e-05 # B[1551, [47, 7, 4, 7], [48, 7, 5, 8]] + 0.000150434033167294937 # B[1552, [47, 7, 4, 7], [49, 7, 6, 7]] + 0.000201922161197246736 # B[1553, [47, 7, 4, 7], [50, 7, 7, 8]] + 5.63689077359152968e-05 # B[1554, [47, 7, 4, 7], [51, 8, 0, 8]] + 0.000490229079971716761 # B[1555, [47, 7, 4, 7], [52, 8, 2, 8]] + -0.00019335269881828529 # B[1556, [47, 7, 4, 7], [53, 8, 4, 8]] + -0.000118664083374402096 # B[1557, [47, 7, 4, 7], [54, 8, 6, 8]] + -0.000397263359111398734 # B[1558, [47, 7, 4, 7], [55, 8, 8, 8]] + -0.000724261739409587726 # B[1559, [48, 7, 5, 8], [48, 7, 5, 8]] + 0.000186853474209224685 # B[1560, [48, 7, 5, 8], [49, 7, 6, 7]] + -0.000533321040010020266 # B[1561, [48, 7, 5, 8], [50, 7, 7, 8]] + 9.95102706208284005e-08 # B[1562, [48, 7, 5, 8], [51, 8, 0, 8]] + -0.00093755398196557671 # B[1563, [48, 7, 5, 8], [52, 8, 2, 8]] + 0.000483236780374178207 # B[1564, [48, 7, 5, 8], [53, 8, 4, 8]] + -5.03524206302112531e-05 # B[1565, [48, 7, 5, 8], [54, 8, 6, 8]] + -0.000586245052440398373 # B[1566, [48, 7, 5, 8], [55, 8, 8, 8]] + -0.000207118017941997773 # B[1567, [49, 7, 6, 7], [49, 7, 6, 7]] + -9.40116364012005823e-05 # B[1568, [49, 7, 6, 7], [50, 7, 7, 8]] + 0.000124266884770383307 # B[1569, [49, 7, 6, 7], [51, 8, 0, 8]] + 0.00118479186165786239 # B[1570, [49, 7, 6, 7], [52, 8, 2, 8]] + -0.000129238345120056067 # B[1571, [49, 7, 6, 7], [53, 8, 4, 8]] + -0.000383875224777865259 # B[1572, [49, 7, 6, 7], [54, 8, 6, 8]] + -0.000457194559055141767 # B[1573, [49, 7, 6, 7], [55, 8, 8, 8]] + -0.000450510261664234871 # B[1574, [50, 7, 7, 8], [50, 7, 7, 8]] + 7.52704593073999506e-05 # B[1575, [50, 7, 7, 8], [51, 8, 0, 8]] + -0.00128732840082427732 # B[1576, [50, 7, 7, 8], [52, 8, 2, 8]] + 0.000293225651298797269 # B[1577, [50, 7, 7, 8], [53, 8, 4, 8]] + -0.000306521733645761033 # B[1578, [50, 7, 7, 8], [54, 8, 6, 8]] + -0.000370268243746852549 # B[1579, [50, 7, 7, 8], [55, 8, 8, 8]] + -4.00747887657759705e-06 # B[1580, [51, 8, 0, 8], [51, 8, 0, 8]] + -0.000179079356204300821 # B[1581, [51, 8, 0, 8], [52, 8, 2, 8]] + -6.37205046857824975e-06 # B[1582, [51, 8, 0, 8], [53, 8, 4, 8]] + 5.20087282658288075e-05 # B[1583, [51, 8, 0, 8], [54, 8, 6, 8]] + 6.68015373273544988e-05 # B[1584, [51, 8, 0, 8], [55, 8, 8, 8]] + 0.00160592146390294661 # B[1585, [52, 8, 2, 8], [52, 8, 2, 8]] + 0.000454049229948232103 # B[1586, [52, 8, 2, 8], [53, 8, 4, 8]] + 0.00110675066334388339 # B[1587, [52, 8, 2, 8], [54, 8, 6, 8]] + -0.000191060465051852771 # B[1588, [52, 8, 2, 8], [55, 8, 8, 8]] + -0.000131765455753670314 # B[1589, [53, 8, 4, 8], [53, 8, 4, 8]] + -7.05704764431217685e-05 # B[1590, [53, 8, 4, 8], [54, 8, 6, 8]] + -1.82263105369812051e-05 # B[1591, [53, 8, 4, 8], [55, 8, 8, 8]] + -0.00032731873727259329 # B[1592, [54, 8, 6, 8], [54, 8, 6, 8]] + -0.000198178389384386089 # B[1593, [54, 8, 6, 8], [55, 8, 8, 8]] + -0.000136309758672861769 # B[1594, [55, 8, 8, 8], [55, 8, 8, 8]] + +# End of potential \ No newline at end of file diff --git a/potentials/C_Willman_PRB2022.quadratic.snapparam b/potentials/C_Willman_PRB2022.quadratic.snapparam new file mode 100644 index 0000000000..26dddf627d --- /dev/null +++ b/potentials/C_Willman_PRB2022.quadratic.snapparam @@ -0,0 +1,10 @@ + + # required + rcutfac 2.7 + twojmax 8 + + # optional + rfac0 0.99363 + rmin0 0.0 + bzeroflag 0 + quadraticflag 1 From bd9ea586a77f12af66584a9687f85f60015b15ee Mon Sep 17 00:00:00 2001 From: jwillma2 <52575231+jwillma2@users.noreply.github.com> Date: Tue, 21 Mar 2023 23:13:49 -0400 Subject: [PATCH 048/448] Delete C_Willman_PRB2022.quadratic.snapcoeff --- .../C_Willman_PRB2022.quadratic.snapcoeff | 1602 ----------------- 1 file changed, 1602 deletions(-) delete mode 100644 potentials/C_Willman_PRB2022.quadratic.snapcoeff diff --git a/potentials/C_Willman_PRB2022.quadratic.snapcoeff b/potentials/C_Willman_PRB2022.quadratic.snapcoeff deleted file mode 100644 index 4ef88ade03..0000000000 --- a/potentials/C_Willman_PRB2022.quadratic.snapcoeff +++ /dev/null @@ -1,1602 +0,0 @@ -# fitsnap fit generated on 2021-10-15 08:21:38.396384 - -1 1596 -C 0.5 1.0 - -2.7758927591660334 # B[0] - 0.00859216942217639126 # B[1, 0, 0, 0] - 0.16638458601459194 # B[2, 1, 0, 1] - 0.22261822339506554 # B[3, 1, 1, 2] - 0.257355166247009937 # B[4, 2, 0, 2] - 0.802105904460230779 # B[5, 2, 1, 3] - 0.227216469467176801 # B[6, 2, 2, 2] - 0.494646284119575508 # B[7, 2, 2, 4] - 0.276718638025069574 # B[8, 3, 0, 3] - 1.09101782892605392 # B[9, 3, 1, 4] - 0.775283725099378151 # B[10, 3, 2, 3] - -0.232869556477520168 # B[11, 3, 2, 5] - 0.188466708736270222 # B[12, 3, 3, 4] - -0.213463540195325957 # B[13, 3, 3, 6] - 0.285049005401720568 # B[14, 4, 0, 4] - -0.248039138369940321 # B[15, 4, 1, 5] - -0.017694405190132434 # B[16, 4, 2, 4] - -0.513770238875468355 # B[17, 4, 2, 6] - -0.603368424950793791 # B[18, 4, 3, 5] - -0.4245149972360448 # B[19, 4, 3, 7] - -0.149612637312833391 # B[20, 4, 4, 4] - -0.153415086019898006 # B[21, 4, 4, 6] - -0.14513624400298164 # B[22, 4, 4, 8] - -0.0460661393681677661 # B[23, 5, 0, 5] - -0.0512559726916635844 # B[24, 5, 1, 6] - -0.125285455697324882 # B[25, 5, 2, 5] - -0.297464016341802473 # B[26, 5, 2, 7] - -0.219930176940332595 # B[27, 5, 3, 6] - -0.195418601625407001 # B[28, 5, 3, 8] - -0.236454956825408069 # B[29, 5, 4, 5] - -0.247483318285177556 # B[30, 5, 4, 7] - 0.108404148378543994 # B[31, 5, 5, 6] - 0.102786344334006338 # B[32, 5, 5, 8] - -0.0174963987262215619 # B[33, 6, 0, 6] - -0.347663919737827065 # B[34, 6, 1, 7] - -0.308777238806140442 # B[35, 6, 2, 6] - -0.30366671620990171 # B[36, 6, 2, 8] - -0.190992135157848048 # B[37, 6, 3, 7] - -0.212717125362634818 # B[38, 6, 4, 6] - -0.127682310305149815 # B[39, 6, 4, 8] - 0.128955786755968027 # B[40, 6, 5, 7] - 0.108121871413745185 # B[41, 6, 6, 6] - 0.0951564970231452284 # B[42, 6, 6, 8] - -0.0443430969083889667 # B[43, 7, 0, 7] - 0.0394012265947801602 # B[44, 7, 1, 8] - 0.0238287662182333909 # B[45, 7, 2, 7] - -0.0703216614205220136 # B[46, 7, 3, 8] - -0.0229748587995626564 # B[47, 7, 4, 7] - 0.461615758896215367 # B[48, 7, 5, 8] - 0.032037855993324961 # B[49, 7, 6, 7] - 0.105399776101016598 # B[50, 7, 7, 8] - -0.0452778356788145764 # B[51, 8, 0, 8] - -0.0400452652333231421 # B[52, 8, 2, 8] - -0.152415456089667084 # B[53, 8, 4, 8] - 0.0303383368396002995 # B[54, 8, 6, 8] - 0.0660845112300222914 # B[55, 8, 8, 8] - 5.0022584003536763e-06 # B[55, [1, 0, 0, 0], [1, 0, 0, 0]] - 7.12434860521689133e-05 # B[56, [1, 0, 0, 0], [2, 1, 0, 1]] - 0.00410559459459784552 # B[57, [1, 0, 0, 0], [3, 1, 1, 2]] - -0.000152151102822628559 # B[58, [1, 0, 0, 0], [4, 2, 0, 2]] - -0.00104851962847402839 # B[59, [1, 0, 0, 0], [5, 2, 1, 3]] - 0.00174544590749468355 # B[60, [1, 0, 0, 0], [6, 2, 2, 2]] - -0.00039686396723943862 # B[61, [1, 0, 0, 0], [7, 2, 2, 4]] - 0.000344474173032960351 # B[62, [1, 0, 0, 0], [8, 3, 0, 3]] - 5.77832175303926235e-05 # B[63, [1, 0, 0, 0], [9, 3, 1, 4]] - 0.00124014860085090543 # B[64, [1, 0, 0, 0], [10, 3, 2, 3]] - 1.92520730655986946e-05 # B[65, [1, 0, 0, 0], [11, 3, 2, 5]] - -0.000659022869027497959 # B[66, [1, 0, 0, 0], [12, 3, 3, 4]] - -0.000296998157394604001 # B[67, [1, 0, 0, 0], [13, 3, 3, 6]] - 2.13348987737616014e-06 # B[68, [1, 0, 0, 0], [14, 4, 0, 4]] - -0.000377679899824956422 # B[69, [1, 0, 0, 0], [15, 4, 1, 5]] - 0.00045743496488695988 # B[70, [1, 0, 0, 0], [16, 4, 2, 4]] - -0.00047978616167941926 # B[71, [1, 0, 0, 0], [17, 4, 2, 6]] - -0.000346601408372410741 # B[72, [1, 0, 0, 0], [18, 4, 3, 5]] - -0.000216752459512900564 # B[73, [1, 0, 0, 0], [19, 4, 3, 7]] - -0.000153945954064437646 # B[74, [1, 0, 0, 0], [20, 4, 4, 4]] - 0.00029484781857681483 # B[75, [1, 0, 0, 0], [21, 4, 4, 6]] - 1.59236973873017051e-05 # B[76, [1, 0, 0, 0], [22, 4, 4, 8]] - -2.35544935613951623e-05 # B[77, [1, 0, 0, 0], [23, 5, 0, 5]] - 0.000492019807872501325 # B[78, [1, 0, 0, 0], [24, 5, 1, 6]] - 0.000376700986017126233 # B[79, [1, 0, 0, 0], [25, 5, 2, 5]] - -0.000185900021989794662 # B[80, [1, 0, 0, 0], [26, 5, 2, 7]] - 0.000219939447169378507 # B[81, [1, 0, 0, 0], [27, 5, 3, 6]] - -0.000192198129806066265 # B[82, [1, 0, 0, 0], [28, 5, 3, 8]] - 0.000175514531344928004 # B[83, [1, 0, 0, 0], [29, 5, 4, 5]] - 0.000261949015135925535 # B[84, [1, 0, 0, 0], [30, 5, 4, 7]] - 0.00021011408484750832 # B[85, [1, 0, 0, 0], [31, 5, 5, 6]] - -7.47807464450689352e-05 # B[86, [1, 0, 0, 0], [32, 5, 5, 8]] - -1.36809205491805752e-05 # B[87, [1, 0, 0, 0], [33, 6, 0, 6]] - 0.000493576806965066728 # B[88, [1, 0, 0, 0], [34, 6, 1, 7]] - 0.000216301405824667614 # B[89, [1, 0, 0, 0], [35, 6, 2, 6]] - -0.000364540437645548276 # B[90, [1, 0, 0, 0], [36, 6, 2, 8]] - -0.000251411532179113273 # B[91, [1, 0, 0, 0], [37, 6, 3, 7]] - 3.19331690196988927e-05 # B[92, [1, 0, 0, 0], [38, 6, 4, 6]] - -1.56092571080845843e-05 # B[93, [1, 0, 0, 0], [39, 6, 4, 8]] - 2.4859429830464963e-05 # B[94, [1, 0, 0, 0], [40, 6, 5, 7]] - -5.06306418207175257e-05 # B[95, [1, 0, 0, 0], [41, 6, 6, 6]] - -9.75742047871729079e-05 # B[96, [1, 0, 0, 0], [42, 6, 6, 8]] - -4.07774117821002591e-05 # B[97, [1, 0, 0, 0], [43, 7, 0, 7]] - 0.000169705539551909257 # B[98, [1, 0, 0, 0], [44, 7, 1, 8]] - 0.000261792097012429614 # B[99, [1, 0, 0, 0], [45, 7, 2, 7]] - 0.000235813389494382575 # B[100, [1, 0, 0, 0], [46, 7, 3, 8]] - 3.69194385055615637e-05 # B[101, [1, 0, 0, 0], [47, 7, 4, 7]] - 0.000101832840349036502 # B[102, [1, 0, 0, 0], [48, 7, 5, 8]] - 1.87768621704026417e-05 # B[103, [1, 0, 0, 0], [49, 7, 6, 7]] - 6.90123641682582889e-05 # B[104, [1, 0, 0, 0], [50, 7, 7, 8]] - 3.82281861928956967e-05 # B[105, [1, 0, 0, 0], [51, 8, 0, 8]] - 0.00044905358698343889 # B[106, [1, 0, 0, 0], [52, 8, 2, 8]] - 3.83170337754923374e-05 # B[107, [1, 0, 0, 0], [53, 8, 4, 8]] - -4.53472261485315942e-05 # B[108, [1, 0, 0, 0], [54, 8, 6, 8]] - -0.000105793544360549552 # B[109, [1, 0, 0, 0], [55, 8, 8, 8]] - -0.00542851209933992596 # B[110, [2, 1, 0, 1], [2, 1, 0, 1]] - -0.00800035055604917701 # B[111, [2, 1, 0, 1], [3, 1, 1, 2]] - 0.000279580761847972054 # B[112, [2, 1, 0, 1], [4, 2, 0, 2]] - -0.0132643544617690821 # B[113, [2, 1, 0, 1], [5, 2, 1, 3]] - -0.00300637860380324968 # B[114, [2, 1, 0, 1], [6, 2, 2, 2]] - 0.00343216933390476549 # B[115, [2, 1, 0, 1], [7, 2, 2, 4]] - 6.39026040622058672e-05 # B[116, [2, 1, 0, 1], [8, 3, 0, 3]] - -0.0124005148347727506 # B[117, [2, 1, 0, 1], [9, 3, 1, 4]] - -0.0036690465725984691 # B[118, [2, 1, 0, 1], [10, 3, 2, 3]] - -0.0066468850826254932 # B[119, [2, 1, 0, 1], [11, 3, 2, 5]] - -0.00518212543330048934 # B[120, [2, 1, 0, 1], [12, 3, 3, 4]] - -0.00269613907034030407 # B[121, [2, 1, 0, 1], [13, 3, 3, 6]] - -0.000330193583102013615 # B[122, [2, 1, 0, 1], [14, 4, 0, 4]] - -0.000429062486184235686 # B[123, [2, 1, 0, 1], [15, 4, 1, 5]] - -0.000991704717453613382 # B[124, [2, 1, 0, 1], [16, 4, 2, 4]] - 0.00152944521177345071 # B[125, [2, 1, 0, 1], [17, 4, 2, 6]] - -0.00660856033628089406 # B[126, [2, 1, 0, 1], [18, 4, 3, 5]] - 0.00146758746394204951 # B[127, [2, 1, 0, 1], [19, 4, 3, 7]] - -0.00161093753941019967 # B[128, [2, 1, 0, 1], [20, 4, 4, 4]] - -0.00101484284665418574 # B[129, [2, 1, 0, 1], [21, 4, 4, 6]] - 0.00150269420364470413 # B[130, [2, 1, 0, 1], [22, 4, 4, 8]] - -0.000251279508914979688 # B[131, [2, 1, 0, 1], [23, 5, 0, 5]] - 0.00427791921512100763 # B[132, [2, 1, 0, 1], [24, 5, 1, 6]] - -0.00312327633171666707 # B[133, [2, 1, 0, 1], [25, 5, 2, 5]] - 0.00145518956483171066 # B[134, [2, 1, 0, 1], [26, 5, 2, 7]] - -0.00296392629706135422 # B[135, [2, 1, 0, 1], [27, 5, 3, 6]] - 0.00106990236696331148 # B[136, [2, 1, 0, 1], [28, 5, 3, 8]] - 0.000140740776400729824 # B[137, [2, 1, 0, 1], [29, 5, 4, 5]] - -0.000704484148092703912 # B[138, [2, 1, 0, 1], [30, 5, 4, 7]] - 0.000555926138942124939 # B[139, [2, 1, 0, 1], [31, 5, 5, 6]] - 0.000749361142656781065 # B[140, [2, 1, 0, 1], [32, 5, 5, 8]] - -0.000275563231062828096 # B[141, [2, 1, 0, 1], [33, 6, 0, 6]] - 0.00404287546990938183 # B[142, [2, 1, 0, 1], [34, 6, 1, 7]] - -0.00329083016295819491 # B[143, [2, 1, 0, 1], [35, 6, 2, 6]] - 0.00374648670440783874 # B[144, [2, 1, 0, 1], [36, 6, 2, 8]] - -0.000931584323738718183 # B[145, [2, 1, 0, 1], [37, 6, 3, 7]] - 0.001545987588966576 # B[146, [2, 1, 0, 1], [38, 6, 4, 6]] - 0.000136630337825366203 # B[147, [2, 1, 0, 1], [39, 6, 4, 8]] - -0.000338191518470186761 # B[148, [2, 1, 0, 1], [40, 6, 5, 7]] - 0.000383732900037425575 # B[149, [2, 1, 0, 1], [41, 6, 6, 6]] - 0.000891911333988446714 # B[150, [2, 1, 0, 1], [42, 6, 6, 8]] - 0.000372325777048820861 # B[151, [2, 1, 0, 1], [43, 7, 0, 7]] - 0.00203975899324063559 # B[152, [2, 1, 0, 1], [44, 7, 1, 8]] - -0.00366168906366426058 # B[153, [2, 1, 0, 1], [45, 7, 2, 7]] - -0.00217927110231279971 # B[154, [2, 1, 0, 1], [46, 7, 3, 8]] - -0.000355180731966526532 # B[155, [2, 1, 0, 1], [47, 7, 4, 7]] - -0.00190295940654904624 # B[156, [2, 1, 0, 1], [48, 7, 5, 8]] - -0.00045640385432905474 # B[157, [2, 1, 0, 1], [49, 7, 6, 7]] - -0.00123273230096131864 # B[158, [2, 1, 0, 1], [50, 7, 7, 8]] - 2.61749541232737803e-06 # B[159, [2, 1, 0, 1], [51, 8, 0, 8]] - -0.00188736987570012403 # B[160, [2, 1, 0, 1], [52, 8, 2, 8]] - 0.000127235145614493401 # B[161, [2, 1, 0, 1], [53, 8, 4, 8]] - -0.000446185446234578786 # B[162, [2, 1, 0, 1], [54, 8, 6, 8]] - 3.06626149019382718e-05 # B[163, [2, 1, 0, 1], [55, 8, 8, 8]] - 0.00500803145405033512 # B[164, [3, 1, 1, 2], [3, 1, 1, 2]] - 0.0136537265129433767 # B[165, [3, 1, 1, 2], [4, 2, 0, 2]] - 0.00586793418015095231 # B[166, [3, 1, 1, 2], [5, 2, 1, 3]] - 0.0108897828563872673 # B[167, [3, 1, 1, 2], [6, 2, 2, 2]] - 0.000782326392446437181 # B[168, [3, 1, 1, 2], [7, 2, 2, 4]] - -0.00196905235294965193 # B[169, [3, 1, 1, 2], [8, 3, 0, 3]] - -0.00575620599927615263 # B[170, [3, 1, 1, 2], [9, 3, 1, 4]] - -0.0395084171352078836 # B[171, [3, 1, 1, 2], [10, 3, 2, 3]] - -0.0402914809330097226 # B[172, [3, 1, 1, 2], [11, 3, 2, 5]] - -0.031380925125560552 # B[173, [3, 1, 1, 2], [12, 3, 3, 4]] - 0.0074098991236085333 # B[174, [3, 1, 1, 2], [13, 3, 3, 6]] - -0.00144234945688183152 # B[175, [3, 1, 1, 2], [14, 4, 0, 4]] - -0.00715563010950572616 # B[176, [3, 1, 1, 2], [15, 4, 1, 5]] - -0.0068004389765142035 # B[177, [3, 1, 1, 2], [16, 4, 2, 4]] - -0.0397838555572563451 # B[178, [3, 1, 1, 2], [17, 4, 2, 6]] - 0.00335672059516798228 # B[179, [3, 1, 1, 2], [18, 4, 3, 5]] - 0.0148934683418572647 # B[180, [3, 1, 1, 2], [19, 4, 3, 7]] - -0.000967980016249102011 # B[181, [3, 1, 1, 2], [20, 4, 4, 4]] - 0.00772576295059950596 # B[182, [3, 1, 1, 2], [21, 4, 4, 6]] - -0.00450662666899595381 # B[183, [3, 1, 1, 2], [22, 4, 4, 8]] - -0.00395807515027411967 # B[184, [3, 1, 1, 2], [23, 5, 0, 5]] - 0.010414612350238486 # B[185, [3, 1, 1, 2], [24, 5, 1, 6]] - -0.00513372683983254804 # B[186, [3, 1, 1, 2], [25, 5, 2, 5]] - -0.0265398819124704963 # B[187, [3, 1, 1, 2], [26, 5, 2, 7]] - 0.00742434172938952544 # B[188, [3, 1, 1, 2], [27, 5, 3, 6]] - -0.00256386423704287481 # B[189, [3, 1, 1, 2], [28, 5, 3, 8]] - 0.00841179553194743718 # B[190, [3, 1, 1, 2], [29, 5, 4, 5]] - 0.00668617729586690451 # B[191, [3, 1, 1, 2], [30, 5, 4, 7]] - 0.000484464094046739568 # B[192, [3, 1, 1, 2], [31, 5, 5, 6]] - 0.00458460314168420216 # B[193, [3, 1, 1, 2], [32, 5, 5, 8]] - -0.00235318401641824212 # B[194, [3, 1, 1, 2], [33, 6, 0, 6]] - -0.000804392064641467762 # B[195, [3, 1, 1, 2], [34, 6, 1, 7]] - -0.000974349018272668323 # B[196, [3, 1, 1, 2], [35, 6, 2, 6]] - -0.0186467861443154748 # B[197, [3, 1, 1, 2], [36, 6, 2, 8]] - 0.0149394908128317495 # B[198, [3, 1, 1, 2], [37, 6, 3, 7]] - -0.001417773975968062 # B[199, [3, 1, 1, 2], [38, 6, 4, 6]] - 0.00708801668305296916 # B[200, [3, 1, 1, 2], [39, 6, 4, 8]] - 0.00422029817457212405 # B[201, [3, 1, 1, 2], [40, 6, 5, 7]] - 0.00110117813016081525 # B[202, [3, 1, 1, 2], [41, 6, 6, 6]] - -0.00187490884044745794 # B[203, [3, 1, 1, 2], [42, 6, 6, 8]] - -0.00530063898164105998 # B[204, [3, 1, 1, 2], [43, 7, 0, 7]] - 0.0156639815207892212 # B[205, [3, 1, 1, 2], [44, 7, 1, 8]] - 0.0118519420103458811 # B[206, [3, 1, 1, 2], [45, 7, 2, 7]] - 0.00375057568532275679 # B[207, [3, 1, 1, 2], [46, 7, 3, 8]] - 0.00757584350406629962 # B[208, [3, 1, 1, 2], [47, 7, 4, 7]] - 0.0106601777099339986 # B[209, [3, 1, 1, 2], [48, 7, 5, 8]] - -0.0041075690062942552 # B[210, [3, 1, 1, 2], [49, 7, 6, 7]] - 0.00248707997936048041 # B[211, [3, 1, 1, 2], [50, 7, 7, 8]] - -0.0025390217113529746 # B[212, [3, 1, 1, 2], [51, 8, 0, 8]] - 0.00498354453902482165 # B[213, [3, 1, 1, 2], [52, 8, 2, 8]] - 0.00383782774054214912 # B[214, [3, 1, 1, 2], [53, 8, 4, 8]] - 0.00318870204625110783 # B[215, [3, 1, 1, 2], [54, 8, 6, 8]] - -0.00078409267383599678 # B[216, [3, 1, 1, 2], [55, 8, 8, 8]] - 0.00411479420703600093 # B[217, [4, 2, 0, 2], [4, 2, 0, 2]] - -0.00352482696278418658 # B[218, [4, 2, 0, 2], [5, 2, 1, 3]] - 0.00293296373222708129 # B[219, [4, 2, 0, 2], [6, 2, 2, 2]] - -0.00169108240942662173 # B[220, [4, 2, 0, 2], [7, 2, 2, 4]] - -0.00166875839344953099 # B[221, [4, 2, 0, 2], [8, 3, 0, 3]] - -0.00303743189373234653 # B[222, [4, 2, 0, 2], [9, 3, 1, 4]] - -0.00360352002032471395 # B[223, [4, 2, 0, 2], [10, 3, 2, 3]] - -0.00844475258400314774 # B[224, [4, 2, 0, 2], [11, 3, 2, 5]] - -0.00267861760564082688 # B[225, [4, 2, 0, 2], [12, 3, 3, 4]] - 0.00249373694942188646 # B[226, [4, 2, 0, 2], [13, 3, 3, 6]] - 0.00129518789575956 # B[227, [4, 2, 0, 2], [14, 4, 0, 4]] - -0.000616706097657935626 # B[228, [4, 2, 0, 2], [15, 4, 1, 5]] - -0.00374793183827557257 # B[229, [4, 2, 0, 2], [16, 4, 2, 4]] - -0.00725453590077526286 # B[230, [4, 2, 0, 2], [17, 4, 2, 6]] - -0.00328165463874066426 # B[231, [4, 2, 0, 2], [18, 4, 3, 5]] - -0.00387910875571249565 # B[232, [4, 2, 0, 2], [19, 4, 3, 7]] - -0.000691443248665482221 # B[233, [4, 2, 0, 2], [20, 4, 4, 4]] - -0.00364575524119575139 # B[234, [4, 2, 0, 2], [21, 4, 4, 6]] - 0.000579213613942424974 # B[235, [4, 2, 0, 2], [22, 4, 4, 8]] - 0.000382530088889220486 # B[236, [4, 2, 0, 2], [23, 5, 0, 5]] - 0.000700082663528700608 # B[237, [4, 2, 0, 2], [24, 5, 1, 6]] - -0.00303645662419470708 # B[238, [4, 2, 0, 2], [25, 5, 2, 5]] - -0.00412449214914962191 # B[239, [4, 2, 0, 2], [26, 5, 2, 7]] - -0.000863747946010486305 # B[240, [4, 2, 0, 2], [27, 5, 3, 6]] - 0.000597171151136822748 # B[241, [4, 2, 0, 2], [28, 5, 3, 8]] - -0.00290482182317059953 # B[242, [4, 2, 0, 2], [29, 5, 4, 5]] - -0.00218615594313117554 # B[243, [4, 2, 0, 2], [30, 5, 4, 7]] - 0.00120270898159113111 # B[244, [4, 2, 0, 2], [31, 5, 5, 6]] - -0.000439562436330729364 # B[245, [4, 2, 0, 2], [32, 5, 5, 8]] - -0.000155002689849706443 # B[246, [4, 2, 0, 2], [33, 6, 0, 6]] - -0.00203784613220199399 # B[247, [4, 2, 0, 2], [34, 6, 1, 7]] - -0.00251933129878168221 # B[248, [4, 2, 0, 2], [35, 6, 2, 6]] - -0.00227857345941180406 # B[249, [4, 2, 0, 2], [36, 6, 2, 8]] - 0.00307391827986236085 # B[250, [4, 2, 0, 2], [37, 6, 3, 7]] - -0.000435707916552085118 # B[251, [4, 2, 0, 2], [38, 6, 4, 6]] - -0.00141960729594133419 # B[252, [4, 2, 0, 2], [39, 6, 4, 8]] - -0.000275734648504752638 # B[253, [4, 2, 0, 2], [40, 6, 5, 7]] - 0.000703286595409794617 # B[254, [4, 2, 0, 2], [41, 6, 6, 6]] - -5.55751922647368824e-05 # B[255, [4, 2, 0, 2], [42, 6, 6, 8]] - -0.000401816924228297345 # B[256, [4, 2, 0, 2], [43, 7, 0, 7]] - -0.000554714661495172429 # B[257, [4, 2, 0, 2], [44, 7, 1, 8]] - 0.00088244559527147267 # B[258, [4, 2, 0, 2], [45, 7, 2, 7]] - 0.000429487284537406104 # B[259, [4, 2, 0, 2], [46, 7, 3, 8]] - 0.000160720016534536374 # B[260, [4, 2, 0, 2], [47, 7, 4, 7]] - -0.000116046064898544729 # B[261, [4, 2, 0, 2], [48, 7, 5, 8]] - 0.00077812424584384446 # B[262, [4, 2, 0, 2], [49, 7, 6, 7]] - 0.0014223009786123353 # B[263, [4, 2, 0, 2], [50, 7, 7, 8]] - 5.45987148103492526e-05 # B[264, [4, 2, 0, 2], [51, 8, 0, 8]] - -0.00229888217343966316 # B[265, [4, 2, 0, 2], [52, 8, 2, 8]] - -0.00144376280980788169 # B[266, [4, 2, 0, 2], [53, 8, 4, 8]] - 0.000240138800657541986 # B[267, [4, 2, 0, 2], [54, 8, 6, 8]] - -4.09764373741731969e-05 # B[268, [4, 2, 0, 2], [55, 8, 8, 8]] - 0.0453826120189535706 # B[269, [5, 2, 1, 3], [5, 2, 1, 3]] - 0.00337080799390409615 # B[270, [5, 2, 1, 3], [6, 2, 2, 2]] - 0.0339316309546992961 # B[271, [5, 2, 1, 3], [7, 2, 2, 4]] - 0.00483677443671226039 # B[272, [5, 2, 1, 3], [8, 3, 0, 3]] - 0.00174954019608989774 # B[273, [5, 2, 1, 3], [9, 3, 1, 4]] - 0.00420306320210527603 # B[274, [5, 2, 1, 3], [10, 3, 2, 3]] - -0.0179939258962366969 # B[275, [5, 2, 1, 3], [11, 3, 2, 5]] - -0.01997198698308544 # B[276, [5, 2, 1, 3], [12, 3, 3, 4]] - -0.0136471344704570501 # B[277, [5, 2, 1, 3], [13, 3, 3, 6]] - -0.00203572867299816902 # B[278, [5, 2, 1, 3], [14, 4, 0, 4]] - 0.0113893698593142377 # B[279, [5, 2, 1, 3], [15, 4, 1, 5]] - -0.00283495847488346529 # B[280, [5, 2, 1, 3], [16, 4, 2, 4]] - -0.0209899506178404249 # B[281, [5, 2, 1, 3], [17, 4, 2, 6]] - 0.00307893999573658839 # B[282, [5, 2, 1, 3], [18, 4, 3, 5]] - 0.00625880909518397067 # B[283, [5, 2, 1, 3], [19, 4, 3, 7]] - 0.00109461945578659598 # B[284, [5, 2, 1, 3], [20, 4, 4, 4]] - 0.00213752786441095705 # B[285, [5, 2, 1, 3], [21, 4, 4, 6]] - -0.00379774849562602296 # B[286, [5, 2, 1, 3], [22, 4, 4, 8]] - -0.0013508169978871552 # B[287, [5, 2, 1, 3], [23, 5, 0, 5]] - 0.00921730935112183292 # B[288, [5, 2, 1, 3], [24, 5, 1, 6]] - -0.0029427132897584694 # B[289, [5, 2, 1, 3], [25, 5, 2, 5]] - 0.0013497580216050211 # B[290, [5, 2, 1, 3], [26, 5, 2, 7]] - -0.0130362734683665445 # B[291, [5, 2, 1, 3], [27, 5, 3, 6]] - 0.000858369129835153365 # B[292, [5, 2, 1, 3], [28, 5, 3, 8]] - 0.0129288669947052737 # B[293, [5, 2, 1, 3], [29, 5, 4, 5]] - -0.00373719468786774291 # B[294, [5, 2, 1, 3], [30, 5, 4, 7]] - -0.00885030928727506203 # B[295, [5, 2, 1, 3], [31, 5, 5, 6]] - 0.00285083482960970039 # B[296, [5, 2, 1, 3], [32, 5, 5, 8]] - 0.00351819863542377799 # B[297, [5, 2, 1, 3], [33, 6, 0, 6]] - -0.00783526064954031404 # B[298, [5, 2, 1, 3], [34, 6, 1, 7]] - -0.00257460837433342703 # B[299, [5, 2, 1, 3], [35, 6, 2, 6]] - -0.00421680657028429638 # B[300, [5, 2, 1, 3], [36, 6, 2, 8]] - -0.00918753516813325399 # B[301, [5, 2, 1, 3], [37, 6, 3, 7]] - -0.00316878171100497871 # B[302, [5, 2, 1, 3], [38, 6, 4, 6]] - 0.000939804682159322766 # B[303, [5, 2, 1, 3], [39, 6, 4, 8]] - -0.00618801787900946643 # B[304, [5, 2, 1, 3], [40, 6, 5, 7]] - -0.00623545765495540482 # B[305, [5, 2, 1, 3], [41, 6, 6, 6]] - 0.00519552954815065936 # B[306, [5, 2, 1, 3], [42, 6, 6, 8]] - 0.0042213652228506697 # B[307, [5, 2, 1, 3], [43, 7, 0, 7]] - 0.0113944611011103838 # B[308, [5, 2, 1, 3], [44, 7, 1, 8]] - -0.00104197865751114085 # B[309, [5, 2, 1, 3], [45, 7, 2, 7]] - -0.0087446191630695079 # B[310, [5, 2, 1, 3], [46, 7, 3, 8]] - -0.00196327596558909696 # B[311, [5, 2, 1, 3], [47, 7, 4, 7]] - -0.00447686867642808298 # B[312, [5, 2, 1, 3], [48, 7, 5, 8]] - -0.00474469665733750351 # B[313, [5, 2, 1, 3], [49, 7, 6, 7]] - -0.0059004868061462868 # B[314, [5, 2, 1, 3], [50, 7, 7, 8]] - 2.22874717926892923e-05 # B[315, [5, 2, 1, 3], [51, 8, 0, 8]] - -0.00154741089157206784 # B[316, [5, 2, 1, 3], [52, 8, 2, 8]] - 0.00417852330669051582 # B[317, [5, 2, 1, 3], [53, 8, 4, 8]] - 0.00134060860138395356 # B[318, [5, 2, 1, 3], [54, 8, 6, 8]] - -4.29219459423162489e-05 # B[319, [5, 2, 1, 3], [55, 8, 8, 8]] - 0.000319124100064731785 # B[320, [6, 2, 2, 2], [6, 2, 2, 2]] - -0.00839561599135440172 # B[321, [6, 2, 2, 2], [7, 2, 2, 4]] - -0.00326195850510992494 # B[322, [6, 2, 2, 2], [8, 3, 0, 3]] - 0.0194547426296311776 # B[323, [6, 2, 2, 2], [9, 3, 1, 4]] - -0.020516093722439413 # B[324, [6, 2, 2, 2], [10, 3, 2, 3]] - -0.00901624473884381043 # B[325, [6, 2, 2, 2], [11, 3, 2, 5]] - 0.0129026669830971837 # B[326, [6, 2, 2, 2], [12, 3, 3, 4]] - 0.00463182910296210636 # B[327, [6, 2, 2, 2], [13, 3, 3, 6]] - -0.00261498466108737743 # B[328, [6, 2, 2, 2], [14, 4, 0, 4]] - 0.0215819608660451426 # B[329, [6, 2, 2, 2], [15, 4, 1, 5]] - 0.000767688854520869957 # B[330, [6, 2, 2, 2], [16, 4, 2, 4]] - -0.00666111439578009716 # B[331, [6, 2, 2, 2], [17, 4, 2, 6]] - 0.0112705725443772303 # B[332, [6, 2, 2, 2], [18, 4, 3, 5]] - 0.00228839615631495127 # B[333, [6, 2, 2, 2], [19, 4, 3, 7]] - 0.00124148748415313414 # B[334, [6, 2, 2, 2], [20, 4, 4, 4]] - 0.00353391028977510834 # B[335, [6, 2, 2, 2], [21, 4, 4, 6]] - -0.00310464569903003834 # B[336, [6, 2, 2, 2], [22, 4, 4, 8]] - -0.001770681064288395 # B[337, [6, 2, 2, 2], [23, 5, 0, 5]] - 0.000554784469018851215 # B[338, [6, 2, 2, 2], [24, 5, 1, 6]] - -0.000102008183116791319 # B[339, [6, 2, 2, 2], [25, 5, 2, 5]] - -0.00128750706249572758 # B[340, [6, 2, 2, 2], [26, 5, 2, 7]] - 0.0046490656013451568 # B[341, [6, 2, 2, 2], [27, 5, 3, 6]] - 0.0034506831073765681 # B[342, [6, 2, 2, 2], [28, 5, 3, 8]] - 0.00501652811902741046 # B[343, [6, 2, 2, 2], [29, 5, 4, 5]] - -1.88389891915279224e-05 # B[344, [6, 2, 2, 2], [30, 5, 4, 7]] - -0.00246586719805504942 # B[345, [6, 2, 2, 2], [31, 5, 5, 6]] - -0.00339629261051872756 # B[346, [6, 2, 2, 2], [32, 5, 5, 8]] - -1.22729584505151552e-05 # B[347, [6, 2, 2, 2], [33, 6, 0, 6]] - -0.0055646406349652653 # B[348, [6, 2, 2, 2], [34, 6, 1, 7]] - 0.00216606634250279383 # B[349, [6, 2, 2, 2], [35, 6, 2, 6]] - -0.000140725603696151627 # B[350, [6, 2, 2, 2], [36, 6, 2, 8]] - -0.01190136261487338 # B[351, [6, 2, 2, 2], [37, 6, 3, 7]] - -0.000996588010308921109 # B[352, [6, 2, 2, 2], [38, 6, 4, 6]] - -0.0040124728576705895 # B[353, [6, 2, 2, 2], [39, 6, 4, 8]] - 0.000422679331586792552 # B[354, [6, 2, 2, 2], [40, 6, 5, 7]] - 0.000548939662545001959 # B[355, [6, 2, 2, 2], [41, 6, 6, 6]] - 0.00256895119228900404 # B[356, [6, 2, 2, 2], [42, 6, 6, 8]] - -0.000615139781019174688 # B[357, [6, 2, 2, 2], [43, 7, 0, 7]] - -0.00404941774617198578 # B[358, [6, 2, 2, 2], [44, 7, 1, 8]] - 0.00466754848324051064 # B[359, [6, 2, 2, 2], [45, 7, 2, 7]] - 0.00150461796185176488 # B[360, [6, 2, 2, 2], [46, 7, 3, 8]] - 0.0037489054114537468 # B[361, [6, 2, 2, 2], [47, 7, 4, 7]] - 0.00285804436398595782 # B[362, [6, 2, 2, 2], [48, 7, 5, 8]] - -0.00287521518361254919 # B[363, [6, 2, 2, 2], [49, 7, 6, 7]] - 0.000969520968104660755 # B[364, [6, 2, 2, 2], [50, 7, 7, 8]] - -0.000716125857042927043 # B[365, [6, 2, 2, 2], [51, 8, 0, 8]] - -0.00157385185114507437 # B[366, [6, 2, 2, 2], [52, 8, 2, 8]] - 0.002689243736875038 # B[367, [6, 2, 2, 2], [53, 8, 4, 8]] - -0.000661038690452418623 # B[368, [6, 2, 2, 2], [54, 8, 6, 8]] - 0.00157186481624649321 # B[369, [6, 2, 2, 2], [55, 8, 8, 8]] - -0.0134601349926017494 # B[370, [7, 2, 2, 4], [7, 2, 2, 4]] - -0.000918558149715113011 # B[371, [7, 2, 2, 4], [8, 3, 0, 3]] - -0.00377418701166061087 # B[372, [7, 2, 2, 4], [9, 3, 1, 4]] - 0.0148168734486278948 # B[373, [7, 2, 2, 4], [10, 3, 2, 3]] - -0.00535328606426562371 # B[374, [7, 2, 2, 4], [11, 3, 2, 5]] - 0.00804271469408427385 # B[375, [7, 2, 2, 4], [12, 3, 3, 4]] - 0.00136329663181449737 # B[376, [7, 2, 2, 4], [13, 3, 3, 6]] - 0.000218608555253111195 # B[377, [7, 2, 2, 4], [14, 4, 0, 4]] - 0.00767165886258287799 # B[378, [7, 2, 2, 4], [15, 4, 1, 5]] - -0.0022580429604385833 # B[379, [7, 2, 2, 4], [16, 4, 2, 4]] - -0.0050991924246220309 # B[380, [7, 2, 2, 4], [17, 4, 2, 6]] - -0.00308509180848093572 # B[381, [7, 2, 2, 4], [18, 4, 3, 5]] - -0.000900097231895549623 # B[382, [7, 2, 2, 4], [19, 4, 3, 7]] - -0.0063557020842957869 # B[383, [7, 2, 2, 4], [20, 4, 4, 4]] - -0.000409569358807882096 # B[384, [7, 2, 2, 4], [21, 4, 4, 6]] - 0.00254581400782049119 # B[385, [7, 2, 2, 4], [22, 4, 4, 8]] - 0.000657951401298526029 # B[386, [7, 2, 2, 4], [23, 5, 0, 5]] - -0.00940269729352927013 # B[387, [7, 2, 2, 4], [24, 5, 1, 6]] - 0.00333566383730494239 # B[388, [7, 2, 2, 4], [25, 5, 2, 5]] - 0.00896493308698088215 # B[389, [7, 2, 2, 4], [26, 5, 2, 7]] - 0.00132812590751918685 # B[390, [7, 2, 2, 4], [27, 5, 3, 6]] - -0.00127282140780485189 # B[391, [7, 2, 2, 4], [28, 5, 3, 8]] - -0.00435358176352772068 # B[392, [7, 2, 2, 4], [29, 5, 4, 5]] - -0.00226566527245459885 # B[393, [7, 2, 2, 4], [30, 5, 4, 7]] - 0.00326597657188156627 # B[394, [7, 2, 2, 4], [31, 5, 5, 6]] - -0.00247993076825692074 # B[395, [7, 2, 2, 4], [32, 5, 5, 8]] - -0.00138012806761597748 # B[396, [7, 2, 2, 4], [33, 6, 0, 6]] - -0.00296559266178312566 # B[397, [7, 2, 2, 4], [34, 6, 1, 7]] - -0.00345134318647404535 # B[398, [7, 2, 2, 4], [35, 6, 2, 6]] - 0.00604122282441024554 # B[399, [7, 2, 2, 4], [36, 6, 2, 8]] - -0.00602530276328681197 # B[400, [7, 2, 2, 4], [37, 6, 3, 7]] - 0.00113230868581531974 # B[401, [7, 2, 2, 4], [38, 6, 4, 6]] - 0.00132069580529702024 # B[402, [7, 2, 2, 4], [39, 6, 4, 8]] - -0.00355708848499901743 # B[403, [7, 2, 2, 4], [40, 6, 5, 7]] - 0.00103954578232134899 # B[404, [7, 2, 2, 4], [41, 6, 6, 6]] - 0.00138660655783935638 # B[405, [7, 2, 2, 4], [42, 6, 6, 8]] - 0.00122312383058832339 # B[406, [7, 2, 2, 4], [43, 7, 0, 7]] - 0.00122422070912251465 # B[407, [7, 2, 2, 4], [44, 7, 1, 8]] - -0.00497379521097694472 # B[408, [7, 2, 2, 4], [45, 7, 2, 7]] - -0.00811974704425355749 # B[409, [7, 2, 2, 4], [46, 7, 3, 8]] - 0.00114732010903773659 # B[410, [7, 2, 2, 4], [47, 7, 4, 7]] - -0.00569074628354063975 # B[411, [7, 2, 2, 4], [48, 7, 5, 8]] - 0.00235624642317577588 # B[412, [7, 2, 2, 4], [49, 7, 6, 7]] - 7.98437182146268919e-05 # B[413, [7, 2, 2, 4], [50, 7, 7, 8]] - 0.00113891921332402897 # B[414, [7, 2, 2, 4], [51, 8, 0, 8]] - -0.00492469555442132112 # B[415, [7, 2, 2, 4], [52, 8, 2, 8]] - 0.000792980352556455804 # B[416, [7, 2, 2, 4], [53, 8, 4, 8]] - 0.00153854887229367375 # B[417, [7, 2, 2, 4], [54, 8, 6, 8]] - -0.000881221748445243022 # B[418, [7, 2, 2, 4], [55, 8, 8, 8]] - -0.00136471788502227735 # B[419, [8, 3, 0, 3], [8, 3, 0, 3]] - 0.00246251727263488776 # B[420, [8, 3, 0, 3], [9, 3, 1, 4]] - 0.000996613519267240677 # B[421, [8, 3, 0, 3], [10, 3, 2, 3]] - -0.00207976146372090831 # B[422, [8, 3, 0, 3], [11, 3, 2, 5]] - -9.97509064182486305e-05 # B[423, [8, 3, 0, 3], [12, 3, 3, 4]] - 0.000656935135924852087 # B[424, [8, 3, 0, 3], [13, 3, 3, 6]] - -0.000492474229225159377 # B[425, [8, 3, 0, 3], [14, 4, 0, 4]] - 0.0032189163248994351 # B[426, [8, 3, 0, 3], [15, 4, 1, 5]] - -0.00115555104609991501 # B[427, [8, 3, 0, 3], [16, 4, 2, 4]] - -0.000101151026370576574 # B[428, [8, 3, 0, 3], [17, 4, 2, 6]] - 0.00020301152740384229 # B[429, [8, 3, 0, 3], [18, 4, 3, 5]] - -0.000285445107860462371 # B[430, [8, 3, 0, 3], [19, 4, 3, 7]] - 0.000462665925556146607 # B[431, [8, 3, 0, 3], [20, 4, 4, 4]] - -2.75652763320703015e-05 # B[432, [8, 3, 0, 3], [21, 4, 4, 6]] - -0.000358778647317398169 # B[433, [8, 3, 0, 3], [22, 4, 4, 8]] - -0.000397176131748222527 # B[434, [8, 3, 0, 3], [23, 5, 0, 5]] - -0.00026950177456114624 # B[435, [8, 3, 0, 3], [24, 5, 1, 6]] - 0.00119424632084062527 # B[436, [8, 3, 0, 3], [25, 5, 2, 5]] - 0.000922347152199163439 # B[437, [8, 3, 0, 3], [26, 5, 2, 7]] - -0.000340838509282952173 # B[438, [8, 3, 0, 3], [27, 5, 3, 6]] - 0.00128847730890532808 # B[439, [8, 3, 0, 3], [28, 5, 3, 8]] - -0.00044582191494569115 # B[440, [8, 3, 0, 3], [29, 5, 4, 5]] - -0.00114898350718379422 # B[441, [8, 3, 0, 3], [30, 5, 4, 7]] - -0.000530499767100067743 # B[442, [8, 3, 0, 3], [31, 5, 5, 6]] - 1.68864176486992895e-05 # B[443, [8, 3, 0, 3], [32, 5, 5, 8]] - -0.000312292146951373417 # B[444, [8, 3, 0, 3], [33, 6, 0, 6]] - -0.00186273440079770883 # B[445, [8, 3, 0, 3], [34, 6, 1, 7]] - -0.000475625961442131123 # B[446, [8, 3, 0, 3], [35, 6, 2, 6]] - 0.000505090975521763769 # B[447, [8, 3, 0, 3], [36, 6, 2, 8]] - 0.000128630083375533277 # B[448, [8, 3, 0, 3], [37, 6, 3, 7]] - -0.000431369283499544176 # B[449, [8, 3, 0, 3], [38, 6, 4, 6]] - 0.000461881443708941908 # B[450, [8, 3, 0, 3], [39, 6, 4, 8]] - 0.000867550860200114182 # B[451, [8, 3, 0, 3], [40, 6, 5, 7]] - 0.000179604539903628624 # B[452, [8, 3, 0, 3], [41, 6, 6, 6]] - -0.000405383988192370426 # B[453, [8, 3, 0, 3], [42, 6, 6, 8]] - -0.000305572243426546764 # B[454, [8, 3, 0, 3], [43, 7, 0, 7]] - -0.0010766931736053021 # B[455, [8, 3, 0, 3], [44, 7, 1, 8]] - 0.000701859051866787764 # B[456, [8, 3, 0, 3], [45, 7, 2, 7]] - -1.5413662061584954e-05 # B[457, [8, 3, 0, 3], [46, 7, 3, 8]] - 0.000428834666348756888 # B[458, [8, 3, 0, 3], [47, 7, 4, 7]] - 0.000468098667731533385 # B[459, [8, 3, 0, 3], [48, 7, 5, 8]] - 0.000158467988956009775 # B[460, [8, 3, 0, 3], [49, 7, 6, 7]] - 2.77948419442784408e-05 # B[461, [8, 3, 0, 3], [50, 7, 7, 8]] - -0.000282655955044820717 # B[462, [8, 3, 0, 3], [51, 8, 0, 8]] - 0.000100300940760145348 # B[463, [8, 3, 0, 3], [52, 8, 2, 8]] - 0.000314947671131902973 # B[464, [8, 3, 0, 3], [53, 8, 4, 8]] - 0.000144842823919437078 # B[465, [8, 3, 0, 3], [54, 8, 6, 8]] - 7.00050428864840146e-05 # B[466, [8, 3, 0, 3], [55, 8, 8, 8]] - 0.0118411448561217512 # B[467, [9, 3, 1, 4], [9, 3, 1, 4]] - 0.0158809314732707603 # B[468, [9, 3, 1, 4], [10, 3, 2, 3]] - -0.00690506493475962109 # B[469, [9, 3, 1, 4], [11, 3, 2, 5]] - 0.0085626937099196887 # B[470, [9, 3, 1, 4], [12, 3, 3, 4]] - -0.00387686964925252654 # B[471, [9, 3, 1, 4], [13, 3, 3, 6]] - 0.00015029200549142481 # B[472, [9, 3, 1, 4], [14, 4, 0, 4]] - -0.000142532963490632015 # B[473, [9, 3, 1, 4], [15, 4, 1, 5]] - 0.00921427022949583042 # B[474, [9, 3, 1, 4], [16, 4, 2, 4]] - -0.0112717231196791407 # B[475, [9, 3, 1, 4], [17, 4, 2, 6]] - -0.0122014182952103704 # B[476, [9, 3, 1, 4], [18, 4, 3, 5]] - -0.0111571557686284996 # B[477, [9, 3, 1, 4], [19, 4, 3, 7]] - -0.00276180055211498916 # B[478, [9, 3, 1, 4], [20, 4, 4, 4]] - -0.00444456405006457382 # B[479, [9, 3, 1, 4], [21, 4, 4, 6]] - -0.00248162623330630983 # B[480, [9, 3, 1, 4], [22, 4, 4, 8]] - 0.000238830840202226575 # B[481, [9, 3, 1, 4], [23, 5, 0, 5]] - 0.0106883008114137777 # B[482, [9, 3, 1, 4], [24, 5, 1, 6]] - -0.00176293319638371826 # B[483, [9, 3, 1, 4], [25, 5, 2, 5]] - -0.000706186990249144109 # B[484, [9, 3, 1, 4], [26, 5, 2, 7]] - -0.000957413082652629373 # B[485, [9, 3, 1, 4], [27, 5, 3, 6]] - -0.00485998335666546887 # B[486, [9, 3, 1, 4], [28, 5, 3, 8]] - -0.000739967956913101287 # B[487, [9, 3, 1, 4], [29, 5, 4, 5]] - -0.00656002591947351353 # B[488, [9, 3, 1, 4], [30, 5, 4, 7]] - -0.00191607250770065712 # B[489, [9, 3, 1, 4], [31, 5, 5, 6]] - -0.000375150046930213714 # B[490, [9, 3, 1, 4], [32, 5, 5, 8]] - 0.000379540253919751804 # B[491, [9, 3, 1, 4], [33, 6, 0, 6]] - 0.0103809997405371179 # B[492, [9, 3, 1, 4], [34, 6, 1, 7]] - -0.00167937900508645203 # B[493, [9, 3, 1, 4], [35, 6, 2, 6]] - -0.000942453027264282192 # B[494, [9, 3, 1, 4], [36, 6, 2, 8]] - -0.00358794660355351257 # B[495, [9, 3, 1, 4], [37, 6, 3, 7]] - 0.00367542903060237222 # B[496, [9, 3, 1, 4], [38, 6, 4, 6]] - -0.00605874518215254298 # B[497, [9, 3, 1, 4], [39, 6, 4, 8]] - -0.0053364107721741022 # B[498, [9, 3, 1, 4], [40, 6, 5, 7]] - -0.00220303686176452889 # B[499, [9, 3, 1, 4], [41, 6, 6, 6]] - 0.000240224733534942676 # B[500, [9, 3, 1, 4], [42, 6, 6, 8]] - 0.00118204722287629585 # B[501, [9, 3, 1, 4], [43, 7, 0, 7]] - 0.00391606544218769514 # B[502, [9, 3, 1, 4], [44, 7, 1, 8]] - -0.00190557542057654024 # B[503, [9, 3, 1, 4], [45, 7, 2, 7]] - -0.0010749256928406746 # B[504, [9, 3, 1, 4], [46, 7, 3, 8]] - 6.24186835188134462e-05 # B[505, [9, 3, 1, 4], [47, 7, 4, 7]] - -0.00250872188348977114 # B[506, [9, 3, 1, 4], [48, 7, 5, 8]] - -0.00164710314956706405 # B[507, [9, 3, 1, 4], [49, 7, 6, 7]] - -0.0029144992153610676 # B[508, [9, 3, 1, 4], [50, 7, 7, 8]] - 0.000712015267242259442 # B[509, [9, 3, 1, 4], [51, 8, 0, 8]] - -0.00179539873092394715 # B[510, [9, 3, 1, 4], [52, 8, 2, 8]] - 0.00203000698298521493 # B[511, [9, 3, 1, 4], [53, 8, 4, 8]] - -0.00103477100047664442 # B[512, [9, 3, 1, 4], [54, 8, 6, 8]] - -0.000727628763147338854 # B[513, [9, 3, 1, 4], [55, 8, 8, 8]] - 0.0163451466486591972 # B[514, [10, 3, 2, 3], [10, 3, 2, 3]] - -0.00145259448176927441 # B[515, [10, 3, 2, 3], [11, 3, 2, 5]] - -0.00808947571520425568 # B[516, [10, 3, 2, 3], [12, 3, 3, 4]] - -0.00693599935022420205 # B[517, [10, 3, 2, 3], [13, 3, 3, 6]] - -0.00419683318703741731 # B[518, [10, 3, 2, 3], [14, 4, 0, 4]] - 0.00927666204585274323 # B[519, [10, 3, 2, 3], [15, 4, 1, 5]] - -0.0138962541759877663 # B[520, [10, 3, 2, 3], [16, 4, 2, 4]] - 0.0115061801390417759 # B[521, [10, 3, 2, 3], [17, 4, 2, 6]] - 0.0118559077356181798 # B[522, [10, 3, 2, 3], [18, 4, 3, 5]] - 0.00193270595871023604 # B[523, [10, 3, 2, 3], [19, 4, 3, 7]] - 0.00156708209719190472 # B[524, [10, 3, 2, 3], [20, 4, 4, 4]] - 0.0030286948486105119 # B[525, [10, 3, 2, 3], [21, 4, 4, 6]] - -6.03736466163237034e-05 # B[526, [10, 3, 2, 3], [22, 4, 4, 8]] - -0.00147218391304548835 # B[527, [10, 3, 2, 3], [23, 5, 0, 5]] - 0.000931966019926808685 # B[528, [10, 3, 2, 3], [24, 5, 1, 6]] - 0.0153667638164197012 # B[529, [10, 3, 2, 3], [25, 5, 2, 5]] - -0.0023105273691670326 # B[530, [10, 3, 2, 3], [26, 5, 2, 7]] - 0.0018873267014898696 # B[531, [10, 3, 2, 3], [27, 5, 3, 6]] - -0.00221592978134090707 # B[532, [10, 3, 2, 3], [28, 5, 3, 8]] - 0.00175823978838723916 # B[533, [10, 3, 2, 3], [29, 5, 4, 5]] - 0.00134986143361107494 # B[534, [10, 3, 2, 3], [30, 5, 4, 7]] - -0.00280444330034939227 # B[535, [10, 3, 2, 3], [31, 5, 5, 6]] - -0.000446159575940244073 # B[536, [10, 3, 2, 3], [32, 5, 5, 8]] - 0.000126573802730074736 # B[537, [10, 3, 2, 3], [33, 6, 0, 6]] - 7.95217271451070795e-05 # B[538, [10, 3, 2, 3], [34, 6, 1, 7]] - -0.000615992203402992468 # B[539, [10, 3, 2, 3], [35, 6, 2, 6]] - -0.0106304231235931409 # B[540, [10, 3, 2, 3], [36, 6, 2, 8]] - -0.00513102234934090934 # B[541, [10, 3, 2, 3], [37, 6, 3, 7]] - 0.00086364506858761271 # B[542, [10, 3, 2, 3], [38, 6, 4, 6]] - -0.00427816275089007263 # B[543, [10, 3, 2, 3], [39, 6, 4, 8]] - -0.00709876751806875171 # B[544, [10, 3, 2, 3], [40, 6, 5, 7]] - -0.00107679083671011894 # B[545, [10, 3, 2, 3], [41, 6, 6, 6]] - -0.0014022801302571164 # B[546, [10, 3, 2, 3], [42, 6, 6, 8]] - 0.00032001340322446864 # B[547, [10, 3, 2, 3], [43, 7, 0, 7]] - 0.0099494513037338677 # B[548, [10, 3, 2, 3], [44, 7, 1, 8]] - 0.00657164457459321564 # B[549, [10, 3, 2, 3], [45, 7, 2, 7]] - -0.00193909086513409032 # B[550, [10, 3, 2, 3], [46, 7, 3, 8]] - -0.000661327911070458407 # B[551, [10, 3, 2, 3], [47, 7, 4, 7]] - -0.00236609840279333045 # B[552, [10, 3, 2, 3], [48, 7, 5, 8]] - 0.000323126961361372422 # B[553, [10, 3, 2, 3], [49, 7, 6, 7]] - 0.00156411007472663857 # B[554, [10, 3, 2, 3], [50, 7, 7, 8]] - -0.000413410696562647312 # B[555, [10, 3, 2, 3], [51, 8, 0, 8]] - 0.00151556635054790959 # B[556, [10, 3, 2, 3], [52, 8, 2, 8]] - 0.0032252808357782943 # B[557, [10, 3, 2, 3], [53, 8, 4, 8]] - 0.00431814581620697767 # B[558, [10, 3, 2, 3], [54, 8, 6, 8]] - 0.000198535493268348594 # B[559, [10, 3, 2, 3], [55, 8, 8, 8]] - 0.0156540432654675432 # B[560, [11, 3, 2, 5], [11, 3, 2, 5]] - 0.00979845476873780416 # B[561, [11, 3, 2, 5], [12, 3, 3, 4]] - 0.00873265456764509701 # B[562, [11, 3, 2, 5], [13, 3, 3, 6]] - -0.00355250352643814854 # B[563, [11, 3, 2, 5], [14, 4, 0, 4]] - 0.0197388975583387243 # B[564, [11, 3, 2, 5], [15, 4, 1, 5]] - 0.0158965586216084157 # B[565, [11, 3, 2, 5], [16, 4, 2, 4]] - 0.0126440348146513917 # B[566, [11, 3, 2, 5], [17, 4, 2, 6]] - 0.00588822462217037865 # B[567, [11, 3, 2, 5], [18, 4, 3, 5]] - 0.00465829809814364074 # B[568, [11, 3, 2, 5], [19, 4, 3, 7]] - 0.00460100330976275125 # B[569, [11, 3, 2, 5], [20, 4, 4, 4]] - 0.00507979510261629894 # B[570, [11, 3, 2, 5], [21, 4, 4, 6]] - -0.000978147842247499566 # B[571, [11, 3, 2, 5], [22, 4, 4, 8]] - 0.000175648698607325238 # B[572, [11, 3, 2, 5], [23, 5, 0, 5]] - 0.00701365729786882983 # B[573, [11, 3, 2, 5], [24, 5, 1, 6]] - 0.0124121871279893672 # B[574, [11, 3, 2, 5], [25, 5, 2, 5]] - 0.0133268604743271169 # B[575, [11, 3, 2, 5], [26, 5, 2, 7]] - -0.00306906262974302943 # B[576, [11, 3, 2, 5], [27, 5, 3, 6]] - 0.00411586711144847073 # B[577, [11, 3, 2, 5], [28, 5, 3, 8]] - -0.00483702208096517539 # B[578, [11, 3, 2, 5], [29, 5, 4, 5]] - 0.000232830853394127776 # B[579, [11, 3, 2, 5], [30, 5, 4, 7]] - -0.00500644765401524715 # B[580, [11, 3, 2, 5], [31, 5, 5, 6]] - -0.000732991087538808345 # B[581, [11, 3, 2, 5], [32, 5, 5, 8]] - 0.0028290195015726223 # B[582, [11, 3, 2, 5], [33, 6, 0, 6]] - 0.000660043236562475252 # B[583, [11, 3, 2, 5], [34, 6, 1, 7]] - 0.00858014820620479901 # B[584, [11, 3, 2, 5], [35, 6, 2, 6]] - 0.00979420830127970127 # B[585, [11, 3, 2, 5], [36, 6, 2, 8]] - -0.00276929529868128257 # B[586, [11, 3, 2, 5], [37, 6, 3, 7]] - -0.00462592209123751513 # B[587, [11, 3, 2, 5], [38, 6, 4, 6]] - 0.000957159367659247626 # B[588, [11, 3, 2, 5], [39, 6, 4, 8]] - -0.00289923459154850169 # B[589, [11, 3, 2, 5], [40, 6, 5, 7]] - -0.00605668820795574915 # B[590, [11, 3, 2, 5], [41, 6, 6, 6]] - -0.00571070540762017888 # B[591, [11, 3, 2, 5], [42, 6, 6, 8]] - 0.00247733408975375075 # B[592, [11, 3, 2, 5], [43, 7, 0, 7]] - 0.00452000165177812024 # B[593, [11, 3, 2, 5], [44, 7, 1, 8]] - 0.00267833963693382693 # B[594, [11, 3, 2, 5], [45, 7, 2, 7]] - -0.00558917145621175976 # B[595, [11, 3, 2, 5], [46, 7, 3, 8]] - -0.00228097422335522999 # B[596, [11, 3, 2, 5], [47, 7, 4, 7]] - -0.00366604043706369575 # B[597, [11, 3, 2, 5], [48, 7, 5, 8]] - -0.00340088281218112534 # B[598, [11, 3, 2, 5], [49, 7, 6, 7]] - -0.00355022426643257852 # B[599, [11, 3, 2, 5], [50, 7, 7, 8]] - 0.00124080314205340242 # B[600, [11, 3, 2, 5], [51, 8, 0, 8]] - 0.00287261267197001097 # B[601, [11, 3, 2, 5], [52, 8, 2, 8]] - 0.000744815191487350516 # B[602, [11, 3, 2, 5], [53, 8, 4, 8]] - -0.000112288931147085103 # B[603, [11, 3, 2, 5], [54, 8, 6, 8]] - -0.000128712309023326903 # B[604, [11, 3, 2, 5], [55, 8, 8, 8]] - -0.00238666366477884723 # B[605, [12, 3, 3, 4], [12, 3, 3, 4]] - 0.000248696286071804773 # B[606, [12, 3, 3, 4], [13, 3, 3, 6]] - -0.000479775127143412111 # B[607, [12, 3, 3, 4], [14, 4, 0, 4]] - 0.00175952173341571141 # B[608, [12, 3, 3, 4], [15, 4, 1, 5]] - 0.000197368498788095745 # B[609, [12, 3, 3, 4], [16, 4, 2, 4]] - 0.00726401135600521306 # B[610, [12, 3, 3, 4], [17, 4, 2, 6]] - -0.00118096336629036625 # B[611, [12, 3, 3, 4], [18, 4, 3, 5]] - 0.00702896514440041337 # B[612, [12, 3, 3, 4], [19, 4, 3, 7]] - -0.00236026619914155369 # B[613, [12, 3, 3, 4], [20, 4, 4, 4]] - -0.00341152672753146672 # B[614, [12, 3, 3, 4], [21, 4, 4, 6]] - 0.00348613231611557411 # B[615, [12, 3, 3, 4], [22, 4, 4, 8]] - 0.00244457707345889508 # B[616, [12, 3, 3, 4], [23, 5, 0, 5]] - -0.000822727235681003019 # B[617, [12, 3, 3, 4], [24, 5, 1, 6]] - -0.00248763810919495551 # B[618, [12, 3, 3, 4], [25, 5, 2, 5]] - 0.00796413115978647848 # B[619, [12, 3, 3, 4], [26, 5, 2, 7]] - -0.00179317048488774472 # B[620, [12, 3, 3, 4], [27, 5, 3, 6]] - 0.00454384820995466787 # B[621, [12, 3, 3, 4], [28, 5, 3, 8]] - -0.00425365149530766012 # B[622, [12, 3, 3, 4], [29, 5, 4, 5]] - -0.000569152560526600682 # B[623, [12, 3, 3, 4], [30, 5, 4, 7]] - -0.00506501220127485163 # B[624, [12, 3, 3, 4], [31, 5, 5, 6]] - -0.00142637122228714969 # B[625, [12, 3, 3, 4], [32, 5, 5, 8]] - 0.00190739239349446005 # B[626, [12, 3, 3, 4], [33, 6, 0, 6]] - 0.00215429853006474104 # B[627, [12, 3, 3, 4], [34, 6, 1, 7]] - 0.00512135793044871807 # B[628, [12, 3, 3, 4], [35, 6, 2, 6]] - 0.00479344551680733165 # B[629, [12, 3, 3, 4], [36, 6, 2, 8]] - -0.000813733007282164966 # B[630, [12, 3, 3, 4], [37, 6, 3, 7]] - -0.00162747725274282884 # B[631, [12, 3, 3, 4], [38, 6, 4, 6]] - -0.00440004969635155417 # B[632, [12, 3, 3, 4], [39, 6, 4, 8]] - -0.00939941153506137356 # B[633, [12, 3, 3, 4], [40, 6, 5, 7]] - -0.00314893787689287524 # B[634, [12, 3, 3, 4], [41, 6, 6, 6]] - -0.00125776748984993136 # B[635, [12, 3, 3, 4], [42, 6, 6, 8]] - 0.00129112127843685615 # B[636, [12, 3, 3, 4], [43, 7, 0, 7]] - 0.00564724346615860621 # B[637, [12, 3, 3, 4], [44, 7, 1, 8]] - -0.0018460571659526942 # B[638, [12, 3, 3, 4], [45, 7, 2, 7]] - -0.000300525523225368685 # B[639, [12, 3, 3, 4], [46, 7, 3, 8]] - -0.00277157581435865698 # B[640, [12, 3, 3, 4], [47, 7, 4, 7]] - -0.00975210406554173105 # B[641, [12, 3, 3, 4], [48, 7, 5, 8]] - -0.00233845213984289896 # B[642, [12, 3, 3, 4], [49, 7, 6, 7]] - -0.00138723239922117561 # B[643, [12, 3, 3, 4], [50, 7, 7, 8]] - 0.000864866797073243071 # B[644, [12, 3, 3, 4], [51, 8, 0, 8]] - -0.000747563068773752452 # B[645, [12, 3, 3, 4], [52, 8, 2, 8]] - 0.000965474694725087373 # B[646, [12, 3, 3, 4], [53, 8, 4, 8]] - -0.00140612646390263218 # B[647, [12, 3, 3, 4], [54, 8, 6, 8]] - -0.00149643617894318522 # B[648, [12, 3, 3, 4], [55, 8, 8, 8]] - 0.00149153681612450295 # B[649, [13, 3, 3, 6], [13, 3, 3, 6]] - -0.000954556711257832646 # B[650, [13, 3, 3, 6], [14, 4, 0, 4]] - 0.00120983585813713799 # B[651, [13, 3, 3, 6], [15, 4, 1, 5]] - 0.00300317867570911888 # B[652, [13, 3, 3, 6], [16, 4, 2, 4]] - 0.00236443796053106663 # B[653, [13, 3, 3, 6], [17, 4, 2, 6]] - 0.00415524139600132597 # B[654, [13, 3, 3, 6], [18, 4, 3, 5]] - -0.000123573851697839077 # B[655, [13, 3, 3, 6], [19, 4, 3, 7]] - 0.000470359195248265527 # B[656, [13, 3, 3, 6], [20, 4, 4, 4]] - 0.000635927641249957321 # B[657, [13, 3, 3, 6], [21, 4, 4, 6]] - 0.000747673754939660613 # B[658, [13, 3, 3, 6], [22, 4, 4, 8]] - 0.00074188846631736971 # B[659, [13, 3, 3, 6], [23, 5, 0, 5]] - 0.00463957097737913854 # B[660, [13, 3, 3, 6], [24, 5, 1, 6]] - -0.00271105182543343939 # B[661, [13, 3, 3, 6], [25, 5, 2, 5]] - 6.90411348413036419e-06 # B[662, [13, 3, 3, 6], [26, 5, 2, 7]] - 0.000911354980270381865 # B[663, [13, 3, 3, 6], [27, 5, 3, 6]] - -0.0028545746938972022 # B[664, [13, 3, 3, 6], [28, 5, 3, 8]] - -1.76062828863947363e-05 # B[665, [13, 3, 3, 6], [29, 5, 4, 5]] - -1.51206672011107435e-05 # B[666, [13, 3, 3, 6], [30, 5, 4, 7]] - -0.000798318879555708766 # B[667, [13, 3, 3, 6], [31, 5, 5, 6]] - -0.0015978026047660434 # B[668, [13, 3, 3, 6], [32, 5, 5, 8]] - 0.00034244751324807865 # B[669, [13, 3, 3, 6], [33, 6, 0, 6]] - 0.00338996797689858353 # B[670, [13, 3, 3, 6], [34, 6, 1, 7]] - 0.000289281476490772793 # B[671, [13, 3, 3, 6], [35, 6, 2, 6]] - -0.000559772151149058594 # B[672, [13, 3, 3, 6], [36, 6, 2, 8]] - -0.000650724286175463629 # B[673, [13, 3, 3, 6], [37, 6, 3, 7]] - 0.00148244897292096334 # B[674, [13, 3, 3, 6], [38, 6, 4, 6]] - 0.000183404639618602733 # B[675, [13, 3, 3, 6], [39, 6, 4, 8]] - -0.00185779692530890772 # B[676, [13, 3, 3, 6], [40, 6, 5, 7]] - -0.000708322215432564961 # B[677, [13, 3, 3, 6], [41, 6, 6, 6]] - -0.000491831969715535167 # B[678, [13, 3, 3, 6], [42, 6, 6, 8]] - 0.000833818016036214082 # B[679, [13, 3, 3, 6], [43, 7, 0, 7]] - -0.00256922900730601443 # B[680, [13, 3, 3, 6], [44, 7, 1, 8]] - -0.00112433206588518839 # B[681, [13, 3, 3, 6], [45, 7, 2, 7]] - 6.43716101358243753e-05 # B[682, [13, 3, 3, 6], [46, 7, 3, 8]] - -0.00126304972485289518 # B[683, [13, 3, 3, 6], [47, 7, 4, 7]] - -0.00210937996313975001 # B[684, [13, 3, 3, 6], [48, 7, 5, 8]] - -0.00126022676030809744 # B[685, [13, 3, 3, 6], [49, 7, 6, 7]] - -0.000555039709846411045 # B[686, [13, 3, 3, 6], [50, 7, 7, 8]] - 0.000790824100586496465 # B[687, [13, 3, 3, 6], [51, 8, 0, 8]] - -0.000844206812343649936 # B[688, [13, 3, 3, 6], [52, 8, 2, 8]] - 0.000195900027714517901 # B[689, [13, 3, 3, 6], [53, 8, 4, 8]] - -0.000823274415849936658 # B[690, [13, 3, 3, 6], [54, 8, 6, 8]] - -0.000330474595809105917 # B[691, [13, 3, 3, 6], [55, 8, 8, 8]] - -3.04835503155357485e-05 # B[692, [14, 4, 0, 4], [14, 4, 0, 4]] - -0.000825475145007361147 # B[693, [14, 4, 0, 4], [15, 4, 1, 5]] - -0.00244887111925138484 # B[694, [14, 4, 0, 4], [16, 4, 2, 4]] - -0.00122050568127611732 # B[695, [14, 4, 0, 4], [17, 4, 2, 6]] - -0.00226655265247485693 # B[696, [14, 4, 0, 4], [18, 4, 3, 5]] - -0.000767631950688907327 # B[697, [14, 4, 0, 4], [19, 4, 3, 7]] - -0.000547575812124723171 # B[698, [14, 4, 0, 4], [20, 4, 4, 4]] - -0.00121783548699544442 # B[699, [14, 4, 0, 4], [21, 4, 4, 6]] - 6.68947985199286332e-05 # B[700, [14, 4, 0, 4], [22, 4, 4, 8]] - -9.6030771921717939e-05 # B[701, [14, 4, 0, 4], [23, 5, 0, 5]] - -0.000544408900336967871 # B[702, [14, 4, 0, 4], [24, 5, 1, 6]] - -0.00139019051437529293 # B[703, [14, 4, 0, 4], [25, 5, 2, 5]] - -0.000281919324988699413 # B[704, [14, 4, 0, 4], [26, 5, 2, 7]] - -0.00125721115437776171 # B[705, [14, 4, 0, 4], [27, 5, 3, 6]] - -0.000282797770993010317 # B[706, [14, 4, 0, 4], [28, 5, 3, 8]] - -0.00139320549871079641 # B[707, [14, 4, 0, 4], [29, 5, 4, 5]] - -0.000628813518841068401 # B[708, [14, 4, 0, 4], [30, 5, 4, 7]] - -0.000607292163329276047 # B[709, [14, 4, 0, 4], [31, 5, 5, 6]] - 0.000242807689929189566 # B[710, [14, 4, 0, 4], [32, 5, 5, 8]] - -0.000100536983796830487 # B[711, [14, 4, 0, 4], [33, 6, 0, 6]] - 0.00111838401982674706 # B[712, [14, 4, 0, 4], [34, 6, 1, 7]] - -0.0012014113032742873 # B[713, [14, 4, 0, 4], [35, 6, 2, 6]] - -1.32311363260466386e-05 # B[714, [14, 4, 0, 4], [36, 6, 2, 8]] - 0.000753146180409180327 # B[715, [14, 4, 0, 4], [37, 6, 3, 7]] - -0.000270332227596856156 # B[716, [14, 4, 0, 4], [38, 6, 4, 6]] - -0.000293750660311472775 # B[717, [14, 4, 0, 4], [39, 6, 4, 8]] - 6.52480591955099942e-05 # B[718, [14, 4, 0, 4], [40, 6, 5, 7]] - -4.70588815947581285e-05 # B[719, [14, 4, 0, 4], [41, 6, 6, 6]] - 0.000244731448919628669 # B[720, [14, 4, 0, 4], [42, 6, 6, 8]] - -9.3149326930830334e-05 # B[721, [14, 4, 0, 4], [43, 7, 0, 7]] - 0.000731947904616598796 # B[722, [14, 4, 0, 4], [44, 7, 1, 8]] - -0.00107463735030771668 # B[723, [14, 4, 0, 4], [45, 7, 2, 7]] - 0.000139861959076940934 # B[724, [14, 4, 0, 4], [46, 7, 3, 8]] - 0.000101877532936889281 # B[725, [14, 4, 0, 4], [47, 7, 4, 7]] - -0.000196888502333611437 # B[726, [14, 4, 0, 4], [48, 7, 5, 8]] - 6.12030178565765859e-05 # B[727, [14, 4, 0, 4], [49, 7, 6, 7]] - -0.000223986590912481076 # B[728, [14, 4, 0, 4], [50, 7, 7, 8]] - -6.56819431667232667e-05 # B[729, [14, 4, 0, 4], [51, 8, 0, 8]] - -0.000970632773483491584 # B[730, [14, 4, 0, 4], [52, 8, 2, 8]] - -0.000182189294658170395 # B[731, [14, 4, 0, 4], [53, 8, 4, 8]] - -3.45215935849477185e-05 # B[732, [14, 4, 0, 4], [54, 8, 6, 8]] - 6.19739521221795986e-05 # B[733, [14, 4, 0, 4], [55, 8, 8, 8]] - 0.000242753902013392972 # B[734, [15, 4, 1, 5], [15, 4, 1, 5]] - 0.00729727211034517358 # B[735, [15, 4, 1, 5], [16, 4, 2, 4]] - -0.0024545495000649507 # B[736, [15, 4, 1, 5], [17, 4, 2, 6]] - -0.00265559618939786597 # B[737, [15, 4, 1, 5], [18, 4, 3, 5]] - 0.00473045463551583639 # B[738, [15, 4, 1, 5], [19, 4, 3, 7]] - -0.000140785797905494323 # B[739, [15, 4, 1, 5], [20, 4, 4, 4]] - 0.00179841698526277474 # B[740, [15, 4, 1, 5], [21, 4, 4, 6]] - 0.00129773534161339073 # B[741, [15, 4, 1, 5], [22, 4, 4, 8]] - 0.00172905697138841467 # B[742, [15, 4, 1, 5], [23, 5, 0, 5]] - -0.00408304027381215483 # B[743, [15, 4, 1, 5], [24, 5, 1, 6]] - -0.00205043992851699228 # B[744, [15, 4, 1, 5], [25, 5, 2, 5]] - 0.000756591579123801249 # B[745, [15, 4, 1, 5], [26, 5, 2, 7]] - -0.00421238291006168549 # B[746, [15, 4, 1, 5], [27, 5, 3, 6]] - -0.00196911327032830725 # B[747, [15, 4, 1, 5], [28, 5, 3, 8]] - 0.000729488918071528446 # B[748, [15, 4, 1, 5], [29, 5, 4, 5]] - -0.00177843604064341788 # B[749, [15, 4, 1, 5], [30, 5, 4, 7]] - -0.00130376966915328159 # B[750, [15, 4, 1, 5], [31, 5, 5, 6]] - -0.00198695656227435707 # B[751, [15, 4, 1, 5], [32, 5, 5, 8]] - 0.000608914142072050635 # B[752, [15, 4, 1, 5], [33, 6, 0, 6]] - -0.00109469344681823767 # B[753, [15, 4, 1, 5], [34, 6, 1, 7]] - -0.00451953523789613495 # B[754, [15, 4, 1, 5], [35, 6, 2, 6]] - 0.00279449892877900279 # B[755, [15, 4, 1, 5], [36, 6, 2, 8]] - -0.00435984465194903283 # B[756, [15, 4, 1, 5], [37, 6, 3, 7]] - 0.00275969130186590542 # B[757, [15, 4, 1, 5], [38, 6, 4, 6]] - 0.00154021904971430755 # B[758, [15, 4, 1, 5], [39, 6, 4, 8]] - -0.00146163413862035289 # B[759, [15, 4, 1, 5], [40, 6, 5, 7]] - -0.000333421796264918996 # B[760, [15, 4, 1, 5], [41, 6, 6, 6]] - -0.00139958818201657261 # B[761, [15, 4, 1, 5], [42, 6, 6, 8]] - 0.000750502250600797172 # B[762, [15, 4, 1, 5], [43, 7, 0, 7]] - 0.00476052216726493421 # B[763, [15, 4, 1, 5], [44, 7, 1, 8]] - -0.00155321215408361565 # B[764, [15, 4, 1, 5], [45, 7, 2, 7]] - -0.00351167160511536933 # B[765, [15, 4, 1, 5], [46, 7, 3, 8]] - 0.00268907735535169144 # B[766, [15, 4, 1, 5], [47, 7, 4, 7]] - -0.00296394481906553462 # B[767, [15, 4, 1, 5], [48, 7, 5, 8]] - -0.00115945739998543369 # B[768, [15, 4, 1, 5], [49, 7, 6, 7]] - -0.0011498694923236445 # B[769, [15, 4, 1, 5], [50, 7, 7, 8]] - 0.000691127444573572114 # B[770, [15, 4, 1, 5], [51, 8, 0, 8]] - 0.00149148321917135169 # B[771, [15, 4, 1, 5], [52, 8, 2, 8]] - 0.00226549729687968923 # B[772, [15, 4, 1, 5], [53, 8, 4, 8]] - -0.00127955154911817224 # B[773, [15, 4, 1, 5], [54, 8, 6, 8]] - -0.0006680598304007173 # B[774, [15, 4, 1, 5], [55, 8, 8, 8]] - 0.00773393138113156846 # B[775, [16, 4, 2, 4], [16, 4, 2, 4]] - 0.00481567776445743917 # B[776, [16, 4, 2, 4], [17, 4, 2, 6]] - 0.00646602315581837339 # B[777, [16, 4, 2, 4], [18, 4, 3, 5]] - 0.00401373256364237051 # B[778, [16, 4, 2, 4], [19, 4, 3, 7]] - -0.000224833927917125753 # B[779, [16, 4, 2, 4], [20, 4, 4, 4]] - 0.0030532060451974926 # B[780, [16, 4, 2, 4], [21, 4, 4, 6]] - -0.000126777823410560014 # B[781, [16, 4, 2, 4], [22, 4, 4, 8]] - 0.00109512376860463863 # B[782, [16, 4, 2, 4], [23, 5, 0, 5]] - 0.0014906978453806609 # B[783, [16, 4, 2, 4], [24, 5, 1, 6]] - 0.00278609484035531206 # B[784, [16, 4, 2, 4], [25, 5, 2, 5]] - 0.00720611209490516682 # B[785, [16, 4, 2, 4], [26, 5, 2, 7]] - 0.00230880055683394415 # B[786, [16, 4, 2, 4], [27, 5, 3, 6]] - 0.00492114792718315389 # B[787, [16, 4, 2, 4], [28, 5, 3, 8]] - 0.00102265649585190407 # B[788, [16, 4, 2, 4], [29, 5, 4, 5]] - -0.000348239317084679881 # B[789, [16, 4, 2, 4], [30, 5, 4, 7]] - -0.00394431438420023671 # B[790, [16, 4, 2, 4], [31, 5, 5, 6]] - -0.00362914461095884553 # B[791, [16, 4, 2, 4], [32, 5, 5, 8]] - 0.000172019923347470349 # B[792, [16, 4, 2, 4], [33, 6, 0, 6]] - -0.000316455135754767445 # B[793, [16, 4, 2, 4], [34, 6, 1, 7]] - 0.00107098215861984453 # B[794, [16, 4, 2, 4], [35, 6, 2, 6]] - -0.000907131668137324478 # B[795, [16, 4, 2, 4], [36, 6, 2, 8]] - -0.000367695081353409058 # B[796, [16, 4, 2, 4], [37, 6, 3, 7]] - 0.00181370580350630889 # B[797, [16, 4, 2, 4], [38, 6, 4, 6]] - 0.000820930060826967692 # B[798, [16, 4, 2, 4], [39, 6, 4, 8]] - -0.00466238776474962348 # B[799, [16, 4, 2, 4], [40, 6, 5, 7]] - -0.0024305728850557008 # B[800, [16, 4, 2, 4], [41, 6, 6, 6]] - -0.00165013696151081928 # B[801, [16, 4, 2, 4], [42, 6, 6, 8]] - 0.000760058338755045804 # B[802, [16, 4, 2, 4], [43, 7, 0, 7]] - -0.00203289214112462729 # B[803, [16, 4, 2, 4], [44, 7, 1, 8]] - -0.00103057221789182719 # B[804, [16, 4, 2, 4], [45, 7, 2, 7]] - 0.00188720556649034019 # B[805, [16, 4, 2, 4], [46, 7, 3, 8]] - -0.000348979964538542048 # B[806, [16, 4, 2, 4], [47, 7, 4, 7]] - -0.00595514004121479486 # B[807, [16, 4, 2, 4], [48, 7, 5, 8]] - -0.00122307692783891336 # B[808, [16, 4, 2, 4], [49, 7, 6, 7]] - -0.00161626528708522232 # B[809, [16, 4, 2, 4], [50, 7, 7, 8]] - 0.000683658453003721522 # B[810, [16, 4, 2, 4], [51, 8, 0, 8]] - 0.000169503544911074264 # B[811, [16, 4, 2, 4], [52, 8, 2, 8]] - 0.00163132840171071117 # B[812, [16, 4, 2, 4], [53, 8, 4, 8]] - -0.000633742642666999118 # B[813, [16, 4, 2, 4], [54, 8, 6, 8]] - -0.000861029784191980584 # B[814, [16, 4, 2, 4], [55, 8, 8, 8]] - 0.0101724317893582689 # B[815, [17, 4, 2, 6], [17, 4, 2, 6]] - 0.00963074903115390332 # B[816, [17, 4, 2, 6], [18, 4, 3, 5]] - 0.00792776812488414986 # B[817, [17, 4, 2, 6], [19, 4, 3, 7]] - 0.00129789596639547263 # B[818, [17, 4, 2, 6], [20, 4, 4, 4]] - 0.0025280260724625768 # B[819, [17, 4, 2, 6], [21, 4, 4, 6]] - -0.00130604081814601758 # B[820, [17, 4, 2, 6], [22, 4, 4, 8]] - 0.00061656245411057832 # B[821, [17, 4, 2, 6], [23, 5, 0, 5]] - 0.00256026791937838134 # B[822, [17, 4, 2, 6], [24, 5, 1, 6]] - 0.00833728674660196879 # B[823, [17, 4, 2, 6], [25, 5, 2, 5]] - 0.00819332084025456604 # B[824, [17, 4, 2, 6], [26, 5, 2, 7]] - 0.00199258058679730159 # B[825, [17, 4, 2, 6], [27, 5, 3, 6]] - -0.00235687406293394464 # B[826, [17, 4, 2, 6], [28, 5, 3, 8]] - 0.00172306590551023903 # B[827, [17, 4, 2, 6], [29, 5, 4, 5]] - 0.00273320921325834404 # B[828, [17, 4, 2, 6], [30, 5, 4, 7]] - 0.00124490813870011289 # B[829, [17, 4, 2, 6], [31, 5, 5, 6]] - -0.00239829497882970916 # B[830, [17, 4, 2, 6], [32, 5, 5, 8]] - 0.000403489881901454572 # B[831, [17, 4, 2, 6], [33, 6, 0, 6]] - 0.0115977289566935714 # B[832, [17, 4, 2, 6], [34, 6, 1, 7]] - 0.00631330244272786285 # B[833, [17, 4, 2, 6], [35, 6, 2, 6]] - 0.00745951676374975552 # B[834, [17, 4, 2, 6], [36, 6, 2, 8]] - 0.00129555462014044158 # B[835, [17, 4, 2, 6], [37, 6, 3, 7]] - 0.0031708889242759988 # B[836, [17, 4, 2, 6], [38, 6, 4, 6]] - 0.00314059501950873093 # B[837, [17, 4, 2, 6], [39, 6, 4, 8]] - -0.00157311519106628078 # B[838, [17, 4, 2, 6], [40, 6, 5, 7]] - -0.000535633835711041804 # B[839, [17, 4, 2, 6], [41, 6, 6, 6]] - -0.00106218347026977491 # B[840, [17, 4, 2, 6], [42, 6, 6, 8]] - 0.00171130648037900839 # B[841, [17, 4, 2, 6], [43, 7, 0, 7]] - 0.00318381348777509654 # B[842, [17, 4, 2, 6], [44, 7, 1, 8]] - 0.00121186975917000981 # B[843, [17, 4, 2, 6], [45, 7, 2, 7]] - -0.00505226933268299559 # B[844, [17, 4, 2, 6], [46, 7, 3, 8]] - 0.000505489038324865442 # B[845, [17, 4, 2, 6], [47, 7, 4, 7]] - -0.00260650572816220009 # B[846, [17, 4, 2, 6], [48, 7, 5, 8]] - -0.00458388666826989831 # B[847, [17, 4, 2, 6], [49, 7, 6, 7]] - -0.0030323259618317824 # B[848, [17, 4, 2, 6], [50, 7, 7, 8]] - 0.000919810997489799165 # B[849, [17, 4, 2, 6], [51, 8, 0, 8]] - 0.00153843620323466154 # B[850, [17, 4, 2, 6], [52, 8, 2, 8]] - 0.00177452104337356975 # B[851, [17, 4, 2, 6], [53, 8, 4, 8]] - -0.00133363365246129796 # B[852, [17, 4, 2, 6], [54, 8, 6, 8]] - 0.000497168699576265929 # B[853, [17, 4, 2, 6], [55, 8, 8, 8]] - 0.00916493227652732945 # B[854, [18, 4, 3, 5], [18, 4, 3, 5]] - 0.00662893191875722591 # B[855, [18, 4, 3, 5], [19, 4, 3, 7]] - 0.00102473567933248147 # B[856, [18, 4, 3, 5], [20, 4, 4, 4]] - 0.000661293664462594619 # B[857, [18, 4, 3, 5], [21, 4, 4, 6]] - 0.00302383517430961438 # B[858, [18, 4, 3, 5], [22, 4, 4, 8]] - 0.00182134236384280147 # B[859, [18, 4, 3, 5], [23, 5, 0, 5]] - 0.00481003527044247467 # B[860, [18, 4, 3, 5], [24, 5, 1, 6]] - 0.00472221587821478311 # B[861, [18, 4, 3, 5], [25, 5, 2, 5]] - 0.00204855894682247092 # B[862, [18, 4, 3, 5], [26, 5, 2, 7]] - 0.00108437129165206425 # B[863, [18, 4, 3, 5], [27, 5, 3, 6]] - 0.000188071259560827417 # B[864, [18, 4, 3, 5], [28, 5, 3, 8]] - 0.000402244806083140727 # B[865, [18, 4, 3, 5], [29, 5, 4, 5]] - 0.00350511561101824257 # B[866, [18, 4, 3, 5], [30, 5, 4, 7]] - -0.00196731170271619883 # B[867, [18, 4, 3, 5], [31, 5, 5, 6]] - -0.000854471064769226317 # B[868, [18, 4, 3, 5], [32, 5, 5, 8]] - 0.00163753590726098495 # B[869, [18, 4, 3, 5], [33, 6, 0, 6]] - 0.00678767470498069323 # B[870, [18, 4, 3, 5], [34, 6, 1, 7]] - 0.00671898362129526739 # B[871, [18, 4, 3, 5], [35, 6, 2, 6]] - 0.00504150139406711259 # B[872, [18, 4, 3, 5], [36, 6, 2, 8]] - -0.00150058947564556469 # B[873, [18, 4, 3, 5], [37, 6, 3, 7]] - 0.00126561580055304518 # B[874, [18, 4, 3, 5], [38, 6, 4, 6]] - -0.000556565865268397481 # B[875, [18, 4, 3, 5], [39, 6, 4, 8]] - -0.00527488386402661519 # B[876, [18, 4, 3, 5], [40, 6, 5, 7]] - -0.00214157468754809163 # B[877, [18, 4, 3, 5], [41, 6, 6, 6]] - -0.0020431148178264337 # B[878, [18, 4, 3, 5], [42, 6, 6, 8]] - 0.00142704628054338232 # B[879, [18, 4, 3, 5], [43, 7, 0, 7]] - 0.00368882624306161085 # B[880, [18, 4, 3, 5], [44, 7, 1, 8]] - -0.000742447358153045661 # B[881, [18, 4, 3, 5], [45, 7, 2, 7]] - -0.00158678830901623838 # B[882, [18, 4, 3, 5], [46, 7, 3, 8]] - -0.00107876302160130055 # B[883, [18, 4, 3, 5], [47, 7, 4, 7]] - -0.00701537311445033646 # B[884, [18, 4, 3, 5], [48, 7, 5, 8]] - -0.00184801443295596127 # B[885, [18, 4, 3, 5], [49, 7, 6, 7]] - -0.00127678697871524667 # B[886, [18, 4, 3, 5], [50, 7, 7, 8]] - 0.00105641109188138113 # B[887, [18, 4, 3, 5], [51, 8, 0, 8]] - 0.000718098622203026428 # B[888, [18, 4, 3, 5], [52, 8, 2, 8]] - 0.00219486004289275692 # B[889, [18, 4, 3, 5], [53, 8, 4, 8]] - -0.00158748993130468905 # B[890, [18, 4, 3, 5], [54, 8, 6, 8]] - -0.00105128398142791644 # B[891, [18, 4, 3, 5], [55, 8, 8, 8]] - -0.00705876763301777586 # B[892, [19, 4, 3, 7], [19, 4, 3, 7]] - 0.00377186011578763136 # B[893, [19, 4, 3, 7], [20, 4, 4, 4]] - 0.00351225097737749986 # B[894, [19, 4, 3, 7], [21, 4, 4, 6]] - -0.00323798036048509805 # B[895, [19, 4, 3, 7], [22, 4, 4, 8]] - 0.00126225430824061444 # B[896, [19, 4, 3, 7], [23, 5, 0, 5]] - -0.00132900767543010258 # B[897, [19, 4, 3, 7], [24, 5, 1, 6]] - 0.000212743875668733318 # B[898, [19, 4, 3, 7], [25, 5, 2, 5]] - -8.93559293989563963e-05 # B[899, [19, 4, 3, 7], [26, 5, 2, 7]] - 0.00401415269432878544 # B[900, [19, 4, 3, 7], [27, 5, 3, 6]] - -0.00422923196125859352 # B[901, [19, 4, 3, 7], [28, 5, 3, 8]] - 0.00252733635050122335 # B[902, [19, 4, 3, 7], [29, 5, 4, 5]] - -0.00020969110581340808 # B[903, [19, 4, 3, 7], [30, 5, 4, 7]] - -0.000969147769818896193 # B[904, [19, 4, 3, 7], [31, 5, 5, 6]] - -0.00249817386761041864 # B[905, [19, 4, 3, 7], [32, 5, 5, 8]] - 7.71120512828363247e-05 # B[906, [19, 4, 3, 7], [33, 6, 0, 6]] - 0.00560302176075209817 # B[907, [19, 4, 3, 7], [34, 6, 1, 7]] - 0.00342833731167378752 # B[908, [19, 4, 3, 7], [35, 6, 2, 6]] - 0.00116548365936076578 # B[909, [19, 4, 3, 7], [36, 6, 2, 8]] - 0.00499590856190199745 # B[910, [19, 4, 3, 7], [37, 6, 3, 7]] - 0.00391644837067879614 # B[911, [19, 4, 3, 7], [38, 6, 4, 6]] - 0.00116606811408420229 # B[912, [19, 4, 3, 7], [39, 6, 4, 8]] - -0.000563820914290556058 # B[913, [19, 4, 3, 7], [40, 6, 5, 7]] - -0.000251464925992161276 # B[914, [19, 4, 3, 7], [41, 6, 6, 6]] - -0.000718753250305587815 # B[915, [19, 4, 3, 7], [42, 6, 6, 8]] - 0.000453024387943248494 # B[916, [19, 4, 3, 7], [43, 7, 0, 7]] - -0.00146422451962339994 # B[917, [19, 4, 3, 7], [44, 7, 1, 8]] - 0.00271974781140060795 # B[918, [19, 4, 3, 7], [45, 7, 2, 7]] - 0.00151707017829591159 # B[919, [19, 4, 3, 7], [46, 7, 3, 8]] - 0.00202377896423465691 # B[920, [19, 4, 3, 7], [47, 7, 4, 7]] - -0.00131185948123999779 # B[921, [19, 4, 3, 7], [48, 7, 5, 8]] - 0.000239464941185672797 # B[922, [19, 4, 3, 7], [49, 7, 6, 7]] - -0.000667571478871501964 # B[923, [19, 4, 3, 7], [50, 7, 7, 8]] - 0.000666789360176615192 # B[924, [19, 4, 3, 7], [51, 8, 0, 8]] - 0.00179543252151156355 # B[925, [19, 4, 3, 7], [52, 8, 2, 8]] - 0.000954396542852647967 # B[926, [19, 4, 3, 7], [53, 8, 4, 8]] - 0.000593331439814590023 # B[927, [19, 4, 3, 7], [54, 8, 6, 8]] - -0.000292670120459602445 # B[928, [19, 4, 3, 7], [55, 8, 8, 8]] - -0.000303353861178074294 # B[929, [20, 4, 4, 4], [20, 4, 4, 4]] - -6.41585335468541906e-05 # B[930, [20, 4, 4, 4], [21, 4, 4, 6]] - 0.00145464895340288725 # B[931, [20, 4, 4, 4], [22, 4, 4, 8]] - 0.000557677559397141802 # B[932, [20, 4, 4, 4], [23, 5, 0, 5]] - 0.00214733001664968188 # B[933, [20, 4, 4, 4], [24, 5, 1, 6]] - 0.000196804226194771757 # B[934, [20, 4, 4, 4], [25, 5, 2, 5]] - 0.00169621771662652795 # B[935, [20, 4, 4, 4], [26, 5, 2, 7]] - -0.00126951106424718924 # B[936, [20, 4, 4, 4], [27, 5, 3, 6]] - 0.00156201190059711802 # B[937, [20, 4, 4, 4], [28, 5, 3, 8]] - -0.000188505112089858498 # B[938, [20, 4, 4, 4], [29, 5, 4, 5]] - 0.00101485096974841295 # B[939, [20, 4, 4, 4], [30, 5, 4, 7]] - -0.000254023094278113288 # B[940, [20, 4, 4, 4], [31, 5, 5, 6]] - -0.000332430225508446864 # B[941, [20, 4, 4, 4], [32, 5, 5, 8]] - 0.000393172799404761797 # B[942, [20, 4, 4, 4], [33, 6, 0, 6]] - -0.000945851456653874594 # B[943, [20, 4, 4, 4], [34, 6, 1, 7]] - 0.000937118523093692299 # B[944, [20, 4, 4, 4], [35, 6, 2, 6]] - 0.00108463610451345858 # B[945, [20, 4, 4, 4], [36, 6, 2, 8]] - -0.00167878968186336089 # B[946, [20, 4, 4, 4], [37, 6, 3, 7]] - 0.000109649976457827647 # B[947, [20, 4, 4, 4], [38, 6, 4, 6]] - 0.000205908523746248934 # B[948, [20, 4, 4, 4], [39, 6, 4, 8]] - -0.000952641271225448949 # B[949, [20, 4, 4, 4], [40, 6, 5, 7]] - -0.000386842165161269298 # B[950, [20, 4, 4, 4], [41, 6, 6, 6]] - -0.000662992329463731739 # B[951, [20, 4, 4, 4], [42, 6, 6, 8]] - 0.000368522676488847178 # B[952, [20, 4, 4, 4], [43, 7, 0, 7]] - -0.000181924614212486402 # B[953, [20, 4, 4, 4], [44, 7, 1, 8]] - -0.00119374010493299761 # B[954, [20, 4, 4, 4], [45, 7, 2, 7]] - -0.000775398926021152179 # B[955, [20, 4, 4, 4], [46, 7, 3, 8]] - -0.000670782103704289923 # B[956, [20, 4, 4, 4], [47, 7, 4, 7]] - -0.00192682764111087456 # B[957, [20, 4, 4, 4], [48, 7, 5, 8]] - -0.000648663865567958298 # B[958, [20, 4, 4, 4], [49, 7, 6, 7]] - -0.000387954189232417312 # B[959, [20, 4, 4, 4], [50, 7, 7, 8]] - 0.000302370648048068055 # B[960, [20, 4, 4, 4], [51, 8, 0, 8]] - -0.00085980088667597307 # B[961, [20, 4, 4, 4], [52, 8, 2, 8]] - 0.000568399123124077588 # B[962, [20, 4, 4, 4], [53, 8, 4, 8]] - -0.000482151590861096269 # B[963, [20, 4, 4, 4], [54, 8, 6, 8]] - -0.000405828455879983507 # B[964, [20, 4, 4, 4], [55, 8, 8, 8]] - 0.00165997230068267755 # B[965, [21, 4, 4, 6], [21, 4, 4, 6]] - 0.000963896255597472551 # B[966, [21, 4, 4, 6], [22, 4, 4, 8]] - 0.0002094521100325826 # B[967, [21, 4, 4, 6], [23, 5, 0, 5]] - 0.000534879644705995444 # B[968, [21, 4, 4, 6], [24, 5, 1, 6]] - 0.00292236533791157905 # B[969, [21, 4, 4, 6], [25, 5, 2, 5]] - 0.00151524368635043427 # B[970, [21, 4, 4, 6], [26, 5, 2, 7]] - -0.00101689007388491501 # B[971, [21, 4, 4, 6], [27, 5, 3, 6]] - 0.000738459806183821427 # B[972, [21, 4, 4, 6], [28, 5, 3, 8]] - 0.00148643764242684627 # B[973, [21, 4, 4, 6], [29, 5, 4, 5]] - 0.0011556877894129472 # B[974, [21, 4, 4, 6], [30, 5, 4, 7]] - -0.000208381440186615127 # B[975, [21, 4, 4, 6], [31, 5, 5, 6]] - -0.00143743030752817389 # B[976, [21, 4, 4, 6], [32, 5, 5, 8]] - -0.00016600302639456152 # B[977, [21, 4, 4, 6], [33, 6, 0, 6]] - 0.00172160125073629253 # B[978, [21, 4, 4, 6], [34, 6, 1, 7]] - 0.00344812165058533751 # B[979, [21, 4, 4, 6], [35, 6, 2, 6]] - 0.000544104512334869089 # B[980, [21, 4, 4, 6], [36, 6, 2, 8]] - -0.00182558144376257503 # B[981, [21, 4, 4, 6], [37, 6, 3, 7]] - 0.00101065848983370246 # B[982, [21, 4, 4, 6], [38, 6, 4, 6]] - 0.00103400096073465869 # B[983, [21, 4, 4, 6], [39, 6, 4, 8]] - -0.000235944095127582111 # B[984, [21, 4, 4, 6], [40, 6, 5, 7]] - 0.000154580830205655606 # B[985, [21, 4, 4, 6], [41, 6, 6, 6]] - -0.000488680460493023505 # B[986, [21, 4, 4, 6], [42, 6, 6, 8]] - 3.83739714257189113e-05 # B[987, [21, 4, 4, 6], [43, 7, 0, 7]] - -0.000275037336268196993 # B[988, [21, 4, 4, 6], [44, 7, 1, 8]] - 0.0017878021157122859 # B[989, [21, 4, 4, 6], [45, 7, 2, 7]] - -0.00110857713686632331 # B[990, [21, 4, 4, 6], [46, 7, 3, 8]] - -0.000126074852562767237 # B[991, [21, 4, 4, 6], [47, 7, 4, 7]] - -0.00125862858469075189 # B[992, [21, 4, 4, 6], [48, 7, 5, 8]] - -0.000277638160776805254 # B[993, [21, 4, 4, 6], [49, 7, 6, 7]] - 0.000163335859971639602 # B[994, [21, 4, 4, 6], [50, 7, 7, 8]] - 0.000151747507838979889 # B[995, [21, 4, 4, 6], [51, 8, 0, 8]] - 0.00156180455186682998 # B[996, [21, 4, 4, 6], [52, 8, 2, 8]] - 0.00112614353705531994 # B[997, [21, 4, 4, 6], [53, 8, 4, 8]] - -0.000376140365477903652 # B[998, [21, 4, 4, 6], [54, 8, 6, 8]] - -0.000378786757414536351 # B[999, [21, 4, 4, 6], [55, 8, 8, 8]] - -0.00186381195965971969 # B[1000, [22, 4, 4, 8], [22, 4, 4, 8]] - 0.000334060235611270684 # B[1001, [22, 4, 4, 8], [23, 5, 0, 5]] - -0.000182139490643212255 # B[1002, [22, 4, 4, 8], [24, 5, 1, 6]] - -0.000866414678376911532 # B[1003, [22, 4, 4, 8], [25, 5, 2, 5]] - -0.000713836573909394211 # B[1004, [22, 4, 4, 8], [26, 5, 2, 7]] - 0.00340359387460056721 # B[1005, [22, 4, 4, 8], [27, 5, 3, 6]] - -0.0025631762232975969 # B[1006, [22, 4, 4, 8], [28, 5, 3, 8]] - 0.00154837338005092001 # B[1007, [22, 4, 4, 8], [29, 5, 4, 5]] - -0.000713785025005329171 # B[1008, [22, 4, 4, 8], [30, 5, 4, 7]] - -6.17852167664190155e-06 # B[1009, [22, 4, 4, 8], [31, 5, 5, 6]] - -0.000925788250245492385 # B[1010, [22, 4, 4, 8], [32, 5, 5, 8]] - -0.000220618203180443506 # B[1011, [22, 4, 4, 8], [33, 6, 0, 6]] - 0.00158760304062654546 # B[1012, [22, 4, 4, 8], [34, 6, 1, 7]] - -0.00201296543384867077 # B[1013, [22, 4, 4, 8], [35, 6, 2, 6]] - -0.000153111573438037551 # B[1014, [22, 4, 4, 8], [36, 6, 2, 8]] - 0.001936342943994784 # B[1015, [22, 4, 4, 8], [37, 6, 3, 7]] - 0.0014724303902098404 # B[1016, [22, 4, 4, 8], [38, 6, 4, 6]] - 0.000412977919829218137 # B[1017, [22, 4, 4, 8], [39, 6, 4, 8]] - 0.000243129124011996767 # B[1018, [22, 4, 4, 8], [40, 6, 5, 7]] - 0.000433542078585167322 # B[1019, [22, 4, 4, 8], [41, 6, 6, 6]] - 5.87712210821707964e-05 # B[1020, [22, 4, 4, 8], [42, 6, 6, 8]] - -2.13873587015245281e-05 # B[1021, [22, 4, 4, 8], [43, 7, 0, 7]] - -0.00121671500578664389 # B[1022, [22, 4, 4, 8], [44, 7, 1, 8]] - 0.00185443425860575776 # B[1023, [22, 4, 4, 8], [45, 7, 2, 7]] - 0.00153976874095648406 # B[1024, [22, 4, 4, 8], [46, 7, 3, 8]] - 0.00100585852984078766 # B[1025, [22, 4, 4, 8], [47, 7, 4, 7]] - 0.000146502145157426621 # B[1026, [22, 4, 4, 8], [48, 7, 5, 8]] - 0.00026572798098887726 # B[1027, [22, 4, 4, 8], [49, 7, 6, 7]] - 0.000239744529446223043 # B[1028, [22, 4, 4, 8], [50, 7, 7, 8]] - 3.13331575558552233e-05 # B[1029, [22, 4, 4, 8], [51, 8, 0, 8]] - 0.0005761629631739415 # B[1030, [22, 4, 4, 8], [52, 8, 2, 8]] - 0.00020451472183747807 # B[1031, [22, 4, 4, 8], [53, 8, 4, 8]] - 0.000761501707699011737 # B[1032, [22, 4, 4, 8], [54, 8, 6, 8]] - 4.7608269104475881e-05 # B[1033, [22, 4, 4, 8], [55, 8, 8, 8]] - 0.00010288893231941848 # B[1034, [23, 5, 0, 5], [23, 5, 0, 5]] - -0.000598160679614365143 # B[1035, [23, 5, 0, 5], [24, 5, 1, 6]] - -0.000125600887517359969 # B[1036, [23, 5, 0, 5], [25, 5, 2, 5]] - -0.000541602347577959872 # B[1037, [23, 5, 0, 5], [26, 5, 2, 7]] - 0.000138742295315047448 # B[1038, [23, 5, 0, 5], [27, 5, 3, 6]] - 0.000320496112291311641 # B[1039, [23, 5, 0, 5], [28, 5, 3, 8]] - 9.77076363189860464e-05 # B[1040, [23, 5, 0, 5], [29, 5, 4, 5]] - -0.00018519393057754574 # B[1041, [23, 5, 0, 5], [30, 5, 4, 7]] - -0.000314308790209320843 # B[1042, [23, 5, 0, 5], [31, 5, 5, 6]] - -2.03507196530547385e-05 # B[1043, [23, 5, 0, 5], [32, 5, 5, 8]] - -8.76692912155085935e-08 # B[1044, [23, 5, 0, 5], [33, 6, 0, 6]] - -0.000208914241663854874 # B[1045, [23, 5, 0, 5], [34, 6, 1, 7]] - 0.000289191305925793653 # B[1046, [23, 5, 0, 5], [35, 6, 2, 6]] - 0.000292827060287376498 # B[1047, [23, 5, 0, 5], [36, 6, 2, 8]] - -0.000195999965143696386 # B[1048, [23, 5, 0, 5], [37, 6, 3, 7]] - 0.000122837407081860615 # B[1049, [23, 5, 0, 5], [38, 6, 4, 6]] - 0.000238061673948679331 # B[1050, [23, 5, 0, 5], [39, 6, 4, 8]] - 6.23458911314621333e-06 # B[1051, [23, 5, 0, 5], [40, 6, 5, 7]] - 0.000153645644536796327 # B[1052, [23, 5, 0, 5], [41, 6, 6, 6]] - 0.000208144485879115104 # B[1053, [23, 5, 0, 5], [42, 6, 6, 8]] - 0.000107382317423423967 # B[1054, [23, 5, 0, 5], [43, 7, 0, 7]] - -3.16437877474207152e-05 # B[1055, [23, 5, 0, 5], [44, 7, 1, 8]] - 5.2567890411161361e-05 # B[1056, [23, 5, 0, 5], [45, 7, 2, 7]] - -0.000407365287815795313 # B[1057, [23, 5, 0, 5], [46, 7, 3, 8]] - -0.000277007442936893014 # B[1058, [23, 5, 0, 5], [47, 7, 4, 7]] - -0.000163960409271388802 # B[1059, [23, 5, 0, 5], [48, 7, 5, 8]] - -0.00018222236229294142 # B[1060, [23, 5, 0, 5], [49, 7, 6, 7]] - -8.93725149996096868e-05 # B[1061, [23, 5, 0, 5], [50, 7, 7, 8]] - -4.59835267753172516e-05 # B[1062, [23, 5, 0, 5], [51, 8, 0, 8]] - -3.00980967951527262e-05 # B[1063, [23, 5, 0, 5], [52, 8, 2, 8]] - -0.00011786089545340328 # B[1064, [23, 5, 0, 5], [53, 8, 4, 8]] - 6.24840877215676604e-05 # B[1065, [23, 5, 0, 5], [54, 8, 6, 8]] - 0.000151333518371397913 # B[1066, [23, 5, 0, 5], [55, 8, 8, 8]] - -0.00373509601310103353 # B[1067, [24, 5, 1, 6], [24, 5, 1, 6]] - 0.00250350668234289742 # B[1068, [24, 5, 1, 6], [25, 5, 2, 5]] - -0.00141763987470412255 # B[1069, [24, 5, 1, 6], [26, 5, 2, 7]] - -0.000458490741576836162 # B[1070, [24, 5, 1, 6], [27, 5, 3, 6]] - 0.000169432811229417585 # B[1071, [24, 5, 1, 6], [28, 5, 3, 8]] - -0.000531768848310092699 # B[1072, [24, 5, 1, 6], [29, 5, 4, 5]] - 0.0019269207337581605 # B[1073, [24, 5, 1, 6], [30, 5, 4, 7]] - 0.000623468915929115824 # B[1074, [24, 5, 1, 6], [31, 5, 5, 6]] - 0.000262459747020924762 # B[1075, [24, 5, 1, 6], [32, 5, 5, 8]] - 0.000319464830252011445 # B[1076, [24, 5, 1, 6], [33, 6, 0, 6]] - 0.00250974732963905444 # B[1077, [24, 5, 1, 6], [34, 6, 1, 7]] - 0.00423653007687384807 # B[1078, [24, 5, 1, 6], [35, 6, 2, 6]] - 0.00144771358428595707 # B[1079, [24, 5, 1, 6], [36, 6, 2, 8]] - 0.00255496505633429419 # B[1080, [24, 5, 1, 6], [37, 6, 3, 7]] - -0.000923899857380450218 # B[1081, [24, 5, 1, 6], [38, 6, 4, 6]] - -0.000308666389289608337 # B[1082, [24, 5, 1, 6], [39, 6, 4, 8]] - 0.00222537659577300671 # B[1083, [24, 5, 1, 6], [40, 6, 5, 7]] - -0.00107541311587263343 # B[1084, [24, 5, 1, 6], [41, 6, 6, 6]] - -0.00278767944085371068 # B[1085, [24, 5, 1, 6], [42, 6, 6, 8]] - -0.000867530969177243705 # B[1086, [24, 5, 1, 6], [43, 7, 0, 7]] - 0.00357297895621819196 # B[1087, [24, 5, 1, 6], [44, 7, 1, 8]] - 0.00383976572090019216 # B[1088, [24, 5, 1, 6], [45, 7, 2, 7]] - -0.000580234942856992786 # B[1089, [24, 5, 1, 6], [46, 7, 3, 8]] - 0.00102888910081111798 # B[1090, [24, 5, 1, 6], [47, 7, 4, 7]] - 0.00132107614311613355 # B[1091, [24, 5, 1, 6], [48, 7, 5, 8]] - 0.00101848252621374036 # B[1092, [24, 5, 1, 6], [49, 7, 6, 7]] - 0.00160018234143227862 # B[1093, [24, 5, 1, 6], [50, 7, 7, 8]] - -5.52824024903572631e-05 # B[1094, [24, 5, 1, 6], [51, 8, 0, 8]] - 4.59186780197786033e-05 # B[1095, [24, 5, 1, 6], [52, 8, 2, 8]] - -0.000153436254581188554 # B[1096, [24, 5, 1, 6], [53, 8, 4, 8]] - -0.000546750998621967597 # B[1097, [24, 5, 1, 6], [54, 8, 6, 8]] - 0.000595956738118895348 # B[1098, [24, 5, 1, 6], [55, 8, 8, 8]] - 0.0083807047595118693 # B[1099, [25, 5, 2, 5], [25, 5, 2, 5]] - -0.000170544318645505719 # B[1100, [25, 5, 2, 5], [26, 5, 2, 7]] - 0.00235544441902155004 # B[1101, [25, 5, 2, 5], [27, 5, 3, 6]] - -0.00340197827063909962 # B[1102, [25, 5, 2, 5], [28, 5, 3, 8]] - 0.00311335525578198104 # B[1103, [25, 5, 2, 5], [29, 5, 4, 5]] - 0.00185214714164834123 # B[1104, [25, 5, 2, 5], [30, 5, 4, 7]] - -0.00328905913600528992 # B[1105, [25, 5, 2, 5], [31, 5, 5, 6]] - -0.00141866010082636025 # B[1106, [25, 5, 2, 5], [32, 5, 5, 8]] - 0.000176317033907393006 # B[1107, [25, 5, 2, 5], [33, 6, 0, 6]] - 0.00648328973805229608 # B[1108, [25, 5, 2, 5], [34, 6, 1, 7]] - 4.8980528358618259e-05 # B[1109, [25, 5, 2, 5], [35, 6, 2, 6]] - -0.00616971046300731144 # B[1110, [25, 5, 2, 5], [36, 6, 2, 8]] - -0.00135942372726050205 # B[1111, [25, 5, 2, 5], [37, 6, 3, 7]] - 0.000572735024796908881 # B[1112, [25, 5, 2, 5], [38, 6, 4, 6]] - -0.00229752149848994405 # B[1113, [25, 5, 2, 5], [39, 6, 4, 8]] - 0.0003485310815041524 # B[1114, [25, 5, 2, 5], [40, 6, 5, 7]] - -0.0011437361439647427 # B[1115, [25, 5, 2, 5], [41, 6, 6, 6]] - -0.000604819873822432311 # B[1116, [25, 5, 2, 5], [42, 6, 6, 8]] - 9.06237770597643696e-05 # B[1117, [25, 5, 2, 5], [43, 7, 0, 7]] - -0.000382141545017884894 # B[1118, [25, 5, 2, 5], [44, 7, 1, 8]] - -0.000842464094047663554 # B[1119, [25, 5, 2, 5], [45, 7, 2, 7]] - 0.000461973830441065811 # B[1120, [25, 5, 2, 5], [46, 7, 3, 8]] - 2.86192620363814355e-06 # B[1121, [25, 5, 2, 5], [47, 7, 4, 7]] - -0.0023436531447123838 # B[1122, [25, 5, 2, 5], [48, 7, 5, 8]] - 0.00134025173860287308 # B[1123, [25, 5, 2, 5], [49, 7, 6, 7]] - -0.000520013981518205846 # B[1124, [25, 5, 2, 5], [50, 7, 7, 8]] - 0.000515782740310496285 # B[1125, [25, 5, 2, 5], [51, 8, 0, 8]] - 0.00421651313615256564 # B[1126, [25, 5, 2, 5], [52, 8, 2, 8]] - 0.000755327719218409519 # B[1127, [25, 5, 2, 5], [53, 8, 4, 8]] - 0.000182937308412391315 # B[1128, [25, 5, 2, 5], [54, 8, 6, 8]] - 8.10383680097163071e-05 # B[1129, [25, 5, 2, 5], [55, 8, 8, 8]] - 0.000177735296666065024 # B[1130, [26, 5, 2, 7], [26, 5, 2, 7]] - -0.000642334677407747565 # B[1131, [26, 5, 2, 7], [27, 5, 3, 6]] - 0.000205172894139061396 # B[1132, [26, 5, 2, 7], [28, 5, 3, 8]] - -0.000537004220752698019 # B[1133, [26, 5, 2, 7], [29, 5, 4, 5]] - 5.14115941491347442e-05 # B[1134, [26, 5, 2, 7], [30, 5, 4, 7]] - 0.000417673445165051005 # B[1135, [26, 5, 2, 7], [31, 5, 5, 6]] - 0.00158446769775330391 # B[1136, [26, 5, 2, 7], [32, 5, 5, 8]] - 0.00121383407410429606 # B[1137, [26, 5, 2, 7], [33, 6, 0, 6]] - -0.00111992976945914785 # B[1138, [26, 5, 2, 7], [34, 6, 1, 7]] - 0.00398972286341117699 # B[1139, [26, 5, 2, 7], [35, 6, 2, 6]] - 0.00454565411209783762 # B[1140, [26, 5, 2, 7], [36, 6, 2, 8]] - -0.00300928796618537761 # B[1141, [26, 5, 2, 7], [37, 6, 3, 7]] - -0.00280024702462813163 # B[1142, [26, 5, 2, 7], [38, 6, 4, 6]] - 0.00182097597359056305 # B[1143, [26, 5, 2, 7], [39, 6, 4, 8]] - 0.00247143387165752772 # B[1144, [26, 5, 2, 7], [40, 6, 5, 7]] - -0.00143698477566456435 # B[1145, [26, 5, 2, 7], [41, 6, 6, 6]] - -0.00105878554545993375 # B[1146, [26, 5, 2, 7], [42, 6, 6, 8]] - 0.000650619036842032747 # B[1147, [26, 5, 2, 7], [43, 7, 0, 7]] - 8.72947879012740853e-05 # B[1148, [26, 5, 2, 7], [44, 7, 1, 8]] - -0.0002084941102769855 # B[1149, [26, 5, 2, 7], [45, 7, 2, 7]] - -0.000924608969529588931 # B[1150, [26, 5, 2, 7], [46, 7, 3, 8]] - -0.000320719808114693777 # B[1151, [26, 5, 2, 7], [47, 7, 4, 7]] - 0.00241998856780361801 # B[1152, [26, 5, 2, 7], [48, 7, 5, 8]] - -0.00171923440812344827 # B[1153, [26, 5, 2, 7], [49, 7, 6, 7]] - -0.000301390241580377569 # B[1154, [26, 5, 2, 7], [50, 7, 7, 8]] - -6.37461557401481499e-05 # B[1155, [26, 5, 2, 7], [51, 8, 0, 8]] - 0.00161644303684405446 # B[1156, [26, 5, 2, 7], [52, 8, 2, 8]] - 0.00104379414920739667 # B[1157, [26, 5, 2, 7], [53, 8, 4, 8]] - -0.00119795702190159808 # B[1158, [26, 5, 2, 7], [54, 8, 6, 8]] - 0.000604059138156293803 # B[1159, [26, 5, 2, 7], [55, 8, 8, 8]] - 0.000513459633959805622 # B[1160, [27, 5, 3, 6], [27, 5, 3, 6]] - -0.000172334638360790993 # B[1161, [27, 5, 3, 6], [28, 5, 3, 8]] - 1.60719061511648345e-05 # B[1162, [27, 5, 3, 6], [29, 5, 4, 5]] - 0.00440279299288983371 # B[1163, [27, 5, 3, 6], [30, 5, 4, 7]] - 0.000549761981236742206 # B[1164, [27, 5, 3, 6], [31, 5, 5, 6]] - 0.000424619689378998542 # B[1165, [27, 5, 3, 6], [32, 5, 5, 8]] - 0.000247367934895610653 # B[1166, [27, 5, 3, 6], [33, 6, 0, 6]] - 0.00400569055534595944 # B[1167, [27, 5, 3, 6], [34, 6, 1, 7]] - 0.00274378194299987679 # B[1168, [27, 5, 3, 6], [35, 6, 2, 6]] - 0.00368141326251353665 # B[1169, [27, 5, 3, 6], [36, 6, 2, 8]] - 0.00160469169395054817 # B[1170, [27, 5, 3, 6], [37, 6, 3, 7]] - 0.000105807739550402985 # B[1171, [27, 5, 3, 6], [38, 6, 4, 6]] - -0.000682801438033796976 # B[1172, [27, 5, 3, 6], [39, 6, 4, 8]] - -0.00121964915110857504 # B[1173, [27, 5, 3, 6], [40, 6, 5, 7]] - -0.000817665263990522556 # B[1174, [27, 5, 3, 6], [41, 6, 6, 6]] - 0.000534593784435832137 # B[1175, [27, 5, 3, 6], [42, 6, 6, 8]] - 0.000116542343021167755 # B[1176, [27, 5, 3, 6], [43, 7, 0, 7]] - 0.00351267154418699948 # B[1177, [27, 5, 3, 6], [44, 7, 1, 8]] - -0.00189934642995405814 # B[1178, [27, 5, 3, 6], [45, 7, 2, 7]] - 0.000751906974843792597 # B[1179, [27, 5, 3, 6], [46, 7, 3, 8]] - -0.000446808189773967301 # B[1180, [27, 5, 3, 6], [47, 7, 4, 7]] - -0.00324699511848197502 # B[1181, [27, 5, 3, 6], [48, 7, 5, 8]] - 2.53540837371335481e-05 # B[1182, [27, 5, 3, 6], [49, 7, 6, 7]] - 7.5273388360289073e-07 # B[1183, [27, 5, 3, 6], [50, 7, 7, 8]] - 0.00023346363571073725 # B[1184, [27, 5, 3, 6], [51, 8, 0, 8]] - 0.000490008984593369619 # B[1185, [27, 5, 3, 6], [52, 8, 2, 8]] - 0.000205260233742234413 # B[1186, [27, 5, 3, 6], [53, 8, 4, 8]] - -7.84984665939646165e-05 # B[1187, [27, 5, 3, 6], [54, 8, 6, 8]] - -0.000299454037036409743 # B[1188, [27, 5, 3, 6], [55, 8, 8, 8]] - -0.00411961786705090406 # B[1189, [28, 5, 3, 8], [28, 5, 3, 8]] - 0.00256764268592788759 # B[1190, [28, 5, 3, 8], [29, 5, 4, 5]] - -0.000267820435572239945 # B[1191, [28, 5, 3, 8], [30, 5, 4, 7]] - 0.000545048575291992229 # B[1192, [28, 5, 3, 8], [31, 5, 5, 6]] - -0.000141236037433873154 # B[1193, [28, 5, 3, 8], [32, 5, 5, 8]] - -8.17647193563642016e-05 # B[1194, [28, 5, 3, 8], [33, 6, 0, 6]] - 0.00184594470809960887 # B[1195, [28, 5, 3, 8], [34, 6, 1, 7]] - 0.000715653691449843685 # B[1196, [28, 5, 3, 8], [35, 6, 2, 6]] - -0.000371782729873919304 # B[1197, [28, 5, 3, 8], [36, 6, 2, 8]] - 0.00184451560473704312 # B[1198, [28, 5, 3, 8], [37, 6, 3, 7]] - 0.00298992898894900189 # B[1199, [28, 5, 3, 8], [38, 6, 4, 6]] - 0.00087474408278464047 # B[1200, [28, 5, 3, 8], [39, 6, 4, 8]] - 0.00115889056554823421 # B[1201, [28, 5, 3, 8], [40, 6, 5, 7]] - -0.000209440071593354482 # B[1202, [28, 5, 3, 8], [41, 6, 6, 6]] - 0.000707847416081031772 # B[1203, [28, 5, 3, 8], [42, 6, 6, 8]] - 0.00025922895119332573 # B[1204, [28, 5, 3, 8], [43, 7, 0, 7]] - -0.00210744601505012327 # B[1205, [28, 5, 3, 8], [44, 7, 1, 8]] - -0.00187401632149015486 # B[1206, [28, 5, 3, 8], [45, 7, 2, 7]] - 0.000616682247583759391 # B[1207, [28, 5, 3, 8], [46, 7, 3, 8]] - 0.00142526179781785924 # B[1208, [28, 5, 3, 8], [47, 7, 4, 7]] - -9.1619163886703936e-06 # B[1209, [28, 5, 3, 8], [48, 7, 5, 8]] - -0.000300978843055903222 # B[1210, [28, 5, 3, 8], [49, 7, 6, 7]] - -0.000124034381208077554 # B[1211, [28, 5, 3, 8], [50, 7, 7, 8]] - 0.000249158311162858692 # B[1212, [28, 5, 3, 8], [51, 8, 0, 8]] - -0.000970252220622513538 # B[1213, [28, 5, 3, 8], [52, 8, 2, 8]] - 0.000840312328335843066 # B[1214, [28, 5, 3, 8], [53, 8, 4, 8]] - 0.000145361901756495965 # B[1215, [28, 5, 3, 8], [54, 8, 6, 8]] - 0.00013163551986085896 # B[1216, [28, 5, 3, 8], [55, 8, 8, 8]] - 0.00265810885844912576 # B[1217, [29, 5, 4, 5], [29, 5, 4, 5]] - 0.00191793603428468823 # B[1218, [29, 5, 4, 5], [30, 5, 4, 7]] - 0.000446118694394436605 # B[1219, [29, 5, 4, 5], [31, 5, 5, 6]] - -9.59445098255573559e-05 # B[1220, [29, 5, 4, 5], [32, 5, 5, 8]] - 0.000369255428727587043 # B[1221, [29, 5, 4, 5], [33, 6, 0, 6]] - -0.000553149628059141762 # B[1222, [29, 5, 4, 5], [34, 6, 1, 7]] - 0.00315275275750991242 # B[1223, [29, 5, 4, 5], [35, 6, 2, 6]] - 0.00138540352181828336 # B[1224, [29, 5, 4, 5], [36, 6, 2, 8]] - 0.000776256233303879162 # B[1225, [29, 5, 4, 5], [37, 6, 3, 7]] - 0.000594477884906325672 # B[1226, [29, 5, 4, 5], [38, 6, 4, 6]] - 0.000757712543509288586 # B[1227, [29, 5, 4, 5], [39, 6, 4, 8]] - -0.000917903532807641184 # B[1228, [29, 5, 4, 5], [40, 6, 5, 7]] - -0.000915313398456763742 # B[1229, [29, 5, 4, 5], [41, 6, 6, 6]] - -0.00116732293566375843 # B[1230, [29, 5, 4, 5], [42, 6, 6, 8]] - 0.000172432189541951719 # B[1231, [29, 5, 4, 5], [43, 7, 0, 7]] - 0.000845370011774060912 # B[1232, [29, 5, 4, 5], [44, 7, 1, 8]] - 0.00178029205661471915 # B[1233, [29, 5, 4, 5], [45, 7, 2, 7]] - 0.00129739636685697463 # B[1234, [29, 5, 4, 5], [46, 7, 3, 8]] - 0.000282865369400489564 # B[1235, [29, 5, 4, 5], [47, 7, 4, 7]] - -0.00178988233479955398 # B[1236, [29, 5, 4, 5], [48, 7, 5, 8]] - 0.00023603474784275949 # B[1237, [29, 5, 4, 5], [49, 7, 6, 7]] - -0.000461436431325358207 # B[1238, [29, 5, 4, 5], [50, 7, 7, 8]] - 0.000234131705926524103 # B[1239, [29, 5, 4, 5], [51, 8, 0, 8]] - 0.00216254821351878363 # B[1240, [29, 5, 4, 5], [52, 8, 2, 8]] - 0.000831658742681578439 # B[1241, [29, 5, 4, 5], [53, 8, 4, 8]] - -0.00046318901257626742 # B[1242, [29, 5, 4, 5], [54, 8, 6, 8]] - -0.000607580535321294163 # B[1243, [29, 5, 4, 5], [55, 8, 8, 8]] - 0.00158347719827001653 # B[1244, [30, 5, 4, 7], [30, 5, 4, 7]] - 0.00120733638068271261 # B[1245, [30, 5, 4, 7], [31, 5, 5, 6]] - -0.000191610125195333311 # B[1246, [30, 5, 4, 7], [32, 5, 5, 8]] - -0.000363280761575070915 # B[1247, [30, 5, 4, 7], [33, 6, 0, 6]] - 0.0015080393447339897 # B[1248, [30, 5, 4, 7], [34, 6, 1, 7]] - 0.00144737958774105498 # B[1249, [30, 5, 4, 7], [35, 6, 2, 6]] - -0.000191256340607337365 # B[1250, [30, 5, 4, 7], [36, 6, 2, 8]] - 0.00324542123326504103 # B[1251, [30, 5, 4, 7], [37, 6, 3, 7]] - 0.00135369467391198949 # B[1252, [30, 5, 4, 7], [38, 6, 4, 6]] - 0.00077393986417062131 # B[1253, [30, 5, 4, 7], [39, 6, 4, 8]] - 0.00187057819081324836 # B[1254, [30, 5, 4, 7], [40, 6, 5, 7]] - 4.06728949024891956e-05 # B[1255, [30, 5, 4, 7], [41, 6, 6, 6]] - -0.000100060243024913467 # B[1256, [30, 5, 4, 7], [42, 6, 6, 8]] - -0.000170624797097965186 # B[1257, [30, 5, 4, 7], [43, 7, 0, 7]] - -0.00157200294852092963 # B[1258, [30, 5, 4, 7], [44, 7, 1, 8]] - -5.099465391029262e-05 # B[1259, [30, 5, 4, 7], [45, 7, 2, 7]] - 0.00166973065524506255 # B[1260, [30, 5, 4, 7], [46, 7, 3, 8]] - 0.000976468235486894175 # B[1261, [30, 5, 4, 7], [47, 7, 4, 7]] - -0.000570830124590235299 # B[1262, [30, 5, 4, 7], [48, 7, 5, 8]] - 0.000667250794893839427 # B[1263, [30, 5, 4, 7], [49, 7, 6, 7]] - -0.000273376565753529832 # B[1264, [30, 5, 4, 7], [50, 7, 7, 8]] - 0.000206233716860107844 # B[1265, [30, 5, 4, 7], [51, 8, 0, 8]] - 0.00260342927157033218 # B[1266, [30, 5, 4, 7], [52, 8, 2, 8]] - 0.000943954042545826558 # B[1267, [30, 5, 4, 7], [53, 8, 4, 8]] - -0.00022781927635321525 # B[1268, [30, 5, 4, 7], [54, 8, 6, 8]] - -0.000448456045604168733 # B[1269, [30, 5, 4, 7], [55, 8, 8, 8]] - 0.00102985782764508475 # B[1270, [31, 5, 5, 6], [31, 5, 5, 6]] - -8.89908688742153606e-05 # B[1271, [31, 5, 5, 6], [32, 5, 5, 8]] - -0.000162481274467801695 # B[1272, [31, 5, 5, 6], [33, 6, 0, 6]] - 0.00263772603538907271 # B[1273, [31, 5, 5, 6], [34, 6, 1, 7]] - -0.00223528099165903275 # B[1274, [31, 5, 5, 6], [35, 6, 2, 6]] - 0.000441657599119526373 # B[1275, [31, 5, 5, 6], [36, 6, 2, 8]] - 0.00165514785004864176 # B[1276, [31, 5, 5, 6], [37, 6, 3, 7]] - 0.000898928585103351413 # B[1277, [31, 5, 5, 6], [38, 6, 4, 6]] - -0.00026071204606309753 # B[1278, [31, 5, 5, 6], [39, 6, 4, 8]] - -0.000251612913047311385 # B[1279, [31, 5, 5, 6], [40, 6, 5, 7]] - -0.00022773870089292346 # B[1280, [31, 5, 5, 6], [41, 6, 6, 6]] - -0.000449951686975022525 # B[1281, [31, 5, 5, 6], [42, 6, 6, 8]] - -0.000252400784021909741 # B[1282, [31, 5, 5, 6], [43, 7, 0, 7]] - 0.000574433272355396977 # B[1283, [31, 5, 5, 6], [44, 7, 1, 8]] - -0.0014040949400035245 # B[1284, [31, 5, 5, 6], [45, 7, 2, 7]] - 0.00124516802775002586 # B[1285, [31, 5, 5, 6], [46, 7, 3, 8]] - 0.000875572292146320832 # B[1286, [31, 5, 5, 6], [47, 7, 4, 7]] - -0.000509730931921630048 # B[1287, [31, 5, 5, 6], [48, 7, 5, 8]] - 0.000422266146488117777 # B[1288, [31, 5, 5, 6], [49, 7, 6, 7]] - -0.000239146684560266956 # B[1289, [31, 5, 5, 6], [50, 7, 7, 8]] - 9.95899703990707486e-05 # B[1290, [31, 5, 5, 6], [51, 8, 0, 8]] - -0.0020784147827535588 # B[1291, [31, 5, 5, 6], [52, 8, 2, 8]] - 0.000735684723224858811 # B[1292, [31, 5, 5, 6], [53, 8, 4, 8]] - -0.000248804810033285279 # B[1293, [31, 5, 5, 6], [54, 8, 6, 8]] - -0.000598263607047986451 # B[1294, [31, 5, 5, 6], [55, 8, 8, 8]] - 0.000131065920905359436 # B[1295, [32, 5, 5, 8], [32, 5, 5, 8]] - 0.000100196796943449913 # B[1296, [32, 5, 5, 8], [33, 6, 0, 6]] - -0.00173991171955805834 # B[1297, [32, 5, 5, 8], [34, 6, 1, 7]] - -0.000490539010579770906 # B[1298, [32, 5, 5, 8], [35, 6, 2, 6]] - 0.000676191083650941674 # B[1299, [32, 5, 5, 8], [36, 6, 2, 8]] - 0.000446932761165407325 # B[1300, [32, 5, 5, 8], [37, 6, 3, 7]] - -0.000153107558622965576 # B[1301, [32, 5, 5, 8], [38, 6, 4, 6]] - 1.67752859932734574e-05 # B[1302, [32, 5, 5, 8], [39, 6, 4, 8]] - 0.000215146896189506113 # B[1303, [32, 5, 5, 8], [40, 6, 5, 7]] - -0.000188466441880926362 # B[1304, [32, 5, 5, 8], [41, 6, 6, 6]] - -4.80917708388720055e-06 # B[1305, [32, 5, 5, 8], [42, 6, 6, 8]] - -5.04429979448911547e-05 # B[1306, [32, 5, 5, 8], [43, 7, 0, 7]] - -0.000494944862407609067 # B[1307, [32, 5, 5, 8], [44, 7, 1, 8]] - -0.000424473825928651724 # B[1308, [32, 5, 5, 8], [45, 7, 2, 7]] - 0.000417544384337296959 # B[1309, [32, 5, 5, 8], [46, 7, 3, 8]] - 0.000431586591455488614 # B[1310, [32, 5, 5, 8], [47, 7, 4, 7]] - 0.000187341827588022357 # B[1311, [32, 5, 5, 8], [48, 7, 5, 8]] - -6.87669988055673864e-05 # B[1312, [32, 5, 5, 8], [49, 7, 6, 7]] - 0.000147867669408649482 # B[1313, [32, 5, 5, 8], [50, 7, 7, 8]] - -7.32201679551347517e-06 # B[1314, [32, 5, 5, 8], [51, 8, 0, 8]] - -0.000392519615947300787 # B[1315, [32, 5, 5, 8], [52, 8, 2, 8]] - 8.78465325612771269e-05 # B[1316, [32, 5, 5, 8], [53, 8, 4, 8]] - -6.3960070015590606e-05 # B[1317, [32, 5, 5, 8], [54, 8, 6, 8]] - -7.97839909379757101e-06 # B[1318, [32, 5, 5, 8], [55, 8, 8, 8]] - 3.95695067041609838e-05 # B[1319, [33, 6, 0, 6], [33, 6, 0, 6]] - -0.000611658005184461534 # B[1320, [33, 6, 0, 6], [34, 6, 1, 7]] - -0.000277914808470863806 # B[1321, [33, 6, 0, 6], [35, 6, 2, 6]] - 0.000987938388973043716 # B[1322, [33, 6, 0, 6], [36, 6, 2, 8]] - 0.000198558948919527745 # B[1323, [33, 6, 0, 6], [37, 6, 3, 7]] - 9.76274805398642809e-05 # B[1324, [33, 6, 0, 6], [38, 6, 4, 6]] - 9.92197766131464043e-05 # B[1325, [33, 6, 0, 6], [39, 6, 4, 8]] - -4.16996931875308896e-05 # B[1326, [33, 6, 0, 6], [40, 6, 5, 7]] - -5.3495059095630057e-05 # B[1327, [33, 6, 0, 6], [41, 6, 6, 6]] - 1.0720822351671655e-05 # B[1328, [33, 6, 0, 6], [42, 6, 6, 8]] - 0.000114464898537391946 # B[1329, [33, 6, 0, 6], [43, 7, 0, 7]] - -0.00033593422820483651 # B[1330, [33, 6, 0, 6], [44, 7, 1, 8]] - -0.00061665800523461739 # B[1331, [33, 6, 0, 6], [45, 7, 2, 7]] - -0.000258302532232180387 # B[1332, [33, 6, 0, 6], [46, 7, 3, 8]] - 3.78181072490033077e-05 # B[1333, [33, 6, 0, 6], [47, 7, 4, 7]] - -0.000326273283142861775 # B[1334, [33, 6, 0, 6], [48, 7, 5, 8]] - 1.74277156155672186e-05 # B[1335, [33, 6, 0, 6], [49, 7, 6, 7]] - -0.000206600107910874173 # B[1336, [33, 6, 0, 6], [50, 7, 7, 8]] - 2.12855018918572947e-05 # B[1337, [33, 6, 0, 6], [51, 8, 0, 8]] - -0.000696835386532819456 # B[1338, [33, 6, 0, 6], [52, 8, 2, 8]] - 8.06841007746916805e-05 # B[1339, [33, 6, 0, 6], [53, 8, 4, 8]] - 1.96129469472779844e-05 # B[1340, [33, 6, 0, 6], [54, 8, 6, 8]] - 7.35114191380559223e-05 # B[1341, [33, 6, 0, 6], [55, 8, 8, 8]] - 0.00360109138862139185 # B[1342, [34, 6, 1, 7], [34, 6, 1, 7]] - 0.00304872474261531218 # B[1343, [34, 6, 1, 7], [35, 6, 2, 6]] - -0.00546316824530662139 # B[1344, [34, 6, 1, 7], [36, 6, 2, 8]] - 0.000721988419001898946 # B[1345, [34, 6, 1, 7], [37, 6, 3, 7]] - -0.00254968694435141717 # B[1346, [34, 6, 1, 7], [38, 6, 4, 6]] - -0.00102187793811427596 # B[1347, [34, 6, 1, 7], [39, 6, 4, 8]] - 0.000977866285507509106 # B[1348, [34, 6, 1, 7], [40, 6, 5, 7]] - 0.00129156024637028417 # B[1349, [34, 6, 1, 7], [41, 6, 6, 6]] - 8.43980229575398005e-05 # B[1350, [34, 6, 1, 7], [42, 6, 6, 8]] - -0.000854491821273548058 # B[1351, [34, 6, 1, 7], [43, 7, 0, 7]] - -0.00229655360277009144 # B[1352, [34, 6, 1, 7], [44, 7, 1, 8]] - 0.00392740594657482126 # B[1353, [34, 6, 1, 7], [45, 7, 2, 7]] - 0.00282086313880587115 # B[1354, [34, 6, 1, 7], [46, 7, 3, 8]] - -0.00269367822401865922 # B[1355, [34, 6, 1, 7], [47, 7, 4, 7]] - 0.00120544917432826269 # B[1356, [34, 6, 1, 7], [48, 7, 5, 8]] - 0.00137213082032611872 # B[1357, [34, 6, 1, 7], [49, 7, 6, 7]] - 0.00278774897747785522 # B[1358, [34, 6, 1, 7], [50, 7, 7, 8]] - -1.00075929411755707e-05 # B[1359, [34, 6, 1, 7], [51, 8, 0, 8]] - 0.00331402709384703321 # B[1360, [34, 6, 1, 7], [52, 8, 2, 8]] - -0.00220016465090739841 # B[1361, [34, 6, 1, 7], [53, 8, 4, 8]] - 0.000794479619849004434 # B[1362, [34, 6, 1, 7], [54, 8, 6, 8]] - 0.000207117210070053084 # B[1363, [34, 6, 1, 7], [55, 8, 8, 8]] - 0.000547206364960122621 # B[1364, [35, 6, 2, 6], [35, 6, 2, 6]] - 0.00243529980905243717 # B[1365, [35, 6, 2, 6], [36, 6, 2, 8]] - 0.000346076245330416421 # B[1366, [35, 6, 2, 6], [37, 6, 3, 7]] - 0.00220550296989585788 # B[1367, [35, 6, 2, 6], [38, 6, 4, 6]] - 0.00101934408216735467 # B[1368, [35, 6, 2, 6], [39, 6, 4, 8]] - 6.76995447894471192e-05 # B[1369, [35, 6, 2, 6], [40, 6, 5, 7]] - -4.61734905116591154e-05 # B[1370, [35, 6, 2, 6], [41, 6, 6, 6]] - 0.000809543629624515093 # B[1371, [35, 6, 2, 6], [42, 6, 6, 8]] - 0.000219078295465409238 # B[1372, [35, 6, 2, 6], [43, 7, 0, 7]] - -0.00316872925249137884 # B[1373, [35, 6, 2, 6], [44, 7, 1, 8]] - 0.000676713636760976206 # B[1374, [35, 6, 2, 6], [45, 7, 2, 7]] - -0.00100477918211841141 # B[1375, [35, 6, 2, 6], [46, 7, 3, 8]] - 0.000400524978896980161 # B[1376, [35, 6, 2, 6], [47, 7, 4, 7]] - -0.00197634098305848622 # B[1377, [35, 6, 2, 6], [48, 7, 5, 8]] - 0.000367979983554051621 # B[1378, [35, 6, 2, 6], [49, 7, 6, 7]] - -0.00126672502130457942 # B[1379, [35, 6, 2, 6], [50, 7, 7, 8]] - 0.000161373464169148675 # B[1380, [35, 6, 2, 6], [51, 8, 0, 8]] - 0.00258770627559228462 # B[1381, [35, 6, 2, 6], [52, 8, 2, 8]] - 0.000816135012742828661 # B[1382, [35, 6, 2, 6], [53, 8, 4, 8]] - -3.28991122771973843e-05 # B[1383, [35, 6, 2, 6], [54, 8, 6, 8]] - -4.18127338362338707e-05 # B[1384, [35, 6, 2, 6], [55, 8, 8, 8]] - 0.00658745572292138409 # B[1385, [36, 6, 2, 8], [36, 6, 2, 8]] - -0.00238764687643479301 # B[1386, [36, 6, 2, 8], [37, 6, 3, 7]] - -0.000831950910425274803 # B[1387, [36, 6, 2, 8], [38, 6, 4, 6]] - 0.00351737364404769177 # B[1388, [36, 6, 2, 8], [39, 6, 4, 8]] - -0.00276293358095670936 # B[1389, [36, 6, 2, 8], [40, 6, 5, 7]] - -0.00115031008308692437 # B[1390, [36, 6, 2, 8], [41, 6, 6, 6]] - -0.000921624256609663434 # B[1391, [36, 6, 2, 8], [42, 6, 6, 8]] - 0.000810924380859275734 # B[1392, [36, 6, 2, 8], [43, 7, 0, 7]] - -0.00488922361819911239 # B[1393, [36, 6, 2, 8], [44, 7, 1, 8]] - 0.00170426259508682162 # B[1394, [36, 6, 2, 8], [45, 7, 2, 7]] - -0.000698037236981145087 # B[1395, [36, 6, 2, 8], [46, 7, 3, 8]] - -0.00159293071425275958 # B[1396, [36, 6, 2, 8], [47, 7, 4, 7]] - 0.00145526568566858513 # B[1397, [36, 6, 2, 8], [48, 7, 5, 8]] - -0.0034526631911915729 # B[1398, [36, 6, 2, 8], [49, 7, 6, 7]] - 0.00136118079841816148 # B[1399, [36, 6, 2, 8], [50, 7, 7, 8]] - -0.000519558666561149851 # B[1400, [36, 6, 2, 8], [51, 8, 0, 8]] - -0.00125430728243427136 # B[1401, [36, 6, 2, 8], [52, 8, 2, 8]] - 0.000225746730173992209 # B[1402, [36, 6, 2, 8], [53, 8, 4, 8]] - 0.000144081610870761424 # B[1403, [36, 6, 2, 8], [54, 8, 6, 8]] - 0.000848192939185923693 # B[1404, [36, 6, 2, 8], [55, 8, 8, 8]] - 0.00209760366601450393 # B[1405, [37, 6, 3, 7], [37, 6, 3, 7]] - -0.00114098142783233825 # B[1406, [37, 6, 3, 7], [38, 6, 4, 6]] - -0.00012482798433224862 # B[1407, [37, 6, 3, 7], [39, 6, 4, 8]] - 0.000414303981445450498 # B[1408, [37, 6, 3, 7], [40, 6, 5, 7]] - -2.06949976952613968e-05 # B[1409, [37, 6, 3, 7], [41, 6, 6, 6]] - 0.000986658381613915447 # B[1410, [37, 6, 3, 7], [42, 6, 6, 8]] - 0.000196361012595618056 # B[1411, [37, 6, 3, 7], [43, 7, 0, 7]] - 0.000421620511108736218 # B[1412, [37, 6, 3, 7], [44, 7, 1, 8]] - -0.00121366957406692996 # B[1413, [37, 6, 3, 7], [45, 7, 2, 7]] - 0.000319772245183778947 # B[1414, [37, 6, 3, 7], [46, 7, 3, 8]] - -0.00189440310525268441 # B[1415, [37, 6, 3, 7], [47, 7, 4, 7]] - -0.000420808921505540223 # B[1416, [37, 6, 3, 7], [48, 7, 5, 8]] - -0.000833056882638676111 # B[1417, [37, 6, 3, 7], [49, 7, 6, 7]] - -0.000210394181928773294 # B[1418, [37, 6, 3, 7], [50, 7, 7, 8]] - 4.67415997983874898e-05 # B[1419, [37, 6, 3, 7], [51, 8, 0, 8]] - -0.000629437221263145228 # B[1420, [37, 6, 3, 7], [52, 8, 2, 8]] - -0.000561739301858470846 # B[1421, [37, 6, 3, 7], [53, 8, 4, 8]] - -0.000244403089656959616 # B[1422, [37, 6, 3, 7], [54, 8, 6, 8]] - 0.000170058213410727299 # B[1423, [37, 6, 3, 7], [55, 8, 8, 8]] - 0.000190580820336867102 # B[1424, [38, 6, 4, 6], [38, 6, 4, 6]] - -5.17086422710446442e-05 # B[1425, [38, 6, 4, 6], [39, 6, 4, 8]] - -0.000870479233908965505 # B[1426, [38, 6, 4, 6], [40, 6, 5, 7]] - 8.56431173592298034e-05 # B[1427, [38, 6, 4, 6], [41, 6, 6, 6]] - -0.000219028113680014638 # B[1428, [38, 6, 4, 6], [42, 6, 6, 8]] - 6.99094597341239771e-05 # B[1429, [38, 6, 4, 6], [43, 7, 0, 7]] - -0.00217214753267054063 # B[1430, [38, 6, 4, 6], [44, 7, 1, 8]] - 0.00103452950595812193 # B[1431, [38, 6, 4, 6], [45, 7, 2, 7]] - 0.000131158053198399821 # B[1432, [38, 6, 4, 6], [46, 7, 3, 8]] - -0.000991288929959081421 # B[1433, [38, 6, 4, 6], [47, 7, 4, 7]] - -0.000321058899826150157 # B[1434, [38, 6, 4, 6], [48, 7, 5, 8]] - -0.000126379357764709599 # B[1435, [38, 6, 4, 6], [49, 7, 6, 7]] - 0.000513859397020456632 # B[1436, [38, 6, 4, 6], [50, 7, 7, 8]] - -2.72482190626921472e-05 # B[1437, [38, 6, 4, 6], [51, 8, 0, 8]] - 0.000742781076179950886 # B[1438, [38, 6, 4, 6], [52, 8, 2, 8]] - -9.17701606060090935e-05 # B[1439, [38, 6, 4, 6], [53, 8, 4, 8]] - 1.49768390447675703e-05 # B[1440, [38, 6, 4, 6], [54, 8, 6, 8]] - -5.94521118466549703e-05 # B[1441, [38, 6, 4, 6], [55, 8, 8, 8]] - 0.00161400415689978271 # B[1442, [39, 6, 4, 8], [39, 6, 4, 8]] - -0.000149892220376375129 # B[1443, [39, 6, 4, 8], [40, 6, 5, 7]] - -0.000242832088631229209 # B[1444, [39, 6, 4, 8], [41, 6, 6, 6]] - -4.23223006292567511e-05 # B[1445, [39, 6, 4, 8], [42, 6, 6, 8]] - 0.000145544599928226076 # B[1446, [39, 6, 4, 8], [43, 7, 0, 7]] - -0.000846976149028450323 # B[1447, [39, 6, 4, 8], [44, 7, 1, 8]] - 0.000313402576083809947 # B[1448, [39, 6, 4, 8], [45, 7, 2, 7]] - -0.00105304559168569421 # B[1449, [39, 6, 4, 8], [46, 7, 3, 8]] - -0.000563622717067245593 # B[1450, [39, 6, 4, 8], [47, 7, 4, 7]] - -0.000176248327800098206 # B[1451, [39, 6, 4, 8], [48, 7, 5, 8]] - -0.000523005481859822874 # B[1452, [39, 6, 4, 8], [49, 7, 6, 7]] - 0.000327425878709725754 # B[1453, [39, 6, 4, 8], [50, 7, 7, 8]] - -0.000214075091648432969 # B[1454, [39, 6, 4, 8], [51, 8, 0, 8]] - 0.000892962890338189208 # B[1455, [39, 6, 4, 8], [52, 8, 2, 8]] - 0.000483016760753301674 # B[1456, [39, 6, 4, 8], [53, 8, 4, 8]] - 0.000385986009520520711 # B[1457, [39, 6, 4, 8], [54, 8, 6, 8]] - 0.000210387221014841225 # B[1458, [39, 6, 4, 8], [55, 8, 8, 8]] - 0.000423894835630976054 # B[1459, [40, 6, 5, 7], [40, 6, 5, 7]] - 2.52152593651043533e-05 # B[1460, [40, 6, 5, 7], [41, 6, 6, 6]] - 0.0001406783760301792 # B[1461, [40, 6, 5, 7], [42, 6, 6, 8]] - -0.000402862939603353815 # B[1462, [40, 6, 5, 7], [43, 7, 0, 7]] - -0.000764679971924708997 # B[1463, [40, 6, 5, 7], [44, 7, 1, 8]] - 0.000690122720081854865 # B[1464, [40, 6, 5, 7], [45, 7, 2, 7]] - 0.00135911524951161378 # B[1465, [40, 6, 5, 7], [46, 7, 3, 8]] - 5.52075818169902449e-06 # B[1466, [40, 6, 5, 7], [47, 7, 4, 7]] - -0.000149902773226399076 # B[1467, [40, 6, 5, 7], [48, 7, 5, 8]] - 0.000389894625400750289 # B[1468, [40, 6, 5, 7], [49, 7, 6, 7]] - 0.000257807843360047251 # B[1469, [40, 6, 5, 7], [50, 7, 7, 8]] - -3.67912373811542237e-05 # B[1470, [40, 6, 5, 7], [51, 8, 0, 8]] - -0.000174743024771516643 # B[1471, [40, 6, 5, 7], [52, 8, 2, 8]] - 0.000276798622678277838 # B[1472, [40, 6, 5, 7], [53, 8, 4, 8]] - 0.000152459620483783032 # B[1473, [40, 6, 5, 7], [54, 8, 6, 8]] - -0.000616599602238733502 # B[1474, [40, 6, 5, 7], [55, 8, 8, 8]] - -5.12324624723156652e-05 # B[1475, [41, 6, 6, 6], [41, 6, 6, 6]] - -4.23334509430418893e-05 # B[1476, [41, 6, 6, 6], [42, 6, 6, 8]] - -0.000111212733055157664 # B[1477, [41, 6, 6, 6], [43, 7, 0, 7]] - 0.000882360189618891337 # B[1478, [41, 6, 6, 6], [44, 7, 1, 8]] - -0.000581964842687935843 # B[1479, [41, 6, 6, 6], [45, 7, 2, 7]] - 0.000211138997961872465 # B[1480, [41, 6, 6, 6], [46, 7, 3, 8]] - 7.79906436828414068e-05 # B[1481, [41, 6, 6, 6], [47, 7, 4, 7]] - -0.000201461425275273331 # B[1482, [41, 6, 6, 6], [48, 7, 5, 8]] - 6.87828589884392771e-05 # B[1483, [41, 6, 6, 6], [49, 7, 6, 7]] - 0.000150653067204437052 # B[1484, [41, 6, 6, 6], [50, 7, 7, 8]] - 3.87532549918634395e-05 # B[1485, [41, 6, 6, 6], [51, 8, 0, 8]] - 0.000361299779465781672 # B[1486, [41, 6, 6, 6], [52, 8, 2, 8]] - -0.000217385549744270783 # B[1487, [41, 6, 6, 6], [53, 8, 4, 8]] - 6.09508622621875856e-05 # B[1488, [41, 6, 6, 6], [54, 8, 6, 8]] - -0.000174447165900721429 # B[1489, [41, 6, 6, 6], [55, 8, 8, 8]] - 4.08451735536830007e-05 # B[1490, [42, 6, 6, 8], [42, 6, 6, 8]] - -0.000100109250872669128 # B[1491, [42, 6, 6, 8], [43, 7, 0, 7]] - 0.000543796967600337564 # B[1492, [42, 6, 6, 8], [44, 7, 1, 8]] - 0.000744432946735457124 # B[1493, [42, 6, 6, 8], [45, 7, 2, 7]] - 0.0010803210667922683 # B[1494, [42, 6, 6, 8], [46, 7, 3, 8]] - 0.000151445105968722347 # B[1495, [42, 6, 6, 8], [47, 7, 4, 7]] - -0.000100848877598445907 # B[1496, [42, 6, 6, 8], [48, 7, 5, 8]] - -0.000109088350721993355 # B[1497, [42, 6, 6, 8], [49, 7, 6, 7]] - -0.000287924009882135207 # B[1498, [42, 6, 6, 8], [50, 7, 7, 8]] - 1.48405987461727729e-05 # B[1499, [42, 6, 6, 8], [51, 8, 0, 8]] - 0.00133229142431166023 # B[1500, [42, 6, 6, 8], [52, 8, 2, 8]] - -0.00019157481902659472 # B[1501, [42, 6, 6, 8], [53, 8, 4, 8]] - -0.000214414469154704246 # B[1502, [42, 6, 6, 8], [54, 8, 6, 8]] - -0.000145460173238021184 # B[1503, [42, 6, 6, 8], [55, 8, 8, 8]] - 0.000122164068846408735 # B[1504, [43, 7, 0, 7], [43, 7, 0, 7]] - -0.000271198052548764657 # B[1505, [43, 7, 0, 7], [44, 7, 1, 8]] - -7.53020792218089818e-05 # B[1506, [43, 7, 0, 7], [45, 7, 2, 7]] - -0.000522043739406908344 # B[1507, [43, 7, 0, 7], [46, 7, 3, 8]] - -4.818852612961666e-05 # B[1508, [43, 7, 0, 7], [47, 7, 4, 7]] - -0.000220542438614808323 # B[1509, [43, 7, 0, 7], [48, 7, 5, 8]] - -0.000160998835878327362 # B[1510, [43, 7, 0, 7], [49, 7, 6, 7]] - -2.41628428966911279e-05 # B[1511, [43, 7, 0, 7], [50, 7, 7, 8]] - -1.41474469189661889e-05 # B[1512, [43, 7, 0, 7], [51, 8, 0, 8]] - -0.000160534811881916234 # B[1513, [43, 7, 0, 7], [52, 8, 2, 8]] - -1.73735621299461046e-05 # B[1514, [43, 7, 0, 7], [53, 8, 4, 8]] - 4.73251016045242445e-05 # B[1515, [43, 7, 0, 7], [54, 8, 6, 8]] - 0.000182463508348683356 # B[1516, [43, 7, 0, 7], [55, 8, 8, 8]] - -0.000629134879565343137 # B[1517, [44, 7, 1, 8], [44, 7, 1, 8]] - -0.00207361578267727673 # B[1518, [44, 7, 1, 8], [45, 7, 2, 7]] - 0.0031686999001355326 # B[1519, [44, 7, 1, 8], [46, 7, 3, 8]] - -0.000405403647932546952 # B[1520, [44, 7, 1, 8], [47, 7, 4, 7]] - -0.000111251617971438489 # B[1521, [44, 7, 1, 8], [48, 7, 5, 8]] - 0.0014482690523848242 # B[1522, [44, 7, 1, 8], [49, 7, 6, 7]] - 0.000818892450912583197 # B[1523, [44, 7, 1, 8], [50, 7, 7, 8]] - 0.000100422502558870572 # B[1524, [44, 7, 1, 8], [51, 8, 0, 8]] - -0.000412863674396233161 # B[1525, [44, 7, 1, 8], [52, 8, 2, 8]] - -0.000905494278120194153 # B[1526, [44, 7, 1, 8], [53, 8, 4, 8]] - 0.00126932173443552359 # B[1527, [44, 7, 1, 8], [54, 8, 6, 8]] - -0.000374814469421512735 # B[1528, [44, 7, 1, 8], [55, 8, 8, 8]] - -0.00330341133748704441 # B[1529, [45, 7, 2, 7], [45, 7, 2, 7]] - 0.00131616674488897398 # B[1530, [45, 7, 2, 7], [46, 7, 3, 8]] - -0.000483635326292886428 # B[1531, [45, 7, 2, 7], [47, 7, 4, 7]] - -0.00177550615332965067 # B[1532, [45, 7, 2, 7], [48, 7, 5, 8]] - 0.00226091969304176299 # B[1533, [45, 7, 2, 7], [49, 7, 6, 7]] - -0.00142635978155006456 # B[1534, [45, 7, 2, 7], [50, 7, 7, 8]] - 0.000289476939908078768 # B[1535, [45, 7, 2, 7], [51, 8, 0, 8]] - 0.000582488578419503846 # B[1536, [45, 7, 2, 7], [52, 8, 2, 8]] - -0.000228795123723987606 # B[1537, [45, 7, 2, 7], [53, 8, 4, 8]] - 0.000478658611037000373 # B[1538, [45, 7, 2, 7], [54, 8, 6, 8]] - -0.00101956994563059782 # B[1539, [45, 7, 2, 7], [55, 8, 8, 8]] - 0.00268648192223141895 # B[1540, [46, 7, 3, 8], [46, 7, 3, 8]] - 0.000515570689344949529 # B[1541, [46, 7, 3, 8], [47, 7, 4, 7]] - 0.000903689215066725768 # B[1542, [46, 7, 3, 8], [48, 7, 5, 8]] - 0.00180650309403464215 # B[1543, [46, 7, 3, 8], [49, 7, 6, 7]] - -7.48574841450792838e-05 # B[1544, [46, 7, 3, 8], [50, 7, 7, 8]] - -2.90930360741237237e-05 # B[1545, [46, 7, 3, 8], [51, 8, 0, 8]] - 0.00139057844941538594 # B[1546, [46, 7, 3, 8], [52, 8, 2, 8]] - -0.000263907165716330272 # B[1547, [46, 7, 3, 8], [53, 8, 4, 8]] - -5.74521512815137289e-05 # B[1548, [46, 7, 3, 8], [54, 8, 6, 8]] - -0.00030234445629373323 # B[1549, [46, 7, 3, 8], [55, 8, 8, 8]] - -0.000842080339294604824 # B[1550, [47, 7, 4, 7], [47, 7, 4, 7]] - -1.8677234631915389e-05 # B[1551, [47, 7, 4, 7], [48, 7, 5, 8]] - 0.000150434033167294937 # B[1552, [47, 7, 4, 7], [49, 7, 6, 7]] - 0.000201922161197246736 # B[1553, [47, 7, 4, 7], [50, 7, 7, 8]] - 5.63689077359152968e-05 # B[1554, [47, 7, 4, 7], [51, 8, 0, 8]] - 0.000490229079971716761 # B[1555, [47, 7, 4, 7], [52, 8, 2, 8]] - -0.00019335269881828529 # B[1556, [47, 7, 4, 7], [53, 8, 4, 8]] - -0.000118664083374402096 # B[1557, [47, 7, 4, 7], [54, 8, 6, 8]] - -0.000397263359111398734 # B[1558, [47, 7, 4, 7], [55, 8, 8, 8]] - -0.000724261739409587726 # B[1559, [48, 7, 5, 8], [48, 7, 5, 8]] - 0.000186853474209224685 # B[1560, [48, 7, 5, 8], [49, 7, 6, 7]] - -0.000533321040010020266 # B[1561, [48, 7, 5, 8], [50, 7, 7, 8]] - 9.95102706208284005e-08 # B[1562, [48, 7, 5, 8], [51, 8, 0, 8]] - -0.00093755398196557671 # B[1563, [48, 7, 5, 8], [52, 8, 2, 8]] - 0.000483236780374178207 # B[1564, [48, 7, 5, 8], [53, 8, 4, 8]] - -5.03524206302112531e-05 # B[1565, [48, 7, 5, 8], [54, 8, 6, 8]] - -0.000586245052440398373 # B[1566, [48, 7, 5, 8], [55, 8, 8, 8]] - -0.000207118017941997773 # B[1567, [49, 7, 6, 7], [49, 7, 6, 7]] - -9.40116364012005823e-05 # B[1568, [49, 7, 6, 7], [50, 7, 7, 8]] - 0.000124266884770383307 # B[1569, [49, 7, 6, 7], [51, 8, 0, 8]] - 0.00118479186165786239 # B[1570, [49, 7, 6, 7], [52, 8, 2, 8]] - -0.000129238345120056067 # B[1571, [49, 7, 6, 7], [53, 8, 4, 8]] - -0.000383875224777865259 # B[1572, [49, 7, 6, 7], [54, 8, 6, 8]] - -0.000457194559055141767 # B[1573, [49, 7, 6, 7], [55, 8, 8, 8]] - -0.000450510261664234871 # B[1574, [50, 7, 7, 8], [50, 7, 7, 8]] - 7.52704593073999506e-05 # B[1575, [50, 7, 7, 8], [51, 8, 0, 8]] - -0.00128732840082427732 # B[1576, [50, 7, 7, 8], [52, 8, 2, 8]] - 0.000293225651298797269 # B[1577, [50, 7, 7, 8], [53, 8, 4, 8]] - -0.000306521733645761033 # B[1578, [50, 7, 7, 8], [54, 8, 6, 8]] - -0.000370268243746852549 # B[1579, [50, 7, 7, 8], [55, 8, 8, 8]] - -4.00747887657759705e-06 # B[1580, [51, 8, 0, 8], [51, 8, 0, 8]] - -0.000179079356204300821 # B[1581, [51, 8, 0, 8], [52, 8, 2, 8]] - -6.37205046857824975e-06 # B[1582, [51, 8, 0, 8], [53, 8, 4, 8]] - 5.20087282658288075e-05 # B[1583, [51, 8, 0, 8], [54, 8, 6, 8]] - 6.68015373273544988e-05 # B[1584, [51, 8, 0, 8], [55, 8, 8, 8]] - 0.00160592146390294661 # B[1585, [52, 8, 2, 8], [52, 8, 2, 8]] - 0.000454049229948232103 # B[1586, [52, 8, 2, 8], [53, 8, 4, 8]] - 0.00110675066334388339 # B[1587, [52, 8, 2, 8], [54, 8, 6, 8]] - -0.000191060465051852771 # B[1588, [52, 8, 2, 8], [55, 8, 8, 8]] - -0.000131765455753670314 # B[1589, [53, 8, 4, 8], [53, 8, 4, 8]] - -7.05704764431217685e-05 # B[1590, [53, 8, 4, 8], [54, 8, 6, 8]] - -1.82263105369812051e-05 # B[1591, [53, 8, 4, 8], [55, 8, 8, 8]] - -0.00032731873727259329 # B[1592, [54, 8, 6, 8], [54, 8, 6, 8]] - -0.000198178389384386089 # B[1593, [54, 8, 6, 8], [55, 8, 8, 8]] - -0.000136309758672861769 # B[1594, [55, 8, 8, 8], [55, 8, 8, 8]] - -# End of potential \ No newline at end of file From 115c9ee3afffb2436b501ed655f37116192ba361 Mon Sep 17 00:00:00 2001 From: jwillma2 <52575231+jwillma2@users.noreply.github.com> Date: Tue, 21 Mar 2023 23:14:18 -0400 Subject: [PATCH 049/448] Add files via upload --- .../C_Willman_PRB2022.quadratic.snapcoeff | 1602 +++++++++++++++++ 1 file changed, 1602 insertions(+) create mode 100644 potentials/C_Willman_PRB2022.quadratic.snapcoeff diff --git a/potentials/C_Willman_PRB2022.quadratic.snapcoeff b/potentials/C_Willman_PRB2022.quadratic.snapcoeff new file mode 100644 index 0000000000..d5e6b79acb --- /dev/null +++ b/potentials/C_Willman_PRB2022.quadratic.snapcoeff @@ -0,0 +1,1602 @@ +# fitsnap fit generated on 2021-10-15 08:21:38.396384 +#UNITS: metal CONTRIBUTOR: Ivan Oleynik CITATION: Jonathan T. Willman, Kien Nguyen-Cong, Ashley S. Williams, Anatoly B. Belonoshko, Stan G. Moore, Aidan P. Thompson, Mitchell A. Wood, and Ivan I. Oleynik, "Machine learning interatomic potential for simulations of carbon at extreme conditions" Phys. Rev. B 106, L180101 (2022) +1 1596 +C 0.5 1.0 + -2.7758927591660334 # B[0] + 0.00859216942217639126 # B[1, 0, 0, 0] + 0.16638458601459194 # B[2, 1, 0, 1] + 0.22261822339506554 # B[3, 1, 1, 2] + 0.257355166247009937 # B[4, 2, 0, 2] + 0.802105904460230779 # B[5, 2, 1, 3] + 0.227216469467176801 # B[6, 2, 2, 2] + 0.494646284119575508 # B[7, 2, 2, 4] + 0.276718638025069574 # B[8, 3, 0, 3] + 1.09101782892605392 # B[9, 3, 1, 4] + 0.775283725099378151 # B[10, 3, 2, 3] + -0.232869556477520168 # B[11, 3, 2, 5] + 0.188466708736270222 # B[12, 3, 3, 4] + -0.213463540195325957 # B[13, 3, 3, 6] + 0.285049005401720568 # B[14, 4, 0, 4] + -0.248039138369940321 # B[15, 4, 1, 5] + -0.017694405190132434 # B[16, 4, 2, 4] + -0.513770238875468355 # B[17, 4, 2, 6] + -0.603368424950793791 # B[18, 4, 3, 5] + -0.4245149972360448 # B[19, 4, 3, 7] + -0.149612637312833391 # B[20, 4, 4, 4] + -0.153415086019898006 # B[21, 4, 4, 6] + -0.14513624400298164 # B[22, 4, 4, 8] + -0.0460661393681677661 # B[23, 5, 0, 5] + -0.0512559726916635844 # B[24, 5, 1, 6] + -0.125285455697324882 # B[25, 5, 2, 5] + -0.297464016341802473 # B[26, 5, 2, 7] + -0.219930176940332595 # B[27, 5, 3, 6] + -0.195418601625407001 # B[28, 5, 3, 8] + -0.236454956825408069 # B[29, 5, 4, 5] + -0.247483318285177556 # B[30, 5, 4, 7] + 0.108404148378543994 # B[31, 5, 5, 6] + 0.102786344334006338 # B[32, 5, 5, 8] + -0.0174963987262215619 # B[33, 6, 0, 6] + -0.347663919737827065 # B[34, 6, 1, 7] + -0.308777238806140442 # B[35, 6, 2, 6] + -0.30366671620990171 # B[36, 6, 2, 8] + -0.190992135157848048 # B[37, 6, 3, 7] + -0.212717125362634818 # B[38, 6, 4, 6] + -0.127682310305149815 # B[39, 6, 4, 8] + 0.128955786755968027 # B[40, 6, 5, 7] + 0.108121871413745185 # B[41, 6, 6, 6] + 0.0951564970231452284 # B[42, 6, 6, 8] + -0.0443430969083889667 # B[43, 7, 0, 7] + 0.0394012265947801602 # B[44, 7, 1, 8] + 0.0238287662182333909 # B[45, 7, 2, 7] + -0.0703216614205220136 # B[46, 7, 3, 8] + -0.0229748587995626564 # B[47, 7, 4, 7] + 0.461615758896215367 # B[48, 7, 5, 8] + 0.032037855993324961 # B[49, 7, 6, 7] + 0.105399776101016598 # B[50, 7, 7, 8] + -0.0452778356788145764 # B[51, 8, 0, 8] + -0.0400452652333231421 # B[52, 8, 2, 8] + -0.152415456089667084 # B[53, 8, 4, 8] + 0.0303383368396002995 # B[54, 8, 6, 8] + 0.0660845112300222914 # B[55, 8, 8, 8] + 5.0022584003536763e-06 # B[55, [1, 0, 0, 0], [1, 0, 0, 0]] + 7.12434860521689133e-05 # B[56, [1, 0, 0, 0], [2, 1, 0, 1]] + 0.00410559459459784552 # B[57, [1, 0, 0, 0], [3, 1, 1, 2]] + -0.000152151102822628559 # B[58, [1, 0, 0, 0], [4, 2, 0, 2]] + -0.00104851962847402839 # B[59, [1, 0, 0, 0], [5, 2, 1, 3]] + 0.00174544590749468355 # B[60, [1, 0, 0, 0], [6, 2, 2, 2]] + -0.00039686396723943862 # B[61, [1, 0, 0, 0], [7, 2, 2, 4]] + 0.000344474173032960351 # B[62, [1, 0, 0, 0], [8, 3, 0, 3]] + 5.77832175303926235e-05 # B[63, [1, 0, 0, 0], [9, 3, 1, 4]] + 0.00124014860085090543 # B[64, [1, 0, 0, 0], [10, 3, 2, 3]] + 1.92520730655986946e-05 # B[65, [1, 0, 0, 0], [11, 3, 2, 5]] + -0.000659022869027497959 # B[66, [1, 0, 0, 0], [12, 3, 3, 4]] + -0.000296998157394604001 # B[67, [1, 0, 0, 0], [13, 3, 3, 6]] + 2.13348987737616014e-06 # B[68, [1, 0, 0, 0], [14, 4, 0, 4]] + -0.000377679899824956422 # B[69, [1, 0, 0, 0], [15, 4, 1, 5]] + 0.00045743496488695988 # B[70, [1, 0, 0, 0], [16, 4, 2, 4]] + -0.00047978616167941926 # B[71, [1, 0, 0, 0], [17, 4, 2, 6]] + -0.000346601408372410741 # B[72, [1, 0, 0, 0], [18, 4, 3, 5]] + -0.000216752459512900564 # B[73, [1, 0, 0, 0], [19, 4, 3, 7]] + -0.000153945954064437646 # B[74, [1, 0, 0, 0], [20, 4, 4, 4]] + 0.00029484781857681483 # B[75, [1, 0, 0, 0], [21, 4, 4, 6]] + 1.59236973873017051e-05 # B[76, [1, 0, 0, 0], [22, 4, 4, 8]] + -2.35544935613951623e-05 # B[77, [1, 0, 0, 0], [23, 5, 0, 5]] + 0.000492019807872501325 # B[78, [1, 0, 0, 0], [24, 5, 1, 6]] + 0.000376700986017126233 # B[79, [1, 0, 0, 0], [25, 5, 2, 5]] + -0.000185900021989794662 # B[80, [1, 0, 0, 0], [26, 5, 2, 7]] + 0.000219939447169378507 # B[81, [1, 0, 0, 0], [27, 5, 3, 6]] + -0.000192198129806066265 # B[82, [1, 0, 0, 0], [28, 5, 3, 8]] + 0.000175514531344928004 # B[83, [1, 0, 0, 0], [29, 5, 4, 5]] + 0.000261949015135925535 # B[84, [1, 0, 0, 0], [30, 5, 4, 7]] + 0.00021011408484750832 # B[85, [1, 0, 0, 0], [31, 5, 5, 6]] + -7.47807464450689352e-05 # B[86, [1, 0, 0, 0], [32, 5, 5, 8]] + -1.36809205491805752e-05 # B[87, [1, 0, 0, 0], [33, 6, 0, 6]] + 0.000493576806965066728 # B[88, [1, 0, 0, 0], [34, 6, 1, 7]] + 0.000216301405824667614 # B[89, [1, 0, 0, 0], [35, 6, 2, 6]] + -0.000364540437645548276 # B[90, [1, 0, 0, 0], [36, 6, 2, 8]] + -0.000251411532179113273 # B[91, [1, 0, 0, 0], [37, 6, 3, 7]] + 3.19331690196988927e-05 # B[92, [1, 0, 0, 0], [38, 6, 4, 6]] + -1.56092571080845843e-05 # B[93, [1, 0, 0, 0], [39, 6, 4, 8]] + 2.4859429830464963e-05 # B[94, [1, 0, 0, 0], [40, 6, 5, 7]] + -5.06306418207175257e-05 # B[95, [1, 0, 0, 0], [41, 6, 6, 6]] + -9.75742047871729079e-05 # B[96, [1, 0, 0, 0], [42, 6, 6, 8]] + -4.07774117821002591e-05 # B[97, [1, 0, 0, 0], [43, 7, 0, 7]] + 0.000169705539551909257 # B[98, [1, 0, 0, 0], [44, 7, 1, 8]] + 0.000261792097012429614 # B[99, [1, 0, 0, 0], [45, 7, 2, 7]] + 0.000235813389494382575 # B[100, [1, 0, 0, 0], [46, 7, 3, 8]] + 3.69194385055615637e-05 # B[101, [1, 0, 0, 0], [47, 7, 4, 7]] + 0.000101832840349036502 # B[102, [1, 0, 0, 0], [48, 7, 5, 8]] + 1.87768621704026417e-05 # B[103, [1, 0, 0, 0], [49, 7, 6, 7]] + 6.90123641682582889e-05 # B[104, [1, 0, 0, 0], [50, 7, 7, 8]] + 3.82281861928956967e-05 # B[105, [1, 0, 0, 0], [51, 8, 0, 8]] + 0.00044905358698343889 # B[106, [1, 0, 0, 0], [52, 8, 2, 8]] + 3.83170337754923374e-05 # B[107, [1, 0, 0, 0], [53, 8, 4, 8]] + -4.53472261485315942e-05 # B[108, [1, 0, 0, 0], [54, 8, 6, 8]] + -0.000105793544360549552 # B[109, [1, 0, 0, 0], [55, 8, 8, 8]] + -0.00542851209933992596 # B[110, [2, 1, 0, 1], [2, 1, 0, 1]] + -0.00800035055604917701 # B[111, [2, 1, 0, 1], [3, 1, 1, 2]] + 0.000279580761847972054 # B[112, [2, 1, 0, 1], [4, 2, 0, 2]] + -0.0132643544617690821 # B[113, [2, 1, 0, 1], [5, 2, 1, 3]] + -0.00300637860380324968 # B[114, [2, 1, 0, 1], [6, 2, 2, 2]] + 0.00343216933390476549 # B[115, [2, 1, 0, 1], [7, 2, 2, 4]] + 6.39026040622058672e-05 # B[116, [2, 1, 0, 1], [8, 3, 0, 3]] + -0.0124005148347727506 # B[117, [2, 1, 0, 1], [9, 3, 1, 4]] + -0.0036690465725984691 # B[118, [2, 1, 0, 1], [10, 3, 2, 3]] + -0.0066468850826254932 # B[119, [2, 1, 0, 1], [11, 3, 2, 5]] + -0.00518212543330048934 # B[120, [2, 1, 0, 1], [12, 3, 3, 4]] + -0.00269613907034030407 # B[121, [2, 1, 0, 1], [13, 3, 3, 6]] + -0.000330193583102013615 # B[122, [2, 1, 0, 1], [14, 4, 0, 4]] + -0.000429062486184235686 # B[123, [2, 1, 0, 1], [15, 4, 1, 5]] + -0.000991704717453613382 # B[124, [2, 1, 0, 1], [16, 4, 2, 4]] + 0.00152944521177345071 # B[125, [2, 1, 0, 1], [17, 4, 2, 6]] + -0.00660856033628089406 # B[126, [2, 1, 0, 1], [18, 4, 3, 5]] + 0.00146758746394204951 # B[127, [2, 1, 0, 1], [19, 4, 3, 7]] + -0.00161093753941019967 # B[128, [2, 1, 0, 1], [20, 4, 4, 4]] + -0.00101484284665418574 # B[129, [2, 1, 0, 1], [21, 4, 4, 6]] + 0.00150269420364470413 # B[130, [2, 1, 0, 1], [22, 4, 4, 8]] + -0.000251279508914979688 # B[131, [2, 1, 0, 1], [23, 5, 0, 5]] + 0.00427791921512100763 # B[132, [2, 1, 0, 1], [24, 5, 1, 6]] + -0.00312327633171666707 # B[133, [2, 1, 0, 1], [25, 5, 2, 5]] + 0.00145518956483171066 # B[134, [2, 1, 0, 1], [26, 5, 2, 7]] + -0.00296392629706135422 # B[135, [2, 1, 0, 1], [27, 5, 3, 6]] + 0.00106990236696331148 # B[136, [2, 1, 0, 1], [28, 5, 3, 8]] + 0.000140740776400729824 # B[137, [2, 1, 0, 1], [29, 5, 4, 5]] + -0.000704484148092703912 # B[138, [2, 1, 0, 1], [30, 5, 4, 7]] + 0.000555926138942124939 # B[139, [2, 1, 0, 1], [31, 5, 5, 6]] + 0.000749361142656781065 # B[140, [2, 1, 0, 1], [32, 5, 5, 8]] + -0.000275563231062828096 # B[141, [2, 1, 0, 1], [33, 6, 0, 6]] + 0.00404287546990938183 # B[142, [2, 1, 0, 1], [34, 6, 1, 7]] + -0.00329083016295819491 # B[143, [2, 1, 0, 1], [35, 6, 2, 6]] + 0.00374648670440783874 # B[144, [2, 1, 0, 1], [36, 6, 2, 8]] + -0.000931584323738718183 # B[145, [2, 1, 0, 1], [37, 6, 3, 7]] + 0.001545987588966576 # B[146, [2, 1, 0, 1], [38, 6, 4, 6]] + 0.000136630337825366203 # B[147, [2, 1, 0, 1], [39, 6, 4, 8]] + -0.000338191518470186761 # B[148, [2, 1, 0, 1], [40, 6, 5, 7]] + 0.000383732900037425575 # B[149, [2, 1, 0, 1], [41, 6, 6, 6]] + 0.000891911333988446714 # B[150, [2, 1, 0, 1], [42, 6, 6, 8]] + 0.000372325777048820861 # B[151, [2, 1, 0, 1], [43, 7, 0, 7]] + 0.00203975899324063559 # B[152, [2, 1, 0, 1], [44, 7, 1, 8]] + -0.00366168906366426058 # B[153, [2, 1, 0, 1], [45, 7, 2, 7]] + -0.00217927110231279971 # B[154, [2, 1, 0, 1], [46, 7, 3, 8]] + -0.000355180731966526532 # B[155, [2, 1, 0, 1], [47, 7, 4, 7]] + -0.00190295940654904624 # B[156, [2, 1, 0, 1], [48, 7, 5, 8]] + -0.00045640385432905474 # B[157, [2, 1, 0, 1], [49, 7, 6, 7]] + -0.00123273230096131864 # B[158, [2, 1, 0, 1], [50, 7, 7, 8]] + 2.61749541232737803e-06 # B[159, [2, 1, 0, 1], [51, 8, 0, 8]] + -0.00188736987570012403 # B[160, [2, 1, 0, 1], [52, 8, 2, 8]] + 0.000127235145614493401 # B[161, [2, 1, 0, 1], [53, 8, 4, 8]] + -0.000446185446234578786 # B[162, [2, 1, 0, 1], [54, 8, 6, 8]] + 3.06626149019382718e-05 # B[163, [2, 1, 0, 1], [55, 8, 8, 8]] + 0.00500803145405033512 # B[164, [3, 1, 1, 2], [3, 1, 1, 2]] + 0.0136537265129433767 # B[165, [3, 1, 1, 2], [4, 2, 0, 2]] + 0.00586793418015095231 # B[166, [3, 1, 1, 2], [5, 2, 1, 3]] + 0.0108897828563872673 # B[167, [3, 1, 1, 2], [6, 2, 2, 2]] + 0.000782326392446437181 # B[168, [3, 1, 1, 2], [7, 2, 2, 4]] + -0.00196905235294965193 # B[169, [3, 1, 1, 2], [8, 3, 0, 3]] + -0.00575620599927615263 # B[170, [3, 1, 1, 2], [9, 3, 1, 4]] + -0.0395084171352078836 # B[171, [3, 1, 1, 2], [10, 3, 2, 3]] + -0.0402914809330097226 # B[172, [3, 1, 1, 2], [11, 3, 2, 5]] + -0.031380925125560552 # B[173, [3, 1, 1, 2], [12, 3, 3, 4]] + 0.0074098991236085333 # B[174, [3, 1, 1, 2], [13, 3, 3, 6]] + -0.00144234945688183152 # B[175, [3, 1, 1, 2], [14, 4, 0, 4]] + -0.00715563010950572616 # B[176, [3, 1, 1, 2], [15, 4, 1, 5]] + -0.0068004389765142035 # B[177, [3, 1, 1, 2], [16, 4, 2, 4]] + -0.0397838555572563451 # B[178, [3, 1, 1, 2], [17, 4, 2, 6]] + 0.00335672059516798228 # B[179, [3, 1, 1, 2], [18, 4, 3, 5]] + 0.0148934683418572647 # B[180, [3, 1, 1, 2], [19, 4, 3, 7]] + -0.000967980016249102011 # B[181, [3, 1, 1, 2], [20, 4, 4, 4]] + 0.00772576295059950596 # B[182, [3, 1, 1, 2], [21, 4, 4, 6]] + -0.00450662666899595381 # B[183, [3, 1, 1, 2], [22, 4, 4, 8]] + -0.00395807515027411967 # B[184, [3, 1, 1, 2], [23, 5, 0, 5]] + 0.010414612350238486 # B[185, [3, 1, 1, 2], [24, 5, 1, 6]] + -0.00513372683983254804 # B[186, [3, 1, 1, 2], [25, 5, 2, 5]] + -0.0265398819124704963 # B[187, [3, 1, 1, 2], [26, 5, 2, 7]] + 0.00742434172938952544 # B[188, [3, 1, 1, 2], [27, 5, 3, 6]] + -0.00256386423704287481 # B[189, [3, 1, 1, 2], [28, 5, 3, 8]] + 0.00841179553194743718 # B[190, [3, 1, 1, 2], [29, 5, 4, 5]] + 0.00668617729586690451 # B[191, [3, 1, 1, 2], [30, 5, 4, 7]] + 0.000484464094046739568 # B[192, [3, 1, 1, 2], [31, 5, 5, 6]] + 0.00458460314168420216 # B[193, [3, 1, 1, 2], [32, 5, 5, 8]] + -0.00235318401641824212 # B[194, [3, 1, 1, 2], [33, 6, 0, 6]] + -0.000804392064641467762 # B[195, [3, 1, 1, 2], [34, 6, 1, 7]] + -0.000974349018272668323 # B[196, [3, 1, 1, 2], [35, 6, 2, 6]] + -0.0186467861443154748 # B[197, [3, 1, 1, 2], [36, 6, 2, 8]] + 0.0149394908128317495 # B[198, [3, 1, 1, 2], [37, 6, 3, 7]] + -0.001417773975968062 # B[199, [3, 1, 1, 2], [38, 6, 4, 6]] + 0.00708801668305296916 # B[200, [3, 1, 1, 2], [39, 6, 4, 8]] + 0.00422029817457212405 # B[201, [3, 1, 1, 2], [40, 6, 5, 7]] + 0.00110117813016081525 # B[202, [3, 1, 1, 2], [41, 6, 6, 6]] + -0.00187490884044745794 # B[203, [3, 1, 1, 2], [42, 6, 6, 8]] + -0.00530063898164105998 # B[204, [3, 1, 1, 2], [43, 7, 0, 7]] + 0.0156639815207892212 # B[205, [3, 1, 1, 2], [44, 7, 1, 8]] + 0.0118519420103458811 # B[206, [3, 1, 1, 2], [45, 7, 2, 7]] + 0.00375057568532275679 # B[207, [3, 1, 1, 2], [46, 7, 3, 8]] + 0.00757584350406629962 # B[208, [3, 1, 1, 2], [47, 7, 4, 7]] + 0.0106601777099339986 # B[209, [3, 1, 1, 2], [48, 7, 5, 8]] + -0.0041075690062942552 # B[210, [3, 1, 1, 2], [49, 7, 6, 7]] + 0.00248707997936048041 # B[211, [3, 1, 1, 2], [50, 7, 7, 8]] + -0.0025390217113529746 # B[212, [3, 1, 1, 2], [51, 8, 0, 8]] + 0.00498354453902482165 # B[213, [3, 1, 1, 2], [52, 8, 2, 8]] + 0.00383782774054214912 # B[214, [3, 1, 1, 2], [53, 8, 4, 8]] + 0.00318870204625110783 # B[215, [3, 1, 1, 2], [54, 8, 6, 8]] + -0.00078409267383599678 # B[216, [3, 1, 1, 2], [55, 8, 8, 8]] + 0.00411479420703600093 # B[217, [4, 2, 0, 2], [4, 2, 0, 2]] + -0.00352482696278418658 # B[218, [4, 2, 0, 2], [5, 2, 1, 3]] + 0.00293296373222708129 # B[219, [4, 2, 0, 2], [6, 2, 2, 2]] + -0.00169108240942662173 # B[220, [4, 2, 0, 2], [7, 2, 2, 4]] + -0.00166875839344953099 # B[221, [4, 2, 0, 2], [8, 3, 0, 3]] + -0.00303743189373234653 # B[222, [4, 2, 0, 2], [9, 3, 1, 4]] + -0.00360352002032471395 # B[223, [4, 2, 0, 2], [10, 3, 2, 3]] + -0.00844475258400314774 # B[224, [4, 2, 0, 2], [11, 3, 2, 5]] + -0.00267861760564082688 # B[225, [4, 2, 0, 2], [12, 3, 3, 4]] + 0.00249373694942188646 # B[226, [4, 2, 0, 2], [13, 3, 3, 6]] + 0.00129518789575956 # B[227, [4, 2, 0, 2], [14, 4, 0, 4]] + -0.000616706097657935626 # B[228, [4, 2, 0, 2], [15, 4, 1, 5]] + -0.00374793183827557257 # B[229, [4, 2, 0, 2], [16, 4, 2, 4]] + -0.00725453590077526286 # B[230, [4, 2, 0, 2], [17, 4, 2, 6]] + -0.00328165463874066426 # B[231, [4, 2, 0, 2], [18, 4, 3, 5]] + -0.00387910875571249565 # B[232, [4, 2, 0, 2], [19, 4, 3, 7]] + -0.000691443248665482221 # B[233, [4, 2, 0, 2], [20, 4, 4, 4]] + -0.00364575524119575139 # B[234, [4, 2, 0, 2], [21, 4, 4, 6]] + 0.000579213613942424974 # B[235, [4, 2, 0, 2], [22, 4, 4, 8]] + 0.000382530088889220486 # B[236, [4, 2, 0, 2], [23, 5, 0, 5]] + 0.000700082663528700608 # B[237, [4, 2, 0, 2], [24, 5, 1, 6]] + -0.00303645662419470708 # B[238, [4, 2, 0, 2], [25, 5, 2, 5]] + -0.00412449214914962191 # B[239, [4, 2, 0, 2], [26, 5, 2, 7]] + -0.000863747946010486305 # B[240, [4, 2, 0, 2], [27, 5, 3, 6]] + 0.000597171151136822748 # B[241, [4, 2, 0, 2], [28, 5, 3, 8]] + -0.00290482182317059953 # B[242, [4, 2, 0, 2], [29, 5, 4, 5]] + -0.00218615594313117554 # B[243, [4, 2, 0, 2], [30, 5, 4, 7]] + 0.00120270898159113111 # B[244, [4, 2, 0, 2], [31, 5, 5, 6]] + -0.000439562436330729364 # B[245, [4, 2, 0, 2], [32, 5, 5, 8]] + -0.000155002689849706443 # B[246, [4, 2, 0, 2], [33, 6, 0, 6]] + -0.00203784613220199399 # B[247, [4, 2, 0, 2], [34, 6, 1, 7]] + -0.00251933129878168221 # B[248, [4, 2, 0, 2], [35, 6, 2, 6]] + -0.00227857345941180406 # B[249, [4, 2, 0, 2], [36, 6, 2, 8]] + 0.00307391827986236085 # B[250, [4, 2, 0, 2], [37, 6, 3, 7]] + -0.000435707916552085118 # B[251, [4, 2, 0, 2], [38, 6, 4, 6]] + -0.00141960729594133419 # B[252, [4, 2, 0, 2], [39, 6, 4, 8]] + -0.000275734648504752638 # B[253, [4, 2, 0, 2], [40, 6, 5, 7]] + 0.000703286595409794617 # B[254, [4, 2, 0, 2], [41, 6, 6, 6]] + -5.55751922647368824e-05 # B[255, [4, 2, 0, 2], [42, 6, 6, 8]] + -0.000401816924228297345 # B[256, [4, 2, 0, 2], [43, 7, 0, 7]] + -0.000554714661495172429 # B[257, [4, 2, 0, 2], [44, 7, 1, 8]] + 0.00088244559527147267 # B[258, [4, 2, 0, 2], [45, 7, 2, 7]] + 0.000429487284537406104 # B[259, [4, 2, 0, 2], [46, 7, 3, 8]] + 0.000160720016534536374 # B[260, [4, 2, 0, 2], [47, 7, 4, 7]] + -0.000116046064898544729 # B[261, [4, 2, 0, 2], [48, 7, 5, 8]] + 0.00077812424584384446 # B[262, [4, 2, 0, 2], [49, 7, 6, 7]] + 0.0014223009786123353 # B[263, [4, 2, 0, 2], [50, 7, 7, 8]] + 5.45987148103492526e-05 # B[264, [4, 2, 0, 2], [51, 8, 0, 8]] + -0.00229888217343966316 # B[265, [4, 2, 0, 2], [52, 8, 2, 8]] + -0.00144376280980788169 # B[266, [4, 2, 0, 2], [53, 8, 4, 8]] + 0.000240138800657541986 # B[267, [4, 2, 0, 2], [54, 8, 6, 8]] + -4.09764373741731969e-05 # B[268, [4, 2, 0, 2], [55, 8, 8, 8]] + 0.0453826120189535706 # B[269, [5, 2, 1, 3], [5, 2, 1, 3]] + 0.00337080799390409615 # B[270, [5, 2, 1, 3], [6, 2, 2, 2]] + 0.0339316309546992961 # B[271, [5, 2, 1, 3], [7, 2, 2, 4]] + 0.00483677443671226039 # B[272, [5, 2, 1, 3], [8, 3, 0, 3]] + 0.00174954019608989774 # B[273, [5, 2, 1, 3], [9, 3, 1, 4]] + 0.00420306320210527603 # B[274, [5, 2, 1, 3], [10, 3, 2, 3]] + -0.0179939258962366969 # B[275, [5, 2, 1, 3], [11, 3, 2, 5]] + -0.01997198698308544 # B[276, [5, 2, 1, 3], [12, 3, 3, 4]] + -0.0136471344704570501 # B[277, [5, 2, 1, 3], [13, 3, 3, 6]] + -0.00203572867299816902 # B[278, [5, 2, 1, 3], [14, 4, 0, 4]] + 0.0113893698593142377 # B[279, [5, 2, 1, 3], [15, 4, 1, 5]] + -0.00283495847488346529 # B[280, [5, 2, 1, 3], [16, 4, 2, 4]] + -0.0209899506178404249 # B[281, [5, 2, 1, 3], [17, 4, 2, 6]] + 0.00307893999573658839 # B[282, [5, 2, 1, 3], [18, 4, 3, 5]] + 0.00625880909518397067 # B[283, [5, 2, 1, 3], [19, 4, 3, 7]] + 0.00109461945578659598 # B[284, [5, 2, 1, 3], [20, 4, 4, 4]] + 0.00213752786441095705 # B[285, [5, 2, 1, 3], [21, 4, 4, 6]] + -0.00379774849562602296 # B[286, [5, 2, 1, 3], [22, 4, 4, 8]] + -0.0013508169978871552 # B[287, [5, 2, 1, 3], [23, 5, 0, 5]] + 0.00921730935112183292 # B[288, [5, 2, 1, 3], [24, 5, 1, 6]] + -0.0029427132897584694 # B[289, [5, 2, 1, 3], [25, 5, 2, 5]] + 0.0013497580216050211 # B[290, [5, 2, 1, 3], [26, 5, 2, 7]] + -0.0130362734683665445 # B[291, [5, 2, 1, 3], [27, 5, 3, 6]] + 0.000858369129835153365 # B[292, [5, 2, 1, 3], [28, 5, 3, 8]] + 0.0129288669947052737 # B[293, [5, 2, 1, 3], [29, 5, 4, 5]] + -0.00373719468786774291 # B[294, [5, 2, 1, 3], [30, 5, 4, 7]] + -0.00885030928727506203 # B[295, [5, 2, 1, 3], [31, 5, 5, 6]] + 0.00285083482960970039 # B[296, [5, 2, 1, 3], [32, 5, 5, 8]] + 0.00351819863542377799 # B[297, [5, 2, 1, 3], [33, 6, 0, 6]] + -0.00783526064954031404 # B[298, [5, 2, 1, 3], [34, 6, 1, 7]] + -0.00257460837433342703 # B[299, [5, 2, 1, 3], [35, 6, 2, 6]] + -0.00421680657028429638 # B[300, [5, 2, 1, 3], [36, 6, 2, 8]] + -0.00918753516813325399 # B[301, [5, 2, 1, 3], [37, 6, 3, 7]] + -0.00316878171100497871 # B[302, [5, 2, 1, 3], [38, 6, 4, 6]] + 0.000939804682159322766 # B[303, [5, 2, 1, 3], [39, 6, 4, 8]] + -0.00618801787900946643 # B[304, [5, 2, 1, 3], [40, 6, 5, 7]] + -0.00623545765495540482 # B[305, [5, 2, 1, 3], [41, 6, 6, 6]] + 0.00519552954815065936 # B[306, [5, 2, 1, 3], [42, 6, 6, 8]] + 0.0042213652228506697 # B[307, [5, 2, 1, 3], [43, 7, 0, 7]] + 0.0113944611011103838 # B[308, [5, 2, 1, 3], [44, 7, 1, 8]] + -0.00104197865751114085 # B[309, [5, 2, 1, 3], [45, 7, 2, 7]] + -0.0087446191630695079 # B[310, [5, 2, 1, 3], [46, 7, 3, 8]] + -0.00196327596558909696 # B[311, [5, 2, 1, 3], [47, 7, 4, 7]] + -0.00447686867642808298 # B[312, [5, 2, 1, 3], [48, 7, 5, 8]] + -0.00474469665733750351 # B[313, [5, 2, 1, 3], [49, 7, 6, 7]] + -0.0059004868061462868 # B[314, [5, 2, 1, 3], [50, 7, 7, 8]] + 2.22874717926892923e-05 # B[315, [5, 2, 1, 3], [51, 8, 0, 8]] + -0.00154741089157206784 # B[316, [5, 2, 1, 3], [52, 8, 2, 8]] + 0.00417852330669051582 # B[317, [5, 2, 1, 3], [53, 8, 4, 8]] + 0.00134060860138395356 # B[318, [5, 2, 1, 3], [54, 8, 6, 8]] + -4.29219459423162489e-05 # B[319, [5, 2, 1, 3], [55, 8, 8, 8]] + 0.000319124100064731785 # B[320, [6, 2, 2, 2], [6, 2, 2, 2]] + -0.00839561599135440172 # B[321, [6, 2, 2, 2], [7, 2, 2, 4]] + -0.00326195850510992494 # B[322, [6, 2, 2, 2], [8, 3, 0, 3]] + 0.0194547426296311776 # B[323, [6, 2, 2, 2], [9, 3, 1, 4]] + -0.020516093722439413 # B[324, [6, 2, 2, 2], [10, 3, 2, 3]] + -0.00901624473884381043 # B[325, [6, 2, 2, 2], [11, 3, 2, 5]] + 0.0129026669830971837 # B[326, [6, 2, 2, 2], [12, 3, 3, 4]] + 0.00463182910296210636 # B[327, [6, 2, 2, 2], [13, 3, 3, 6]] + -0.00261498466108737743 # B[328, [6, 2, 2, 2], [14, 4, 0, 4]] + 0.0215819608660451426 # B[329, [6, 2, 2, 2], [15, 4, 1, 5]] + 0.000767688854520869957 # B[330, [6, 2, 2, 2], [16, 4, 2, 4]] + -0.00666111439578009716 # B[331, [6, 2, 2, 2], [17, 4, 2, 6]] + 0.0112705725443772303 # B[332, [6, 2, 2, 2], [18, 4, 3, 5]] + 0.00228839615631495127 # B[333, [6, 2, 2, 2], [19, 4, 3, 7]] + 0.00124148748415313414 # B[334, [6, 2, 2, 2], [20, 4, 4, 4]] + 0.00353391028977510834 # B[335, [6, 2, 2, 2], [21, 4, 4, 6]] + -0.00310464569903003834 # B[336, [6, 2, 2, 2], [22, 4, 4, 8]] + -0.001770681064288395 # B[337, [6, 2, 2, 2], [23, 5, 0, 5]] + 0.000554784469018851215 # B[338, [6, 2, 2, 2], [24, 5, 1, 6]] + -0.000102008183116791319 # B[339, [6, 2, 2, 2], [25, 5, 2, 5]] + -0.00128750706249572758 # B[340, [6, 2, 2, 2], [26, 5, 2, 7]] + 0.0046490656013451568 # B[341, [6, 2, 2, 2], [27, 5, 3, 6]] + 0.0034506831073765681 # B[342, [6, 2, 2, 2], [28, 5, 3, 8]] + 0.00501652811902741046 # B[343, [6, 2, 2, 2], [29, 5, 4, 5]] + -1.88389891915279224e-05 # B[344, [6, 2, 2, 2], [30, 5, 4, 7]] + -0.00246586719805504942 # B[345, [6, 2, 2, 2], [31, 5, 5, 6]] + -0.00339629261051872756 # B[346, [6, 2, 2, 2], [32, 5, 5, 8]] + -1.22729584505151552e-05 # B[347, [6, 2, 2, 2], [33, 6, 0, 6]] + -0.0055646406349652653 # B[348, [6, 2, 2, 2], [34, 6, 1, 7]] + 0.00216606634250279383 # B[349, [6, 2, 2, 2], [35, 6, 2, 6]] + -0.000140725603696151627 # B[350, [6, 2, 2, 2], [36, 6, 2, 8]] + -0.01190136261487338 # B[351, [6, 2, 2, 2], [37, 6, 3, 7]] + -0.000996588010308921109 # B[352, [6, 2, 2, 2], [38, 6, 4, 6]] + -0.0040124728576705895 # B[353, [6, 2, 2, 2], [39, 6, 4, 8]] + 0.000422679331586792552 # B[354, [6, 2, 2, 2], [40, 6, 5, 7]] + 0.000548939662545001959 # B[355, [6, 2, 2, 2], [41, 6, 6, 6]] + 0.00256895119228900404 # B[356, [6, 2, 2, 2], [42, 6, 6, 8]] + -0.000615139781019174688 # B[357, [6, 2, 2, 2], [43, 7, 0, 7]] + -0.00404941774617198578 # B[358, [6, 2, 2, 2], [44, 7, 1, 8]] + 0.00466754848324051064 # B[359, [6, 2, 2, 2], [45, 7, 2, 7]] + 0.00150461796185176488 # B[360, [6, 2, 2, 2], [46, 7, 3, 8]] + 0.0037489054114537468 # B[361, [6, 2, 2, 2], [47, 7, 4, 7]] + 0.00285804436398595782 # B[362, [6, 2, 2, 2], [48, 7, 5, 8]] + -0.00287521518361254919 # B[363, [6, 2, 2, 2], [49, 7, 6, 7]] + 0.000969520968104660755 # B[364, [6, 2, 2, 2], [50, 7, 7, 8]] + -0.000716125857042927043 # B[365, [6, 2, 2, 2], [51, 8, 0, 8]] + -0.00157385185114507437 # B[366, [6, 2, 2, 2], [52, 8, 2, 8]] + 0.002689243736875038 # B[367, [6, 2, 2, 2], [53, 8, 4, 8]] + -0.000661038690452418623 # B[368, [6, 2, 2, 2], [54, 8, 6, 8]] + 0.00157186481624649321 # B[369, [6, 2, 2, 2], [55, 8, 8, 8]] + -0.0134601349926017494 # B[370, [7, 2, 2, 4], [7, 2, 2, 4]] + -0.000918558149715113011 # B[371, [7, 2, 2, 4], [8, 3, 0, 3]] + -0.00377418701166061087 # B[372, [7, 2, 2, 4], [9, 3, 1, 4]] + 0.0148168734486278948 # B[373, [7, 2, 2, 4], [10, 3, 2, 3]] + -0.00535328606426562371 # B[374, [7, 2, 2, 4], [11, 3, 2, 5]] + 0.00804271469408427385 # B[375, [7, 2, 2, 4], [12, 3, 3, 4]] + 0.00136329663181449737 # B[376, [7, 2, 2, 4], [13, 3, 3, 6]] + 0.000218608555253111195 # B[377, [7, 2, 2, 4], [14, 4, 0, 4]] + 0.00767165886258287799 # B[378, [7, 2, 2, 4], [15, 4, 1, 5]] + -0.0022580429604385833 # B[379, [7, 2, 2, 4], [16, 4, 2, 4]] + -0.0050991924246220309 # B[380, [7, 2, 2, 4], [17, 4, 2, 6]] + -0.00308509180848093572 # B[381, [7, 2, 2, 4], [18, 4, 3, 5]] + -0.000900097231895549623 # B[382, [7, 2, 2, 4], [19, 4, 3, 7]] + -0.0063557020842957869 # B[383, [7, 2, 2, 4], [20, 4, 4, 4]] + -0.000409569358807882096 # B[384, [7, 2, 2, 4], [21, 4, 4, 6]] + 0.00254581400782049119 # B[385, [7, 2, 2, 4], [22, 4, 4, 8]] + 0.000657951401298526029 # B[386, [7, 2, 2, 4], [23, 5, 0, 5]] + -0.00940269729352927013 # B[387, [7, 2, 2, 4], [24, 5, 1, 6]] + 0.00333566383730494239 # B[388, [7, 2, 2, 4], [25, 5, 2, 5]] + 0.00896493308698088215 # B[389, [7, 2, 2, 4], [26, 5, 2, 7]] + 0.00132812590751918685 # B[390, [7, 2, 2, 4], [27, 5, 3, 6]] + -0.00127282140780485189 # B[391, [7, 2, 2, 4], [28, 5, 3, 8]] + -0.00435358176352772068 # B[392, [7, 2, 2, 4], [29, 5, 4, 5]] + -0.00226566527245459885 # B[393, [7, 2, 2, 4], [30, 5, 4, 7]] + 0.00326597657188156627 # B[394, [7, 2, 2, 4], [31, 5, 5, 6]] + -0.00247993076825692074 # B[395, [7, 2, 2, 4], [32, 5, 5, 8]] + -0.00138012806761597748 # B[396, [7, 2, 2, 4], [33, 6, 0, 6]] + -0.00296559266178312566 # B[397, [7, 2, 2, 4], [34, 6, 1, 7]] + -0.00345134318647404535 # B[398, [7, 2, 2, 4], [35, 6, 2, 6]] + 0.00604122282441024554 # B[399, [7, 2, 2, 4], [36, 6, 2, 8]] + -0.00602530276328681197 # B[400, [7, 2, 2, 4], [37, 6, 3, 7]] + 0.00113230868581531974 # B[401, [7, 2, 2, 4], [38, 6, 4, 6]] + 0.00132069580529702024 # B[402, [7, 2, 2, 4], [39, 6, 4, 8]] + -0.00355708848499901743 # B[403, [7, 2, 2, 4], [40, 6, 5, 7]] + 0.00103954578232134899 # B[404, [7, 2, 2, 4], [41, 6, 6, 6]] + 0.00138660655783935638 # B[405, [7, 2, 2, 4], [42, 6, 6, 8]] + 0.00122312383058832339 # B[406, [7, 2, 2, 4], [43, 7, 0, 7]] + 0.00122422070912251465 # B[407, [7, 2, 2, 4], [44, 7, 1, 8]] + -0.00497379521097694472 # B[408, [7, 2, 2, 4], [45, 7, 2, 7]] + -0.00811974704425355749 # B[409, [7, 2, 2, 4], [46, 7, 3, 8]] + 0.00114732010903773659 # B[410, [7, 2, 2, 4], [47, 7, 4, 7]] + -0.00569074628354063975 # B[411, [7, 2, 2, 4], [48, 7, 5, 8]] + 0.00235624642317577588 # B[412, [7, 2, 2, 4], [49, 7, 6, 7]] + 7.98437182146268919e-05 # B[413, [7, 2, 2, 4], [50, 7, 7, 8]] + 0.00113891921332402897 # B[414, [7, 2, 2, 4], [51, 8, 0, 8]] + -0.00492469555442132112 # B[415, [7, 2, 2, 4], [52, 8, 2, 8]] + 0.000792980352556455804 # B[416, [7, 2, 2, 4], [53, 8, 4, 8]] + 0.00153854887229367375 # B[417, [7, 2, 2, 4], [54, 8, 6, 8]] + -0.000881221748445243022 # B[418, [7, 2, 2, 4], [55, 8, 8, 8]] + -0.00136471788502227735 # B[419, [8, 3, 0, 3], [8, 3, 0, 3]] + 0.00246251727263488776 # B[420, [8, 3, 0, 3], [9, 3, 1, 4]] + 0.000996613519267240677 # B[421, [8, 3, 0, 3], [10, 3, 2, 3]] + -0.00207976146372090831 # B[422, [8, 3, 0, 3], [11, 3, 2, 5]] + -9.97509064182486305e-05 # B[423, [8, 3, 0, 3], [12, 3, 3, 4]] + 0.000656935135924852087 # B[424, [8, 3, 0, 3], [13, 3, 3, 6]] + -0.000492474229225159377 # B[425, [8, 3, 0, 3], [14, 4, 0, 4]] + 0.0032189163248994351 # B[426, [8, 3, 0, 3], [15, 4, 1, 5]] + -0.00115555104609991501 # B[427, [8, 3, 0, 3], [16, 4, 2, 4]] + -0.000101151026370576574 # B[428, [8, 3, 0, 3], [17, 4, 2, 6]] + 0.00020301152740384229 # B[429, [8, 3, 0, 3], [18, 4, 3, 5]] + -0.000285445107860462371 # B[430, [8, 3, 0, 3], [19, 4, 3, 7]] + 0.000462665925556146607 # B[431, [8, 3, 0, 3], [20, 4, 4, 4]] + -2.75652763320703015e-05 # B[432, [8, 3, 0, 3], [21, 4, 4, 6]] + -0.000358778647317398169 # B[433, [8, 3, 0, 3], [22, 4, 4, 8]] + -0.000397176131748222527 # B[434, [8, 3, 0, 3], [23, 5, 0, 5]] + -0.00026950177456114624 # B[435, [8, 3, 0, 3], [24, 5, 1, 6]] + 0.00119424632084062527 # B[436, [8, 3, 0, 3], [25, 5, 2, 5]] + 0.000922347152199163439 # B[437, [8, 3, 0, 3], [26, 5, 2, 7]] + -0.000340838509282952173 # B[438, [8, 3, 0, 3], [27, 5, 3, 6]] + 0.00128847730890532808 # B[439, [8, 3, 0, 3], [28, 5, 3, 8]] + -0.00044582191494569115 # B[440, [8, 3, 0, 3], [29, 5, 4, 5]] + -0.00114898350718379422 # B[441, [8, 3, 0, 3], [30, 5, 4, 7]] + -0.000530499767100067743 # B[442, [8, 3, 0, 3], [31, 5, 5, 6]] + 1.68864176486992895e-05 # B[443, [8, 3, 0, 3], [32, 5, 5, 8]] + -0.000312292146951373417 # B[444, [8, 3, 0, 3], [33, 6, 0, 6]] + -0.00186273440079770883 # B[445, [8, 3, 0, 3], [34, 6, 1, 7]] + -0.000475625961442131123 # B[446, [8, 3, 0, 3], [35, 6, 2, 6]] + 0.000505090975521763769 # B[447, [8, 3, 0, 3], [36, 6, 2, 8]] + 0.000128630083375533277 # B[448, [8, 3, 0, 3], [37, 6, 3, 7]] + -0.000431369283499544176 # B[449, [8, 3, 0, 3], [38, 6, 4, 6]] + 0.000461881443708941908 # B[450, [8, 3, 0, 3], [39, 6, 4, 8]] + 0.000867550860200114182 # B[451, [8, 3, 0, 3], [40, 6, 5, 7]] + 0.000179604539903628624 # B[452, [8, 3, 0, 3], [41, 6, 6, 6]] + -0.000405383988192370426 # B[453, [8, 3, 0, 3], [42, 6, 6, 8]] + -0.000305572243426546764 # B[454, [8, 3, 0, 3], [43, 7, 0, 7]] + -0.0010766931736053021 # B[455, [8, 3, 0, 3], [44, 7, 1, 8]] + 0.000701859051866787764 # B[456, [8, 3, 0, 3], [45, 7, 2, 7]] + -1.5413662061584954e-05 # B[457, [8, 3, 0, 3], [46, 7, 3, 8]] + 0.000428834666348756888 # B[458, [8, 3, 0, 3], [47, 7, 4, 7]] + 0.000468098667731533385 # B[459, [8, 3, 0, 3], [48, 7, 5, 8]] + 0.000158467988956009775 # B[460, [8, 3, 0, 3], [49, 7, 6, 7]] + 2.77948419442784408e-05 # B[461, [8, 3, 0, 3], [50, 7, 7, 8]] + -0.000282655955044820717 # B[462, [8, 3, 0, 3], [51, 8, 0, 8]] + 0.000100300940760145348 # B[463, [8, 3, 0, 3], [52, 8, 2, 8]] + 0.000314947671131902973 # B[464, [8, 3, 0, 3], [53, 8, 4, 8]] + 0.000144842823919437078 # B[465, [8, 3, 0, 3], [54, 8, 6, 8]] + 7.00050428864840146e-05 # B[466, [8, 3, 0, 3], [55, 8, 8, 8]] + 0.0118411448561217512 # B[467, [9, 3, 1, 4], [9, 3, 1, 4]] + 0.0158809314732707603 # B[468, [9, 3, 1, 4], [10, 3, 2, 3]] + -0.00690506493475962109 # B[469, [9, 3, 1, 4], [11, 3, 2, 5]] + 0.0085626937099196887 # B[470, [9, 3, 1, 4], [12, 3, 3, 4]] + -0.00387686964925252654 # B[471, [9, 3, 1, 4], [13, 3, 3, 6]] + 0.00015029200549142481 # B[472, [9, 3, 1, 4], [14, 4, 0, 4]] + -0.000142532963490632015 # B[473, [9, 3, 1, 4], [15, 4, 1, 5]] + 0.00921427022949583042 # B[474, [9, 3, 1, 4], [16, 4, 2, 4]] + -0.0112717231196791407 # B[475, [9, 3, 1, 4], [17, 4, 2, 6]] + -0.0122014182952103704 # B[476, [9, 3, 1, 4], [18, 4, 3, 5]] + -0.0111571557686284996 # B[477, [9, 3, 1, 4], [19, 4, 3, 7]] + -0.00276180055211498916 # B[478, [9, 3, 1, 4], [20, 4, 4, 4]] + -0.00444456405006457382 # B[479, [9, 3, 1, 4], [21, 4, 4, 6]] + -0.00248162623330630983 # B[480, [9, 3, 1, 4], [22, 4, 4, 8]] + 0.000238830840202226575 # B[481, [9, 3, 1, 4], [23, 5, 0, 5]] + 0.0106883008114137777 # B[482, [9, 3, 1, 4], [24, 5, 1, 6]] + -0.00176293319638371826 # B[483, [9, 3, 1, 4], [25, 5, 2, 5]] + -0.000706186990249144109 # B[484, [9, 3, 1, 4], [26, 5, 2, 7]] + -0.000957413082652629373 # B[485, [9, 3, 1, 4], [27, 5, 3, 6]] + -0.00485998335666546887 # B[486, [9, 3, 1, 4], [28, 5, 3, 8]] + -0.000739967956913101287 # B[487, [9, 3, 1, 4], [29, 5, 4, 5]] + -0.00656002591947351353 # B[488, [9, 3, 1, 4], [30, 5, 4, 7]] + -0.00191607250770065712 # B[489, [9, 3, 1, 4], [31, 5, 5, 6]] + -0.000375150046930213714 # B[490, [9, 3, 1, 4], [32, 5, 5, 8]] + 0.000379540253919751804 # B[491, [9, 3, 1, 4], [33, 6, 0, 6]] + 0.0103809997405371179 # B[492, [9, 3, 1, 4], [34, 6, 1, 7]] + -0.00167937900508645203 # B[493, [9, 3, 1, 4], [35, 6, 2, 6]] + -0.000942453027264282192 # B[494, [9, 3, 1, 4], [36, 6, 2, 8]] + -0.00358794660355351257 # B[495, [9, 3, 1, 4], [37, 6, 3, 7]] + 0.00367542903060237222 # B[496, [9, 3, 1, 4], [38, 6, 4, 6]] + -0.00605874518215254298 # B[497, [9, 3, 1, 4], [39, 6, 4, 8]] + -0.0053364107721741022 # B[498, [9, 3, 1, 4], [40, 6, 5, 7]] + -0.00220303686176452889 # B[499, [9, 3, 1, 4], [41, 6, 6, 6]] + 0.000240224733534942676 # B[500, [9, 3, 1, 4], [42, 6, 6, 8]] + 0.00118204722287629585 # B[501, [9, 3, 1, 4], [43, 7, 0, 7]] + 0.00391606544218769514 # B[502, [9, 3, 1, 4], [44, 7, 1, 8]] + -0.00190557542057654024 # B[503, [9, 3, 1, 4], [45, 7, 2, 7]] + -0.0010749256928406746 # B[504, [9, 3, 1, 4], [46, 7, 3, 8]] + 6.24186835188134462e-05 # B[505, [9, 3, 1, 4], [47, 7, 4, 7]] + -0.00250872188348977114 # B[506, [9, 3, 1, 4], [48, 7, 5, 8]] + -0.00164710314956706405 # B[507, [9, 3, 1, 4], [49, 7, 6, 7]] + -0.0029144992153610676 # B[508, [9, 3, 1, 4], [50, 7, 7, 8]] + 0.000712015267242259442 # B[509, [9, 3, 1, 4], [51, 8, 0, 8]] + -0.00179539873092394715 # B[510, [9, 3, 1, 4], [52, 8, 2, 8]] + 0.00203000698298521493 # B[511, [9, 3, 1, 4], [53, 8, 4, 8]] + -0.00103477100047664442 # B[512, [9, 3, 1, 4], [54, 8, 6, 8]] + -0.000727628763147338854 # B[513, [9, 3, 1, 4], [55, 8, 8, 8]] + 0.0163451466486591972 # B[514, [10, 3, 2, 3], [10, 3, 2, 3]] + -0.00145259448176927441 # B[515, [10, 3, 2, 3], [11, 3, 2, 5]] + -0.00808947571520425568 # B[516, [10, 3, 2, 3], [12, 3, 3, 4]] + -0.00693599935022420205 # B[517, [10, 3, 2, 3], [13, 3, 3, 6]] + -0.00419683318703741731 # B[518, [10, 3, 2, 3], [14, 4, 0, 4]] + 0.00927666204585274323 # B[519, [10, 3, 2, 3], [15, 4, 1, 5]] + -0.0138962541759877663 # B[520, [10, 3, 2, 3], [16, 4, 2, 4]] + 0.0115061801390417759 # B[521, [10, 3, 2, 3], [17, 4, 2, 6]] + 0.0118559077356181798 # B[522, [10, 3, 2, 3], [18, 4, 3, 5]] + 0.00193270595871023604 # B[523, [10, 3, 2, 3], [19, 4, 3, 7]] + 0.00156708209719190472 # B[524, [10, 3, 2, 3], [20, 4, 4, 4]] + 0.0030286948486105119 # B[525, [10, 3, 2, 3], [21, 4, 4, 6]] + -6.03736466163237034e-05 # B[526, [10, 3, 2, 3], [22, 4, 4, 8]] + -0.00147218391304548835 # B[527, [10, 3, 2, 3], [23, 5, 0, 5]] + 0.000931966019926808685 # B[528, [10, 3, 2, 3], [24, 5, 1, 6]] + 0.0153667638164197012 # B[529, [10, 3, 2, 3], [25, 5, 2, 5]] + -0.0023105273691670326 # B[530, [10, 3, 2, 3], [26, 5, 2, 7]] + 0.0018873267014898696 # B[531, [10, 3, 2, 3], [27, 5, 3, 6]] + -0.00221592978134090707 # B[532, [10, 3, 2, 3], [28, 5, 3, 8]] + 0.00175823978838723916 # B[533, [10, 3, 2, 3], [29, 5, 4, 5]] + 0.00134986143361107494 # B[534, [10, 3, 2, 3], [30, 5, 4, 7]] + -0.00280444330034939227 # B[535, [10, 3, 2, 3], [31, 5, 5, 6]] + -0.000446159575940244073 # B[536, [10, 3, 2, 3], [32, 5, 5, 8]] + 0.000126573802730074736 # B[537, [10, 3, 2, 3], [33, 6, 0, 6]] + 7.95217271451070795e-05 # B[538, [10, 3, 2, 3], [34, 6, 1, 7]] + -0.000615992203402992468 # B[539, [10, 3, 2, 3], [35, 6, 2, 6]] + -0.0106304231235931409 # B[540, [10, 3, 2, 3], [36, 6, 2, 8]] + -0.00513102234934090934 # B[541, [10, 3, 2, 3], [37, 6, 3, 7]] + 0.00086364506858761271 # B[542, [10, 3, 2, 3], [38, 6, 4, 6]] + -0.00427816275089007263 # B[543, [10, 3, 2, 3], [39, 6, 4, 8]] + -0.00709876751806875171 # B[544, [10, 3, 2, 3], [40, 6, 5, 7]] + -0.00107679083671011894 # B[545, [10, 3, 2, 3], [41, 6, 6, 6]] + -0.0014022801302571164 # B[546, [10, 3, 2, 3], [42, 6, 6, 8]] + 0.00032001340322446864 # B[547, [10, 3, 2, 3], [43, 7, 0, 7]] + 0.0099494513037338677 # B[548, [10, 3, 2, 3], [44, 7, 1, 8]] + 0.00657164457459321564 # B[549, [10, 3, 2, 3], [45, 7, 2, 7]] + -0.00193909086513409032 # B[550, [10, 3, 2, 3], [46, 7, 3, 8]] + -0.000661327911070458407 # B[551, [10, 3, 2, 3], [47, 7, 4, 7]] + -0.00236609840279333045 # B[552, [10, 3, 2, 3], [48, 7, 5, 8]] + 0.000323126961361372422 # B[553, [10, 3, 2, 3], [49, 7, 6, 7]] + 0.00156411007472663857 # B[554, [10, 3, 2, 3], [50, 7, 7, 8]] + -0.000413410696562647312 # B[555, [10, 3, 2, 3], [51, 8, 0, 8]] + 0.00151556635054790959 # B[556, [10, 3, 2, 3], [52, 8, 2, 8]] + 0.0032252808357782943 # B[557, [10, 3, 2, 3], [53, 8, 4, 8]] + 0.00431814581620697767 # B[558, [10, 3, 2, 3], [54, 8, 6, 8]] + 0.000198535493268348594 # B[559, [10, 3, 2, 3], [55, 8, 8, 8]] + 0.0156540432654675432 # B[560, [11, 3, 2, 5], [11, 3, 2, 5]] + 0.00979845476873780416 # B[561, [11, 3, 2, 5], [12, 3, 3, 4]] + 0.00873265456764509701 # B[562, [11, 3, 2, 5], [13, 3, 3, 6]] + -0.00355250352643814854 # B[563, [11, 3, 2, 5], [14, 4, 0, 4]] + 0.0197388975583387243 # B[564, [11, 3, 2, 5], [15, 4, 1, 5]] + 0.0158965586216084157 # B[565, [11, 3, 2, 5], [16, 4, 2, 4]] + 0.0126440348146513917 # B[566, [11, 3, 2, 5], [17, 4, 2, 6]] + 0.00588822462217037865 # B[567, [11, 3, 2, 5], [18, 4, 3, 5]] + 0.00465829809814364074 # B[568, [11, 3, 2, 5], [19, 4, 3, 7]] + 0.00460100330976275125 # B[569, [11, 3, 2, 5], [20, 4, 4, 4]] + 0.00507979510261629894 # B[570, [11, 3, 2, 5], [21, 4, 4, 6]] + -0.000978147842247499566 # B[571, [11, 3, 2, 5], [22, 4, 4, 8]] + 0.000175648698607325238 # B[572, [11, 3, 2, 5], [23, 5, 0, 5]] + 0.00701365729786882983 # B[573, [11, 3, 2, 5], [24, 5, 1, 6]] + 0.0124121871279893672 # B[574, [11, 3, 2, 5], [25, 5, 2, 5]] + 0.0133268604743271169 # B[575, [11, 3, 2, 5], [26, 5, 2, 7]] + -0.00306906262974302943 # B[576, [11, 3, 2, 5], [27, 5, 3, 6]] + 0.00411586711144847073 # B[577, [11, 3, 2, 5], [28, 5, 3, 8]] + -0.00483702208096517539 # B[578, [11, 3, 2, 5], [29, 5, 4, 5]] + 0.000232830853394127776 # B[579, [11, 3, 2, 5], [30, 5, 4, 7]] + -0.00500644765401524715 # B[580, [11, 3, 2, 5], [31, 5, 5, 6]] + -0.000732991087538808345 # B[581, [11, 3, 2, 5], [32, 5, 5, 8]] + 0.0028290195015726223 # B[582, [11, 3, 2, 5], [33, 6, 0, 6]] + 0.000660043236562475252 # B[583, [11, 3, 2, 5], [34, 6, 1, 7]] + 0.00858014820620479901 # B[584, [11, 3, 2, 5], [35, 6, 2, 6]] + 0.00979420830127970127 # B[585, [11, 3, 2, 5], [36, 6, 2, 8]] + -0.00276929529868128257 # B[586, [11, 3, 2, 5], [37, 6, 3, 7]] + -0.00462592209123751513 # B[587, [11, 3, 2, 5], [38, 6, 4, 6]] + 0.000957159367659247626 # B[588, [11, 3, 2, 5], [39, 6, 4, 8]] + -0.00289923459154850169 # B[589, [11, 3, 2, 5], [40, 6, 5, 7]] + -0.00605668820795574915 # B[590, [11, 3, 2, 5], [41, 6, 6, 6]] + -0.00571070540762017888 # B[591, [11, 3, 2, 5], [42, 6, 6, 8]] + 0.00247733408975375075 # B[592, [11, 3, 2, 5], [43, 7, 0, 7]] + 0.00452000165177812024 # B[593, [11, 3, 2, 5], [44, 7, 1, 8]] + 0.00267833963693382693 # B[594, [11, 3, 2, 5], [45, 7, 2, 7]] + -0.00558917145621175976 # B[595, [11, 3, 2, 5], [46, 7, 3, 8]] + -0.00228097422335522999 # B[596, [11, 3, 2, 5], [47, 7, 4, 7]] + -0.00366604043706369575 # B[597, [11, 3, 2, 5], [48, 7, 5, 8]] + -0.00340088281218112534 # B[598, [11, 3, 2, 5], [49, 7, 6, 7]] + -0.00355022426643257852 # B[599, [11, 3, 2, 5], [50, 7, 7, 8]] + 0.00124080314205340242 # B[600, [11, 3, 2, 5], [51, 8, 0, 8]] + 0.00287261267197001097 # B[601, [11, 3, 2, 5], [52, 8, 2, 8]] + 0.000744815191487350516 # B[602, [11, 3, 2, 5], [53, 8, 4, 8]] + -0.000112288931147085103 # B[603, [11, 3, 2, 5], [54, 8, 6, 8]] + -0.000128712309023326903 # B[604, [11, 3, 2, 5], [55, 8, 8, 8]] + -0.00238666366477884723 # B[605, [12, 3, 3, 4], [12, 3, 3, 4]] + 0.000248696286071804773 # B[606, [12, 3, 3, 4], [13, 3, 3, 6]] + -0.000479775127143412111 # B[607, [12, 3, 3, 4], [14, 4, 0, 4]] + 0.00175952173341571141 # B[608, [12, 3, 3, 4], [15, 4, 1, 5]] + 0.000197368498788095745 # B[609, [12, 3, 3, 4], [16, 4, 2, 4]] + 0.00726401135600521306 # B[610, [12, 3, 3, 4], [17, 4, 2, 6]] + -0.00118096336629036625 # B[611, [12, 3, 3, 4], [18, 4, 3, 5]] + 0.00702896514440041337 # B[612, [12, 3, 3, 4], [19, 4, 3, 7]] + -0.00236026619914155369 # B[613, [12, 3, 3, 4], [20, 4, 4, 4]] + -0.00341152672753146672 # B[614, [12, 3, 3, 4], [21, 4, 4, 6]] + 0.00348613231611557411 # B[615, [12, 3, 3, 4], [22, 4, 4, 8]] + 0.00244457707345889508 # B[616, [12, 3, 3, 4], [23, 5, 0, 5]] + -0.000822727235681003019 # B[617, [12, 3, 3, 4], [24, 5, 1, 6]] + -0.00248763810919495551 # B[618, [12, 3, 3, 4], [25, 5, 2, 5]] + 0.00796413115978647848 # B[619, [12, 3, 3, 4], [26, 5, 2, 7]] + -0.00179317048488774472 # B[620, [12, 3, 3, 4], [27, 5, 3, 6]] + 0.00454384820995466787 # B[621, [12, 3, 3, 4], [28, 5, 3, 8]] + -0.00425365149530766012 # B[622, [12, 3, 3, 4], [29, 5, 4, 5]] + -0.000569152560526600682 # B[623, [12, 3, 3, 4], [30, 5, 4, 7]] + -0.00506501220127485163 # B[624, [12, 3, 3, 4], [31, 5, 5, 6]] + -0.00142637122228714969 # B[625, [12, 3, 3, 4], [32, 5, 5, 8]] + 0.00190739239349446005 # B[626, [12, 3, 3, 4], [33, 6, 0, 6]] + 0.00215429853006474104 # B[627, [12, 3, 3, 4], [34, 6, 1, 7]] + 0.00512135793044871807 # B[628, [12, 3, 3, 4], [35, 6, 2, 6]] + 0.00479344551680733165 # B[629, [12, 3, 3, 4], [36, 6, 2, 8]] + -0.000813733007282164966 # B[630, [12, 3, 3, 4], [37, 6, 3, 7]] + -0.00162747725274282884 # B[631, [12, 3, 3, 4], [38, 6, 4, 6]] + -0.00440004969635155417 # B[632, [12, 3, 3, 4], [39, 6, 4, 8]] + -0.00939941153506137356 # B[633, [12, 3, 3, 4], [40, 6, 5, 7]] + -0.00314893787689287524 # B[634, [12, 3, 3, 4], [41, 6, 6, 6]] + -0.00125776748984993136 # B[635, [12, 3, 3, 4], [42, 6, 6, 8]] + 0.00129112127843685615 # B[636, [12, 3, 3, 4], [43, 7, 0, 7]] + 0.00564724346615860621 # B[637, [12, 3, 3, 4], [44, 7, 1, 8]] + -0.0018460571659526942 # B[638, [12, 3, 3, 4], [45, 7, 2, 7]] + -0.000300525523225368685 # B[639, [12, 3, 3, 4], [46, 7, 3, 8]] + -0.00277157581435865698 # B[640, [12, 3, 3, 4], [47, 7, 4, 7]] + -0.00975210406554173105 # B[641, [12, 3, 3, 4], [48, 7, 5, 8]] + -0.00233845213984289896 # B[642, [12, 3, 3, 4], [49, 7, 6, 7]] + -0.00138723239922117561 # B[643, [12, 3, 3, 4], [50, 7, 7, 8]] + 0.000864866797073243071 # B[644, [12, 3, 3, 4], [51, 8, 0, 8]] + -0.000747563068773752452 # B[645, [12, 3, 3, 4], [52, 8, 2, 8]] + 0.000965474694725087373 # B[646, [12, 3, 3, 4], [53, 8, 4, 8]] + -0.00140612646390263218 # B[647, [12, 3, 3, 4], [54, 8, 6, 8]] + -0.00149643617894318522 # B[648, [12, 3, 3, 4], [55, 8, 8, 8]] + 0.00149153681612450295 # B[649, [13, 3, 3, 6], [13, 3, 3, 6]] + -0.000954556711257832646 # B[650, [13, 3, 3, 6], [14, 4, 0, 4]] + 0.00120983585813713799 # B[651, [13, 3, 3, 6], [15, 4, 1, 5]] + 0.00300317867570911888 # B[652, [13, 3, 3, 6], [16, 4, 2, 4]] + 0.00236443796053106663 # B[653, [13, 3, 3, 6], [17, 4, 2, 6]] + 0.00415524139600132597 # B[654, [13, 3, 3, 6], [18, 4, 3, 5]] + -0.000123573851697839077 # B[655, [13, 3, 3, 6], [19, 4, 3, 7]] + 0.000470359195248265527 # B[656, [13, 3, 3, 6], [20, 4, 4, 4]] + 0.000635927641249957321 # B[657, [13, 3, 3, 6], [21, 4, 4, 6]] + 0.000747673754939660613 # B[658, [13, 3, 3, 6], [22, 4, 4, 8]] + 0.00074188846631736971 # B[659, [13, 3, 3, 6], [23, 5, 0, 5]] + 0.00463957097737913854 # B[660, [13, 3, 3, 6], [24, 5, 1, 6]] + -0.00271105182543343939 # B[661, [13, 3, 3, 6], [25, 5, 2, 5]] + 6.90411348413036419e-06 # B[662, [13, 3, 3, 6], [26, 5, 2, 7]] + 0.000911354980270381865 # B[663, [13, 3, 3, 6], [27, 5, 3, 6]] + -0.0028545746938972022 # B[664, [13, 3, 3, 6], [28, 5, 3, 8]] + -1.76062828863947363e-05 # B[665, [13, 3, 3, 6], [29, 5, 4, 5]] + -1.51206672011107435e-05 # B[666, [13, 3, 3, 6], [30, 5, 4, 7]] + -0.000798318879555708766 # B[667, [13, 3, 3, 6], [31, 5, 5, 6]] + -0.0015978026047660434 # B[668, [13, 3, 3, 6], [32, 5, 5, 8]] + 0.00034244751324807865 # B[669, [13, 3, 3, 6], [33, 6, 0, 6]] + 0.00338996797689858353 # B[670, [13, 3, 3, 6], [34, 6, 1, 7]] + 0.000289281476490772793 # B[671, [13, 3, 3, 6], [35, 6, 2, 6]] + -0.000559772151149058594 # B[672, [13, 3, 3, 6], [36, 6, 2, 8]] + -0.000650724286175463629 # B[673, [13, 3, 3, 6], [37, 6, 3, 7]] + 0.00148244897292096334 # B[674, [13, 3, 3, 6], [38, 6, 4, 6]] + 0.000183404639618602733 # B[675, [13, 3, 3, 6], [39, 6, 4, 8]] + -0.00185779692530890772 # B[676, [13, 3, 3, 6], [40, 6, 5, 7]] + -0.000708322215432564961 # B[677, [13, 3, 3, 6], [41, 6, 6, 6]] + -0.000491831969715535167 # B[678, [13, 3, 3, 6], [42, 6, 6, 8]] + 0.000833818016036214082 # B[679, [13, 3, 3, 6], [43, 7, 0, 7]] + -0.00256922900730601443 # B[680, [13, 3, 3, 6], [44, 7, 1, 8]] + -0.00112433206588518839 # B[681, [13, 3, 3, 6], [45, 7, 2, 7]] + 6.43716101358243753e-05 # B[682, [13, 3, 3, 6], [46, 7, 3, 8]] + -0.00126304972485289518 # B[683, [13, 3, 3, 6], [47, 7, 4, 7]] + -0.00210937996313975001 # B[684, [13, 3, 3, 6], [48, 7, 5, 8]] + -0.00126022676030809744 # B[685, [13, 3, 3, 6], [49, 7, 6, 7]] + -0.000555039709846411045 # B[686, [13, 3, 3, 6], [50, 7, 7, 8]] + 0.000790824100586496465 # B[687, [13, 3, 3, 6], [51, 8, 0, 8]] + -0.000844206812343649936 # B[688, [13, 3, 3, 6], [52, 8, 2, 8]] + 0.000195900027714517901 # B[689, [13, 3, 3, 6], [53, 8, 4, 8]] + -0.000823274415849936658 # B[690, [13, 3, 3, 6], [54, 8, 6, 8]] + -0.000330474595809105917 # B[691, [13, 3, 3, 6], [55, 8, 8, 8]] + -3.04835503155357485e-05 # B[692, [14, 4, 0, 4], [14, 4, 0, 4]] + -0.000825475145007361147 # B[693, [14, 4, 0, 4], [15, 4, 1, 5]] + -0.00244887111925138484 # B[694, [14, 4, 0, 4], [16, 4, 2, 4]] + -0.00122050568127611732 # B[695, [14, 4, 0, 4], [17, 4, 2, 6]] + -0.00226655265247485693 # B[696, [14, 4, 0, 4], [18, 4, 3, 5]] + -0.000767631950688907327 # B[697, [14, 4, 0, 4], [19, 4, 3, 7]] + -0.000547575812124723171 # B[698, [14, 4, 0, 4], [20, 4, 4, 4]] + -0.00121783548699544442 # B[699, [14, 4, 0, 4], [21, 4, 4, 6]] + 6.68947985199286332e-05 # B[700, [14, 4, 0, 4], [22, 4, 4, 8]] + -9.6030771921717939e-05 # B[701, [14, 4, 0, 4], [23, 5, 0, 5]] + -0.000544408900336967871 # B[702, [14, 4, 0, 4], [24, 5, 1, 6]] + -0.00139019051437529293 # B[703, [14, 4, 0, 4], [25, 5, 2, 5]] + -0.000281919324988699413 # B[704, [14, 4, 0, 4], [26, 5, 2, 7]] + -0.00125721115437776171 # B[705, [14, 4, 0, 4], [27, 5, 3, 6]] + -0.000282797770993010317 # B[706, [14, 4, 0, 4], [28, 5, 3, 8]] + -0.00139320549871079641 # B[707, [14, 4, 0, 4], [29, 5, 4, 5]] + -0.000628813518841068401 # B[708, [14, 4, 0, 4], [30, 5, 4, 7]] + -0.000607292163329276047 # B[709, [14, 4, 0, 4], [31, 5, 5, 6]] + 0.000242807689929189566 # B[710, [14, 4, 0, 4], [32, 5, 5, 8]] + -0.000100536983796830487 # B[711, [14, 4, 0, 4], [33, 6, 0, 6]] + 0.00111838401982674706 # B[712, [14, 4, 0, 4], [34, 6, 1, 7]] + -0.0012014113032742873 # B[713, [14, 4, 0, 4], [35, 6, 2, 6]] + -1.32311363260466386e-05 # B[714, [14, 4, 0, 4], [36, 6, 2, 8]] + 0.000753146180409180327 # B[715, [14, 4, 0, 4], [37, 6, 3, 7]] + -0.000270332227596856156 # B[716, [14, 4, 0, 4], [38, 6, 4, 6]] + -0.000293750660311472775 # B[717, [14, 4, 0, 4], [39, 6, 4, 8]] + 6.52480591955099942e-05 # B[718, [14, 4, 0, 4], [40, 6, 5, 7]] + -4.70588815947581285e-05 # B[719, [14, 4, 0, 4], [41, 6, 6, 6]] + 0.000244731448919628669 # B[720, [14, 4, 0, 4], [42, 6, 6, 8]] + -9.3149326930830334e-05 # B[721, [14, 4, 0, 4], [43, 7, 0, 7]] + 0.000731947904616598796 # B[722, [14, 4, 0, 4], [44, 7, 1, 8]] + -0.00107463735030771668 # B[723, [14, 4, 0, 4], [45, 7, 2, 7]] + 0.000139861959076940934 # B[724, [14, 4, 0, 4], [46, 7, 3, 8]] + 0.000101877532936889281 # B[725, [14, 4, 0, 4], [47, 7, 4, 7]] + -0.000196888502333611437 # B[726, [14, 4, 0, 4], [48, 7, 5, 8]] + 6.12030178565765859e-05 # B[727, [14, 4, 0, 4], [49, 7, 6, 7]] + -0.000223986590912481076 # B[728, [14, 4, 0, 4], [50, 7, 7, 8]] + -6.56819431667232667e-05 # B[729, [14, 4, 0, 4], [51, 8, 0, 8]] + -0.000970632773483491584 # B[730, [14, 4, 0, 4], [52, 8, 2, 8]] + -0.000182189294658170395 # B[731, [14, 4, 0, 4], [53, 8, 4, 8]] + -3.45215935849477185e-05 # B[732, [14, 4, 0, 4], [54, 8, 6, 8]] + 6.19739521221795986e-05 # B[733, [14, 4, 0, 4], [55, 8, 8, 8]] + 0.000242753902013392972 # B[734, [15, 4, 1, 5], [15, 4, 1, 5]] + 0.00729727211034517358 # B[735, [15, 4, 1, 5], [16, 4, 2, 4]] + -0.0024545495000649507 # B[736, [15, 4, 1, 5], [17, 4, 2, 6]] + -0.00265559618939786597 # B[737, [15, 4, 1, 5], [18, 4, 3, 5]] + 0.00473045463551583639 # B[738, [15, 4, 1, 5], [19, 4, 3, 7]] + -0.000140785797905494323 # B[739, [15, 4, 1, 5], [20, 4, 4, 4]] + 0.00179841698526277474 # B[740, [15, 4, 1, 5], [21, 4, 4, 6]] + 0.00129773534161339073 # B[741, [15, 4, 1, 5], [22, 4, 4, 8]] + 0.00172905697138841467 # B[742, [15, 4, 1, 5], [23, 5, 0, 5]] + -0.00408304027381215483 # B[743, [15, 4, 1, 5], [24, 5, 1, 6]] + -0.00205043992851699228 # B[744, [15, 4, 1, 5], [25, 5, 2, 5]] + 0.000756591579123801249 # B[745, [15, 4, 1, 5], [26, 5, 2, 7]] + -0.00421238291006168549 # B[746, [15, 4, 1, 5], [27, 5, 3, 6]] + -0.00196911327032830725 # B[747, [15, 4, 1, 5], [28, 5, 3, 8]] + 0.000729488918071528446 # B[748, [15, 4, 1, 5], [29, 5, 4, 5]] + -0.00177843604064341788 # B[749, [15, 4, 1, 5], [30, 5, 4, 7]] + -0.00130376966915328159 # B[750, [15, 4, 1, 5], [31, 5, 5, 6]] + -0.00198695656227435707 # B[751, [15, 4, 1, 5], [32, 5, 5, 8]] + 0.000608914142072050635 # B[752, [15, 4, 1, 5], [33, 6, 0, 6]] + -0.00109469344681823767 # B[753, [15, 4, 1, 5], [34, 6, 1, 7]] + -0.00451953523789613495 # B[754, [15, 4, 1, 5], [35, 6, 2, 6]] + 0.00279449892877900279 # B[755, [15, 4, 1, 5], [36, 6, 2, 8]] + -0.00435984465194903283 # B[756, [15, 4, 1, 5], [37, 6, 3, 7]] + 0.00275969130186590542 # B[757, [15, 4, 1, 5], [38, 6, 4, 6]] + 0.00154021904971430755 # B[758, [15, 4, 1, 5], [39, 6, 4, 8]] + -0.00146163413862035289 # B[759, [15, 4, 1, 5], [40, 6, 5, 7]] + -0.000333421796264918996 # B[760, [15, 4, 1, 5], [41, 6, 6, 6]] + -0.00139958818201657261 # B[761, [15, 4, 1, 5], [42, 6, 6, 8]] + 0.000750502250600797172 # B[762, [15, 4, 1, 5], [43, 7, 0, 7]] + 0.00476052216726493421 # B[763, [15, 4, 1, 5], [44, 7, 1, 8]] + -0.00155321215408361565 # B[764, [15, 4, 1, 5], [45, 7, 2, 7]] + -0.00351167160511536933 # B[765, [15, 4, 1, 5], [46, 7, 3, 8]] + 0.00268907735535169144 # B[766, [15, 4, 1, 5], [47, 7, 4, 7]] + -0.00296394481906553462 # B[767, [15, 4, 1, 5], [48, 7, 5, 8]] + -0.00115945739998543369 # B[768, [15, 4, 1, 5], [49, 7, 6, 7]] + -0.0011498694923236445 # B[769, [15, 4, 1, 5], [50, 7, 7, 8]] + 0.000691127444573572114 # B[770, [15, 4, 1, 5], [51, 8, 0, 8]] + 0.00149148321917135169 # B[771, [15, 4, 1, 5], [52, 8, 2, 8]] + 0.00226549729687968923 # B[772, [15, 4, 1, 5], [53, 8, 4, 8]] + -0.00127955154911817224 # B[773, [15, 4, 1, 5], [54, 8, 6, 8]] + -0.0006680598304007173 # B[774, [15, 4, 1, 5], [55, 8, 8, 8]] + 0.00773393138113156846 # B[775, [16, 4, 2, 4], [16, 4, 2, 4]] + 0.00481567776445743917 # B[776, [16, 4, 2, 4], [17, 4, 2, 6]] + 0.00646602315581837339 # B[777, [16, 4, 2, 4], [18, 4, 3, 5]] + 0.00401373256364237051 # B[778, [16, 4, 2, 4], [19, 4, 3, 7]] + -0.000224833927917125753 # B[779, [16, 4, 2, 4], [20, 4, 4, 4]] + 0.0030532060451974926 # B[780, [16, 4, 2, 4], [21, 4, 4, 6]] + -0.000126777823410560014 # B[781, [16, 4, 2, 4], [22, 4, 4, 8]] + 0.00109512376860463863 # B[782, [16, 4, 2, 4], [23, 5, 0, 5]] + 0.0014906978453806609 # B[783, [16, 4, 2, 4], [24, 5, 1, 6]] + 0.00278609484035531206 # B[784, [16, 4, 2, 4], [25, 5, 2, 5]] + 0.00720611209490516682 # B[785, [16, 4, 2, 4], [26, 5, 2, 7]] + 0.00230880055683394415 # B[786, [16, 4, 2, 4], [27, 5, 3, 6]] + 0.00492114792718315389 # B[787, [16, 4, 2, 4], [28, 5, 3, 8]] + 0.00102265649585190407 # B[788, [16, 4, 2, 4], [29, 5, 4, 5]] + -0.000348239317084679881 # B[789, [16, 4, 2, 4], [30, 5, 4, 7]] + -0.00394431438420023671 # B[790, [16, 4, 2, 4], [31, 5, 5, 6]] + -0.00362914461095884553 # B[791, [16, 4, 2, 4], [32, 5, 5, 8]] + 0.000172019923347470349 # B[792, [16, 4, 2, 4], [33, 6, 0, 6]] + -0.000316455135754767445 # B[793, [16, 4, 2, 4], [34, 6, 1, 7]] + 0.00107098215861984453 # B[794, [16, 4, 2, 4], [35, 6, 2, 6]] + -0.000907131668137324478 # B[795, [16, 4, 2, 4], [36, 6, 2, 8]] + -0.000367695081353409058 # B[796, [16, 4, 2, 4], [37, 6, 3, 7]] + 0.00181370580350630889 # B[797, [16, 4, 2, 4], [38, 6, 4, 6]] + 0.000820930060826967692 # B[798, [16, 4, 2, 4], [39, 6, 4, 8]] + -0.00466238776474962348 # B[799, [16, 4, 2, 4], [40, 6, 5, 7]] + -0.0024305728850557008 # B[800, [16, 4, 2, 4], [41, 6, 6, 6]] + -0.00165013696151081928 # B[801, [16, 4, 2, 4], [42, 6, 6, 8]] + 0.000760058338755045804 # B[802, [16, 4, 2, 4], [43, 7, 0, 7]] + -0.00203289214112462729 # B[803, [16, 4, 2, 4], [44, 7, 1, 8]] + -0.00103057221789182719 # B[804, [16, 4, 2, 4], [45, 7, 2, 7]] + 0.00188720556649034019 # B[805, [16, 4, 2, 4], [46, 7, 3, 8]] + -0.000348979964538542048 # B[806, [16, 4, 2, 4], [47, 7, 4, 7]] + -0.00595514004121479486 # B[807, [16, 4, 2, 4], [48, 7, 5, 8]] + -0.00122307692783891336 # B[808, [16, 4, 2, 4], [49, 7, 6, 7]] + -0.00161626528708522232 # B[809, [16, 4, 2, 4], [50, 7, 7, 8]] + 0.000683658453003721522 # B[810, [16, 4, 2, 4], [51, 8, 0, 8]] + 0.000169503544911074264 # B[811, [16, 4, 2, 4], [52, 8, 2, 8]] + 0.00163132840171071117 # B[812, [16, 4, 2, 4], [53, 8, 4, 8]] + -0.000633742642666999118 # B[813, [16, 4, 2, 4], [54, 8, 6, 8]] + -0.000861029784191980584 # B[814, [16, 4, 2, 4], [55, 8, 8, 8]] + 0.0101724317893582689 # B[815, [17, 4, 2, 6], [17, 4, 2, 6]] + 0.00963074903115390332 # B[816, [17, 4, 2, 6], [18, 4, 3, 5]] + 0.00792776812488414986 # B[817, [17, 4, 2, 6], [19, 4, 3, 7]] + 0.00129789596639547263 # B[818, [17, 4, 2, 6], [20, 4, 4, 4]] + 0.0025280260724625768 # B[819, [17, 4, 2, 6], [21, 4, 4, 6]] + -0.00130604081814601758 # B[820, [17, 4, 2, 6], [22, 4, 4, 8]] + 0.00061656245411057832 # B[821, [17, 4, 2, 6], [23, 5, 0, 5]] + 0.00256026791937838134 # B[822, [17, 4, 2, 6], [24, 5, 1, 6]] + 0.00833728674660196879 # B[823, [17, 4, 2, 6], [25, 5, 2, 5]] + 0.00819332084025456604 # B[824, [17, 4, 2, 6], [26, 5, 2, 7]] + 0.00199258058679730159 # B[825, [17, 4, 2, 6], [27, 5, 3, 6]] + -0.00235687406293394464 # B[826, [17, 4, 2, 6], [28, 5, 3, 8]] + 0.00172306590551023903 # B[827, [17, 4, 2, 6], [29, 5, 4, 5]] + 0.00273320921325834404 # B[828, [17, 4, 2, 6], [30, 5, 4, 7]] + 0.00124490813870011289 # B[829, [17, 4, 2, 6], [31, 5, 5, 6]] + -0.00239829497882970916 # B[830, [17, 4, 2, 6], [32, 5, 5, 8]] + 0.000403489881901454572 # B[831, [17, 4, 2, 6], [33, 6, 0, 6]] + 0.0115977289566935714 # B[832, [17, 4, 2, 6], [34, 6, 1, 7]] + 0.00631330244272786285 # B[833, [17, 4, 2, 6], [35, 6, 2, 6]] + 0.00745951676374975552 # B[834, [17, 4, 2, 6], [36, 6, 2, 8]] + 0.00129555462014044158 # B[835, [17, 4, 2, 6], [37, 6, 3, 7]] + 0.0031708889242759988 # B[836, [17, 4, 2, 6], [38, 6, 4, 6]] + 0.00314059501950873093 # B[837, [17, 4, 2, 6], [39, 6, 4, 8]] + -0.00157311519106628078 # B[838, [17, 4, 2, 6], [40, 6, 5, 7]] + -0.000535633835711041804 # B[839, [17, 4, 2, 6], [41, 6, 6, 6]] + -0.00106218347026977491 # B[840, [17, 4, 2, 6], [42, 6, 6, 8]] + 0.00171130648037900839 # B[841, [17, 4, 2, 6], [43, 7, 0, 7]] + 0.00318381348777509654 # B[842, [17, 4, 2, 6], [44, 7, 1, 8]] + 0.00121186975917000981 # B[843, [17, 4, 2, 6], [45, 7, 2, 7]] + -0.00505226933268299559 # B[844, [17, 4, 2, 6], [46, 7, 3, 8]] + 0.000505489038324865442 # B[845, [17, 4, 2, 6], [47, 7, 4, 7]] + -0.00260650572816220009 # B[846, [17, 4, 2, 6], [48, 7, 5, 8]] + -0.00458388666826989831 # B[847, [17, 4, 2, 6], [49, 7, 6, 7]] + -0.0030323259618317824 # B[848, [17, 4, 2, 6], [50, 7, 7, 8]] + 0.000919810997489799165 # B[849, [17, 4, 2, 6], [51, 8, 0, 8]] + 0.00153843620323466154 # B[850, [17, 4, 2, 6], [52, 8, 2, 8]] + 0.00177452104337356975 # B[851, [17, 4, 2, 6], [53, 8, 4, 8]] + -0.00133363365246129796 # B[852, [17, 4, 2, 6], [54, 8, 6, 8]] + 0.000497168699576265929 # B[853, [17, 4, 2, 6], [55, 8, 8, 8]] + 0.00916493227652732945 # B[854, [18, 4, 3, 5], [18, 4, 3, 5]] + 0.00662893191875722591 # B[855, [18, 4, 3, 5], [19, 4, 3, 7]] + 0.00102473567933248147 # B[856, [18, 4, 3, 5], [20, 4, 4, 4]] + 0.000661293664462594619 # B[857, [18, 4, 3, 5], [21, 4, 4, 6]] + 0.00302383517430961438 # B[858, [18, 4, 3, 5], [22, 4, 4, 8]] + 0.00182134236384280147 # B[859, [18, 4, 3, 5], [23, 5, 0, 5]] + 0.00481003527044247467 # B[860, [18, 4, 3, 5], [24, 5, 1, 6]] + 0.00472221587821478311 # B[861, [18, 4, 3, 5], [25, 5, 2, 5]] + 0.00204855894682247092 # B[862, [18, 4, 3, 5], [26, 5, 2, 7]] + 0.00108437129165206425 # B[863, [18, 4, 3, 5], [27, 5, 3, 6]] + 0.000188071259560827417 # B[864, [18, 4, 3, 5], [28, 5, 3, 8]] + 0.000402244806083140727 # B[865, [18, 4, 3, 5], [29, 5, 4, 5]] + 0.00350511561101824257 # B[866, [18, 4, 3, 5], [30, 5, 4, 7]] + -0.00196731170271619883 # B[867, [18, 4, 3, 5], [31, 5, 5, 6]] + -0.000854471064769226317 # B[868, [18, 4, 3, 5], [32, 5, 5, 8]] + 0.00163753590726098495 # B[869, [18, 4, 3, 5], [33, 6, 0, 6]] + 0.00678767470498069323 # B[870, [18, 4, 3, 5], [34, 6, 1, 7]] + 0.00671898362129526739 # B[871, [18, 4, 3, 5], [35, 6, 2, 6]] + 0.00504150139406711259 # B[872, [18, 4, 3, 5], [36, 6, 2, 8]] + -0.00150058947564556469 # B[873, [18, 4, 3, 5], [37, 6, 3, 7]] + 0.00126561580055304518 # B[874, [18, 4, 3, 5], [38, 6, 4, 6]] + -0.000556565865268397481 # B[875, [18, 4, 3, 5], [39, 6, 4, 8]] + -0.00527488386402661519 # B[876, [18, 4, 3, 5], [40, 6, 5, 7]] + -0.00214157468754809163 # B[877, [18, 4, 3, 5], [41, 6, 6, 6]] + -0.0020431148178264337 # B[878, [18, 4, 3, 5], [42, 6, 6, 8]] + 0.00142704628054338232 # B[879, [18, 4, 3, 5], [43, 7, 0, 7]] + 0.00368882624306161085 # B[880, [18, 4, 3, 5], [44, 7, 1, 8]] + -0.000742447358153045661 # B[881, [18, 4, 3, 5], [45, 7, 2, 7]] + -0.00158678830901623838 # B[882, [18, 4, 3, 5], [46, 7, 3, 8]] + -0.00107876302160130055 # B[883, [18, 4, 3, 5], [47, 7, 4, 7]] + -0.00701537311445033646 # B[884, [18, 4, 3, 5], [48, 7, 5, 8]] + -0.00184801443295596127 # B[885, [18, 4, 3, 5], [49, 7, 6, 7]] + -0.00127678697871524667 # B[886, [18, 4, 3, 5], [50, 7, 7, 8]] + 0.00105641109188138113 # B[887, [18, 4, 3, 5], [51, 8, 0, 8]] + 0.000718098622203026428 # B[888, [18, 4, 3, 5], [52, 8, 2, 8]] + 0.00219486004289275692 # B[889, [18, 4, 3, 5], [53, 8, 4, 8]] + -0.00158748993130468905 # B[890, [18, 4, 3, 5], [54, 8, 6, 8]] + -0.00105128398142791644 # B[891, [18, 4, 3, 5], [55, 8, 8, 8]] + -0.00705876763301777586 # B[892, [19, 4, 3, 7], [19, 4, 3, 7]] + 0.00377186011578763136 # B[893, [19, 4, 3, 7], [20, 4, 4, 4]] + 0.00351225097737749986 # B[894, [19, 4, 3, 7], [21, 4, 4, 6]] + -0.00323798036048509805 # B[895, [19, 4, 3, 7], [22, 4, 4, 8]] + 0.00126225430824061444 # B[896, [19, 4, 3, 7], [23, 5, 0, 5]] + -0.00132900767543010258 # B[897, [19, 4, 3, 7], [24, 5, 1, 6]] + 0.000212743875668733318 # B[898, [19, 4, 3, 7], [25, 5, 2, 5]] + -8.93559293989563963e-05 # B[899, [19, 4, 3, 7], [26, 5, 2, 7]] + 0.00401415269432878544 # B[900, [19, 4, 3, 7], [27, 5, 3, 6]] + -0.00422923196125859352 # B[901, [19, 4, 3, 7], [28, 5, 3, 8]] + 0.00252733635050122335 # B[902, [19, 4, 3, 7], [29, 5, 4, 5]] + -0.00020969110581340808 # B[903, [19, 4, 3, 7], [30, 5, 4, 7]] + -0.000969147769818896193 # B[904, [19, 4, 3, 7], [31, 5, 5, 6]] + -0.00249817386761041864 # B[905, [19, 4, 3, 7], [32, 5, 5, 8]] + 7.71120512828363247e-05 # B[906, [19, 4, 3, 7], [33, 6, 0, 6]] + 0.00560302176075209817 # B[907, [19, 4, 3, 7], [34, 6, 1, 7]] + 0.00342833731167378752 # B[908, [19, 4, 3, 7], [35, 6, 2, 6]] + 0.00116548365936076578 # B[909, [19, 4, 3, 7], [36, 6, 2, 8]] + 0.00499590856190199745 # B[910, [19, 4, 3, 7], [37, 6, 3, 7]] + 0.00391644837067879614 # B[911, [19, 4, 3, 7], [38, 6, 4, 6]] + 0.00116606811408420229 # B[912, [19, 4, 3, 7], [39, 6, 4, 8]] + -0.000563820914290556058 # B[913, [19, 4, 3, 7], [40, 6, 5, 7]] + -0.000251464925992161276 # B[914, [19, 4, 3, 7], [41, 6, 6, 6]] + -0.000718753250305587815 # B[915, [19, 4, 3, 7], [42, 6, 6, 8]] + 0.000453024387943248494 # B[916, [19, 4, 3, 7], [43, 7, 0, 7]] + -0.00146422451962339994 # B[917, [19, 4, 3, 7], [44, 7, 1, 8]] + 0.00271974781140060795 # B[918, [19, 4, 3, 7], [45, 7, 2, 7]] + 0.00151707017829591159 # B[919, [19, 4, 3, 7], [46, 7, 3, 8]] + 0.00202377896423465691 # B[920, [19, 4, 3, 7], [47, 7, 4, 7]] + -0.00131185948123999779 # B[921, [19, 4, 3, 7], [48, 7, 5, 8]] + 0.000239464941185672797 # B[922, [19, 4, 3, 7], [49, 7, 6, 7]] + -0.000667571478871501964 # B[923, [19, 4, 3, 7], [50, 7, 7, 8]] + 0.000666789360176615192 # B[924, [19, 4, 3, 7], [51, 8, 0, 8]] + 0.00179543252151156355 # B[925, [19, 4, 3, 7], [52, 8, 2, 8]] + 0.000954396542852647967 # B[926, [19, 4, 3, 7], [53, 8, 4, 8]] + 0.000593331439814590023 # B[927, [19, 4, 3, 7], [54, 8, 6, 8]] + -0.000292670120459602445 # B[928, [19, 4, 3, 7], [55, 8, 8, 8]] + -0.000303353861178074294 # B[929, [20, 4, 4, 4], [20, 4, 4, 4]] + -6.41585335468541906e-05 # B[930, [20, 4, 4, 4], [21, 4, 4, 6]] + 0.00145464895340288725 # B[931, [20, 4, 4, 4], [22, 4, 4, 8]] + 0.000557677559397141802 # B[932, [20, 4, 4, 4], [23, 5, 0, 5]] + 0.00214733001664968188 # B[933, [20, 4, 4, 4], [24, 5, 1, 6]] + 0.000196804226194771757 # B[934, [20, 4, 4, 4], [25, 5, 2, 5]] + 0.00169621771662652795 # B[935, [20, 4, 4, 4], [26, 5, 2, 7]] + -0.00126951106424718924 # B[936, [20, 4, 4, 4], [27, 5, 3, 6]] + 0.00156201190059711802 # B[937, [20, 4, 4, 4], [28, 5, 3, 8]] + -0.000188505112089858498 # B[938, [20, 4, 4, 4], [29, 5, 4, 5]] + 0.00101485096974841295 # B[939, [20, 4, 4, 4], [30, 5, 4, 7]] + -0.000254023094278113288 # B[940, [20, 4, 4, 4], [31, 5, 5, 6]] + -0.000332430225508446864 # B[941, [20, 4, 4, 4], [32, 5, 5, 8]] + 0.000393172799404761797 # B[942, [20, 4, 4, 4], [33, 6, 0, 6]] + -0.000945851456653874594 # B[943, [20, 4, 4, 4], [34, 6, 1, 7]] + 0.000937118523093692299 # B[944, [20, 4, 4, 4], [35, 6, 2, 6]] + 0.00108463610451345858 # B[945, [20, 4, 4, 4], [36, 6, 2, 8]] + -0.00167878968186336089 # B[946, [20, 4, 4, 4], [37, 6, 3, 7]] + 0.000109649976457827647 # B[947, [20, 4, 4, 4], [38, 6, 4, 6]] + 0.000205908523746248934 # B[948, [20, 4, 4, 4], [39, 6, 4, 8]] + -0.000952641271225448949 # B[949, [20, 4, 4, 4], [40, 6, 5, 7]] + -0.000386842165161269298 # B[950, [20, 4, 4, 4], [41, 6, 6, 6]] + -0.000662992329463731739 # B[951, [20, 4, 4, 4], [42, 6, 6, 8]] + 0.000368522676488847178 # B[952, [20, 4, 4, 4], [43, 7, 0, 7]] + -0.000181924614212486402 # B[953, [20, 4, 4, 4], [44, 7, 1, 8]] + -0.00119374010493299761 # B[954, [20, 4, 4, 4], [45, 7, 2, 7]] + -0.000775398926021152179 # B[955, [20, 4, 4, 4], [46, 7, 3, 8]] + -0.000670782103704289923 # B[956, [20, 4, 4, 4], [47, 7, 4, 7]] + -0.00192682764111087456 # B[957, [20, 4, 4, 4], [48, 7, 5, 8]] + -0.000648663865567958298 # B[958, [20, 4, 4, 4], [49, 7, 6, 7]] + -0.000387954189232417312 # B[959, [20, 4, 4, 4], [50, 7, 7, 8]] + 0.000302370648048068055 # B[960, [20, 4, 4, 4], [51, 8, 0, 8]] + -0.00085980088667597307 # B[961, [20, 4, 4, 4], [52, 8, 2, 8]] + 0.000568399123124077588 # B[962, [20, 4, 4, 4], [53, 8, 4, 8]] + -0.000482151590861096269 # B[963, [20, 4, 4, 4], [54, 8, 6, 8]] + -0.000405828455879983507 # B[964, [20, 4, 4, 4], [55, 8, 8, 8]] + 0.00165997230068267755 # B[965, [21, 4, 4, 6], [21, 4, 4, 6]] + 0.000963896255597472551 # B[966, [21, 4, 4, 6], [22, 4, 4, 8]] + 0.0002094521100325826 # B[967, [21, 4, 4, 6], [23, 5, 0, 5]] + 0.000534879644705995444 # B[968, [21, 4, 4, 6], [24, 5, 1, 6]] + 0.00292236533791157905 # B[969, [21, 4, 4, 6], [25, 5, 2, 5]] + 0.00151524368635043427 # B[970, [21, 4, 4, 6], [26, 5, 2, 7]] + -0.00101689007388491501 # B[971, [21, 4, 4, 6], [27, 5, 3, 6]] + 0.000738459806183821427 # B[972, [21, 4, 4, 6], [28, 5, 3, 8]] + 0.00148643764242684627 # B[973, [21, 4, 4, 6], [29, 5, 4, 5]] + 0.0011556877894129472 # B[974, [21, 4, 4, 6], [30, 5, 4, 7]] + -0.000208381440186615127 # B[975, [21, 4, 4, 6], [31, 5, 5, 6]] + -0.00143743030752817389 # B[976, [21, 4, 4, 6], [32, 5, 5, 8]] + -0.00016600302639456152 # B[977, [21, 4, 4, 6], [33, 6, 0, 6]] + 0.00172160125073629253 # B[978, [21, 4, 4, 6], [34, 6, 1, 7]] + 0.00344812165058533751 # B[979, [21, 4, 4, 6], [35, 6, 2, 6]] + 0.000544104512334869089 # B[980, [21, 4, 4, 6], [36, 6, 2, 8]] + -0.00182558144376257503 # B[981, [21, 4, 4, 6], [37, 6, 3, 7]] + 0.00101065848983370246 # B[982, [21, 4, 4, 6], [38, 6, 4, 6]] + 0.00103400096073465869 # B[983, [21, 4, 4, 6], [39, 6, 4, 8]] + -0.000235944095127582111 # B[984, [21, 4, 4, 6], [40, 6, 5, 7]] + 0.000154580830205655606 # B[985, [21, 4, 4, 6], [41, 6, 6, 6]] + -0.000488680460493023505 # B[986, [21, 4, 4, 6], [42, 6, 6, 8]] + 3.83739714257189113e-05 # B[987, [21, 4, 4, 6], [43, 7, 0, 7]] + -0.000275037336268196993 # B[988, [21, 4, 4, 6], [44, 7, 1, 8]] + 0.0017878021157122859 # B[989, [21, 4, 4, 6], [45, 7, 2, 7]] + -0.00110857713686632331 # B[990, [21, 4, 4, 6], [46, 7, 3, 8]] + -0.000126074852562767237 # B[991, [21, 4, 4, 6], [47, 7, 4, 7]] + -0.00125862858469075189 # B[992, [21, 4, 4, 6], [48, 7, 5, 8]] + -0.000277638160776805254 # B[993, [21, 4, 4, 6], [49, 7, 6, 7]] + 0.000163335859971639602 # B[994, [21, 4, 4, 6], [50, 7, 7, 8]] + 0.000151747507838979889 # B[995, [21, 4, 4, 6], [51, 8, 0, 8]] + 0.00156180455186682998 # B[996, [21, 4, 4, 6], [52, 8, 2, 8]] + 0.00112614353705531994 # B[997, [21, 4, 4, 6], [53, 8, 4, 8]] + -0.000376140365477903652 # B[998, [21, 4, 4, 6], [54, 8, 6, 8]] + -0.000378786757414536351 # B[999, [21, 4, 4, 6], [55, 8, 8, 8]] + -0.00186381195965971969 # B[1000, [22, 4, 4, 8], [22, 4, 4, 8]] + 0.000334060235611270684 # B[1001, [22, 4, 4, 8], [23, 5, 0, 5]] + -0.000182139490643212255 # B[1002, [22, 4, 4, 8], [24, 5, 1, 6]] + -0.000866414678376911532 # B[1003, [22, 4, 4, 8], [25, 5, 2, 5]] + -0.000713836573909394211 # B[1004, [22, 4, 4, 8], [26, 5, 2, 7]] + 0.00340359387460056721 # B[1005, [22, 4, 4, 8], [27, 5, 3, 6]] + -0.0025631762232975969 # B[1006, [22, 4, 4, 8], [28, 5, 3, 8]] + 0.00154837338005092001 # B[1007, [22, 4, 4, 8], [29, 5, 4, 5]] + -0.000713785025005329171 # B[1008, [22, 4, 4, 8], [30, 5, 4, 7]] + -6.17852167664190155e-06 # B[1009, [22, 4, 4, 8], [31, 5, 5, 6]] + -0.000925788250245492385 # B[1010, [22, 4, 4, 8], [32, 5, 5, 8]] + -0.000220618203180443506 # B[1011, [22, 4, 4, 8], [33, 6, 0, 6]] + 0.00158760304062654546 # B[1012, [22, 4, 4, 8], [34, 6, 1, 7]] + -0.00201296543384867077 # B[1013, [22, 4, 4, 8], [35, 6, 2, 6]] + -0.000153111573438037551 # B[1014, [22, 4, 4, 8], [36, 6, 2, 8]] + 0.001936342943994784 # B[1015, [22, 4, 4, 8], [37, 6, 3, 7]] + 0.0014724303902098404 # B[1016, [22, 4, 4, 8], [38, 6, 4, 6]] + 0.000412977919829218137 # B[1017, [22, 4, 4, 8], [39, 6, 4, 8]] + 0.000243129124011996767 # B[1018, [22, 4, 4, 8], [40, 6, 5, 7]] + 0.000433542078585167322 # B[1019, [22, 4, 4, 8], [41, 6, 6, 6]] + 5.87712210821707964e-05 # B[1020, [22, 4, 4, 8], [42, 6, 6, 8]] + -2.13873587015245281e-05 # B[1021, [22, 4, 4, 8], [43, 7, 0, 7]] + -0.00121671500578664389 # B[1022, [22, 4, 4, 8], [44, 7, 1, 8]] + 0.00185443425860575776 # B[1023, [22, 4, 4, 8], [45, 7, 2, 7]] + 0.00153976874095648406 # B[1024, [22, 4, 4, 8], [46, 7, 3, 8]] + 0.00100585852984078766 # B[1025, [22, 4, 4, 8], [47, 7, 4, 7]] + 0.000146502145157426621 # B[1026, [22, 4, 4, 8], [48, 7, 5, 8]] + 0.00026572798098887726 # B[1027, [22, 4, 4, 8], [49, 7, 6, 7]] + 0.000239744529446223043 # B[1028, [22, 4, 4, 8], [50, 7, 7, 8]] + 3.13331575558552233e-05 # B[1029, [22, 4, 4, 8], [51, 8, 0, 8]] + 0.0005761629631739415 # B[1030, [22, 4, 4, 8], [52, 8, 2, 8]] + 0.00020451472183747807 # B[1031, [22, 4, 4, 8], [53, 8, 4, 8]] + 0.000761501707699011737 # B[1032, [22, 4, 4, 8], [54, 8, 6, 8]] + 4.7608269104475881e-05 # B[1033, [22, 4, 4, 8], [55, 8, 8, 8]] + 0.00010288893231941848 # B[1034, [23, 5, 0, 5], [23, 5, 0, 5]] + -0.000598160679614365143 # B[1035, [23, 5, 0, 5], [24, 5, 1, 6]] + -0.000125600887517359969 # B[1036, [23, 5, 0, 5], [25, 5, 2, 5]] + -0.000541602347577959872 # B[1037, [23, 5, 0, 5], [26, 5, 2, 7]] + 0.000138742295315047448 # B[1038, [23, 5, 0, 5], [27, 5, 3, 6]] + 0.000320496112291311641 # B[1039, [23, 5, 0, 5], [28, 5, 3, 8]] + 9.77076363189860464e-05 # B[1040, [23, 5, 0, 5], [29, 5, 4, 5]] + -0.00018519393057754574 # B[1041, [23, 5, 0, 5], [30, 5, 4, 7]] + -0.000314308790209320843 # B[1042, [23, 5, 0, 5], [31, 5, 5, 6]] + -2.03507196530547385e-05 # B[1043, [23, 5, 0, 5], [32, 5, 5, 8]] + -8.76692912155085935e-08 # B[1044, [23, 5, 0, 5], [33, 6, 0, 6]] + -0.000208914241663854874 # B[1045, [23, 5, 0, 5], [34, 6, 1, 7]] + 0.000289191305925793653 # B[1046, [23, 5, 0, 5], [35, 6, 2, 6]] + 0.000292827060287376498 # B[1047, [23, 5, 0, 5], [36, 6, 2, 8]] + -0.000195999965143696386 # B[1048, [23, 5, 0, 5], [37, 6, 3, 7]] + 0.000122837407081860615 # B[1049, [23, 5, 0, 5], [38, 6, 4, 6]] + 0.000238061673948679331 # B[1050, [23, 5, 0, 5], [39, 6, 4, 8]] + 6.23458911314621333e-06 # B[1051, [23, 5, 0, 5], [40, 6, 5, 7]] + 0.000153645644536796327 # B[1052, [23, 5, 0, 5], [41, 6, 6, 6]] + 0.000208144485879115104 # B[1053, [23, 5, 0, 5], [42, 6, 6, 8]] + 0.000107382317423423967 # B[1054, [23, 5, 0, 5], [43, 7, 0, 7]] + -3.16437877474207152e-05 # B[1055, [23, 5, 0, 5], [44, 7, 1, 8]] + 5.2567890411161361e-05 # B[1056, [23, 5, 0, 5], [45, 7, 2, 7]] + -0.000407365287815795313 # B[1057, [23, 5, 0, 5], [46, 7, 3, 8]] + -0.000277007442936893014 # B[1058, [23, 5, 0, 5], [47, 7, 4, 7]] + -0.000163960409271388802 # B[1059, [23, 5, 0, 5], [48, 7, 5, 8]] + -0.00018222236229294142 # B[1060, [23, 5, 0, 5], [49, 7, 6, 7]] + -8.93725149996096868e-05 # B[1061, [23, 5, 0, 5], [50, 7, 7, 8]] + -4.59835267753172516e-05 # B[1062, [23, 5, 0, 5], [51, 8, 0, 8]] + -3.00980967951527262e-05 # B[1063, [23, 5, 0, 5], [52, 8, 2, 8]] + -0.00011786089545340328 # B[1064, [23, 5, 0, 5], [53, 8, 4, 8]] + 6.24840877215676604e-05 # B[1065, [23, 5, 0, 5], [54, 8, 6, 8]] + 0.000151333518371397913 # B[1066, [23, 5, 0, 5], [55, 8, 8, 8]] + -0.00373509601310103353 # B[1067, [24, 5, 1, 6], [24, 5, 1, 6]] + 0.00250350668234289742 # B[1068, [24, 5, 1, 6], [25, 5, 2, 5]] + -0.00141763987470412255 # B[1069, [24, 5, 1, 6], [26, 5, 2, 7]] + -0.000458490741576836162 # B[1070, [24, 5, 1, 6], [27, 5, 3, 6]] + 0.000169432811229417585 # B[1071, [24, 5, 1, 6], [28, 5, 3, 8]] + -0.000531768848310092699 # B[1072, [24, 5, 1, 6], [29, 5, 4, 5]] + 0.0019269207337581605 # B[1073, [24, 5, 1, 6], [30, 5, 4, 7]] + 0.000623468915929115824 # B[1074, [24, 5, 1, 6], [31, 5, 5, 6]] + 0.000262459747020924762 # B[1075, [24, 5, 1, 6], [32, 5, 5, 8]] + 0.000319464830252011445 # B[1076, [24, 5, 1, 6], [33, 6, 0, 6]] + 0.00250974732963905444 # B[1077, [24, 5, 1, 6], [34, 6, 1, 7]] + 0.00423653007687384807 # B[1078, [24, 5, 1, 6], [35, 6, 2, 6]] + 0.00144771358428595707 # B[1079, [24, 5, 1, 6], [36, 6, 2, 8]] + 0.00255496505633429419 # B[1080, [24, 5, 1, 6], [37, 6, 3, 7]] + -0.000923899857380450218 # B[1081, [24, 5, 1, 6], [38, 6, 4, 6]] + -0.000308666389289608337 # B[1082, [24, 5, 1, 6], [39, 6, 4, 8]] + 0.00222537659577300671 # B[1083, [24, 5, 1, 6], [40, 6, 5, 7]] + -0.00107541311587263343 # B[1084, [24, 5, 1, 6], [41, 6, 6, 6]] + -0.00278767944085371068 # B[1085, [24, 5, 1, 6], [42, 6, 6, 8]] + -0.000867530969177243705 # B[1086, [24, 5, 1, 6], [43, 7, 0, 7]] + 0.00357297895621819196 # B[1087, [24, 5, 1, 6], [44, 7, 1, 8]] + 0.00383976572090019216 # B[1088, [24, 5, 1, 6], [45, 7, 2, 7]] + -0.000580234942856992786 # B[1089, [24, 5, 1, 6], [46, 7, 3, 8]] + 0.00102888910081111798 # B[1090, [24, 5, 1, 6], [47, 7, 4, 7]] + 0.00132107614311613355 # B[1091, [24, 5, 1, 6], [48, 7, 5, 8]] + 0.00101848252621374036 # B[1092, [24, 5, 1, 6], [49, 7, 6, 7]] + 0.00160018234143227862 # B[1093, [24, 5, 1, 6], [50, 7, 7, 8]] + -5.52824024903572631e-05 # B[1094, [24, 5, 1, 6], [51, 8, 0, 8]] + 4.59186780197786033e-05 # B[1095, [24, 5, 1, 6], [52, 8, 2, 8]] + -0.000153436254581188554 # B[1096, [24, 5, 1, 6], [53, 8, 4, 8]] + -0.000546750998621967597 # B[1097, [24, 5, 1, 6], [54, 8, 6, 8]] + 0.000595956738118895348 # B[1098, [24, 5, 1, 6], [55, 8, 8, 8]] + 0.0083807047595118693 # B[1099, [25, 5, 2, 5], [25, 5, 2, 5]] + -0.000170544318645505719 # B[1100, [25, 5, 2, 5], [26, 5, 2, 7]] + 0.00235544441902155004 # B[1101, [25, 5, 2, 5], [27, 5, 3, 6]] + -0.00340197827063909962 # B[1102, [25, 5, 2, 5], [28, 5, 3, 8]] + 0.00311335525578198104 # B[1103, [25, 5, 2, 5], [29, 5, 4, 5]] + 0.00185214714164834123 # B[1104, [25, 5, 2, 5], [30, 5, 4, 7]] + -0.00328905913600528992 # B[1105, [25, 5, 2, 5], [31, 5, 5, 6]] + -0.00141866010082636025 # B[1106, [25, 5, 2, 5], [32, 5, 5, 8]] + 0.000176317033907393006 # B[1107, [25, 5, 2, 5], [33, 6, 0, 6]] + 0.00648328973805229608 # B[1108, [25, 5, 2, 5], [34, 6, 1, 7]] + 4.8980528358618259e-05 # B[1109, [25, 5, 2, 5], [35, 6, 2, 6]] + -0.00616971046300731144 # B[1110, [25, 5, 2, 5], [36, 6, 2, 8]] + -0.00135942372726050205 # B[1111, [25, 5, 2, 5], [37, 6, 3, 7]] + 0.000572735024796908881 # B[1112, [25, 5, 2, 5], [38, 6, 4, 6]] + -0.00229752149848994405 # B[1113, [25, 5, 2, 5], [39, 6, 4, 8]] + 0.0003485310815041524 # B[1114, [25, 5, 2, 5], [40, 6, 5, 7]] + -0.0011437361439647427 # B[1115, [25, 5, 2, 5], [41, 6, 6, 6]] + -0.000604819873822432311 # B[1116, [25, 5, 2, 5], [42, 6, 6, 8]] + 9.06237770597643696e-05 # B[1117, [25, 5, 2, 5], [43, 7, 0, 7]] + -0.000382141545017884894 # B[1118, [25, 5, 2, 5], [44, 7, 1, 8]] + -0.000842464094047663554 # B[1119, [25, 5, 2, 5], [45, 7, 2, 7]] + 0.000461973830441065811 # B[1120, [25, 5, 2, 5], [46, 7, 3, 8]] + 2.86192620363814355e-06 # B[1121, [25, 5, 2, 5], [47, 7, 4, 7]] + -0.0023436531447123838 # B[1122, [25, 5, 2, 5], [48, 7, 5, 8]] + 0.00134025173860287308 # B[1123, [25, 5, 2, 5], [49, 7, 6, 7]] + -0.000520013981518205846 # B[1124, [25, 5, 2, 5], [50, 7, 7, 8]] + 0.000515782740310496285 # B[1125, [25, 5, 2, 5], [51, 8, 0, 8]] + 0.00421651313615256564 # B[1126, [25, 5, 2, 5], [52, 8, 2, 8]] + 0.000755327719218409519 # B[1127, [25, 5, 2, 5], [53, 8, 4, 8]] + 0.000182937308412391315 # B[1128, [25, 5, 2, 5], [54, 8, 6, 8]] + 8.10383680097163071e-05 # B[1129, [25, 5, 2, 5], [55, 8, 8, 8]] + 0.000177735296666065024 # B[1130, [26, 5, 2, 7], [26, 5, 2, 7]] + -0.000642334677407747565 # B[1131, [26, 5, 2, 7], [27, 5, 3, 6]] + 0.000205172894139061396 # B[1132, [26, 5, 2, 7], [28, 5, 3, 8]] + -0.000537004220752698019 # B[1133, [26, 5, 2, 7], [29, 5, 4, 5]] + 5.14115941491347442e-05 # B[1134, [26, 5, 2, 7], [30, 5, 4, 7]] + 0.000417673445165051005 # B[1135, [26, 5, 2, 7], [31, 5, 5, 6]] + 0.00158446769775330391 # B[1136, [26, 5, 2, 7], [32, 5, 5, 8]] + 0.00121383407410429606 # B[1137, [26, 5, 2, 7], [33, 6, 0, 6]] + -0.00111992976945914785 # B[1138, [26, 5, 2, 7], [34, 6, 1, 7]] + 0.00398972286341117699 # B[1139, [26, 5, 2, 7], [35, 6, 2, 6]] + 0.00454565411209783762 # B[1140, [26, 5, 2, 7], [36, 6, 2, 8]] + -0.00300928796618537761 # B[1141, [26, 5, 2, 7], [37, 6, 3, 7]] + -0.00280024702462813163 # B[1142, [26, 5, 2, 7], [38, 6, 4, 6]] + 0.00182097597359056305 # B[1143, [26, 5, 2, 7], [39, 6, 4, 8]] + 0.00247143387165752772 # B[1144, [26, 5, 2, 7], [40, 6, 5, 7]] + -0.00143698477566456435 # B[1145, [26, 5, 2, 7], [41, 6, 6, 6]] + -0.00105878554545993375 # B[1146, [26, 5, 2, 7], [42, 6, 6, 8]] + 0.000650619036842032747 # B[1147, [26, 5, 2, 7], [43, 7, 0, 7]] + 8.72947879012740853e-05 # B[1148, [26, 5, 2, 7], [44, 7, 1, 8]] + -0.0002084941102769855 # B[1149, [26, 5, 2, 7], [45, 7, 2, 7]] + -0.000924608969529588931 # B[1150, [26, 5, 2, 7], [46, 7, 3, 8]] + -0.000320719808114693777 # B[1151, [26, 5, 2, 7], [47, 7, 4, 7]] + 0.00241998856780361801 # B[1152, [26, 5, 2, 7], [48, 7, 5, 8]] + -0.00171923440812344827 # B[1153, [26, 5, 2, 7], [49, 7, 6, 7]] + -0.000301390241580377569 # B[1154, [26, 5, 2, 7], [50, 7, 7, 8]] + -6.37461557401481499e-05 # B[1155, [26, 5, 2, 7], [51, 8, 0, 8]] + 0.00161644303684405446 # B[1156, [26, 5, 2, 7], [52, 8, 2, 8]] + 0.00104379414920739667 # B[1157, [26, 5, 2, 7], [53, 8, 4, 8]] + -0.00119795702190159808 # B[1158, [26, 5, 2, 7], [54, 8, 6, 8]] + 0.000604059138156293803 # B[1159, [26, 5, 2, 7], [55, 8, 8, 8]] + 0.000513459633959805622 # B[1160, [27, 5, 3, 6], [27, 5, 3, 6]] + -0.000172334638360790993 # B[1161, [27, 5, 3, 6], [28, 5, 3, 8]] + 1.60719061511648345e-05 # B[1162, [27, 5, 3, 6], [29, 5, 4, 5]] + 0.00440279299288983371 # B[1163, [27, 5, 3, 6], [30, 5, 4, 7]] + 0.000549761981236742206 # B[1164, [27, 5, 3, 6], [31, 5, 5, 6]] + 0.000424619689378998542 # B[1165, [27, 5, 3, 6], [32, 5, 5, 8]] + 0.000247367934895610653 # B[1166, [27, 5, 3, 6], [33, 6, 0, 6]] + 0.00400569055534595944 # B[1167, [27, 5, 3, 6], [34, 6, 1, 7]] + 0.00274378194299987679 # B[1168, [27, 5, 3, 6], [35, 6, 2, 6]] + 0.00368141326251353665 # B[1169, [27, 5, 3, 6], [36, 6, 2, 8]] + 0.00160469169395054817 # B[1170, [27, 5, 3, 6], [37, 6, 3, 7]] + 0.000105807739550402985 # B[1171, [27, 5, 3, 6], [38, 6, 4, 6]] + -0.000682801438033796976 # B[1172, [27, 5, 3, 6], [39, 6, 4, 8]] + -0.00121964915110857504 # B[1173, [27, 5, 3, 6], [40, 6, 5, 7]] + -0.000817665263990522556 # B[1174, [27, 5, 3, 6], [41, 6, 6, 6]] + 0.000534593784435832137 # B[1175, [27, 5, 3, 6], [42, 6, 6, 8]] + 0.000116542343021167755 # B[1176, [27, 5, 3, 6], [43, 7, 0, 7]] + 0.00351267154418699948 # B[1177, [27, 5, 3, 6], [44, 7, 1, 8]] + -0.00189934642995405814 # B[1178, [27, 5, 3, 6], [45, 7, 2, 7]] + 0.000751906974843792597 # B[1179, [27, 5, 3, 6], [46, 7, 3, 8]] + -0.000446808189773967301 # B[1180, [27, 5, 3, 6], [47, 7, 4, 7]] + -0.00324699511848197502 # B[1181, [27, 5, 3, 6], [48, 7, 5, 8]] + 2.53540837371335481e-05 # B[1182, [27, 5, 3, 6], [49, 7, 6, 7]] + 7.5273388360289073e-07 # B[1183, [27, 5, 3, 6], [50, 7, 7, 8]] + 0.00023346363571073725 # B[1184, [27, 5, 3, 6], [51, 8, 0, 8]] + 0.000490008984593369619 # B[1185, [27, 5, 3, 6], [52, 8, 2, 8]] + 0.000205260233742234413 # B[1186, [27, 5, 3, 6], [53, 8, 4, 8]] + -7.84984665939646165e-05 # B[1187, [27, 5, 3, 6], [54, 8, 6, 8]] + -0.000299454037036409743 # B[1188, [27, 5, 3, 6], [55, 8, 8, 8]] + -0.00411961786705090406 # B[1189, [28, 5, 3, 8], [28, 5, 3, 8]] + 0.00256764268592788759 # B[1190, [28, 5, 3, 8], [29, 5, 4, 5]] + -0.000267820435572239945 # B[1191, [28, 5, 3, 8], [30, 5, 4, 7]] + 0.000545048575291992229 # B[1192, [28, 5, 3, 8], [31, 5, 5, 6]] + -0.000141236037433873154 # B[1193, [28, 5, 3, 8], [32, 5, 5, 8]] + -8.17647193563642016e-05 # B[1194, [28, 5, 3, 8], [33, 6, 0, 6]] + 0.00184594470809960887 # B[1195, [28, 5, 3, 8], [34, 6, 1, 7]] + 0.000715653691449843685 # B[1196, [28, 5, 3, 8], [35, 6, 2, 6]] + -0.000371782729873919304 # B[1197, [28, 5, 3, 8], [36, 6, 2, 8]] + 0.00184451560473704312 # B[1198, [28, 5, 3, 8], [37, 6, 3, 7]] + 0.00298992898894900189 # B[1199, [28, 5, 3, 8], [38, 6, 4, 6]] + 0.00087474408278464047 # B[1200, [28, 5, 3, 8], [39, 6, 4, 8]] + 0.00115889056554823421 # B[1201, [28, 5, 3, 8], [40, 6, 5, 7]] + -0.000209440071593354482 # B[1202, [28, 5, 3, 8], [41, 6, 6, 6]] + 0.000707847416081031772 # B[1203, [28, 5, 3, 8], [42, 6, 6, 8]] + 0.00025922895119332573 # B[1204, [28, 5, 3, 8], [43, 7, 0, 7]] + -0.00210744601505012327 # B[1205, [28, 5, 3, 8], [44, 7, 1, 8]] + -0.00187401632149015486 # B[1206, [28, 5, 3, 8], [45, 7, 2, 7]] + 0.000616682247583759391 # B[1207, [28, 5, 3, 8], [46, 7, 3, 8]] + 0.00142526179781785924 # B[1208, [28, 5, 3, 8], [47, 7, 4, 7]] + -9.1619163886703936e-06 # B[1209, [28, 5, 3, 8], [48, 7, 5, 8]] + -0.000300978843055903222 # B[1210, [28, 5, 3, 8], [49, 7, 6, 7]] + -0.000124034381208077554 # B[1211, [28, 5, 3, 8], [50, 7, 7, 8]] + 0.000249158311162858692 # B[1212, [28, 5, 3, 8], [51, 8, 0, 8]] + -0.000970252220622513538 # B[1213, [28, 5, 3, 8], [52, 8, 2, 8]] + 0.000840312328335843066 # B[1214, [28, 5, 3, 8], [53, 8, 4, 8]] + 0.000145361901756495965 # B[1215, [28, 5, 3, 8], [54, 8, 6, 8]] + 0.00013163551986085896 # B[1216, [28, 5, 3, 8], [55, 8, 8, 8]] + 0.00265810885844912576 # B[1217, [29, 5, 4, 5], [29, 5, 4, 5]] + 0.00191793603428468823 # B[1218, [29, 5, 4, 5], [30, 5, 4, 7]] + 0.000446118694394436605 # B[1219, [29, 5, 4, 5], [31, 5, 5, 6]] + -9.59445098255573559e-05 # B[1220, [29, 5, 4, 5], [32, 5, 5, 8]] + 0.000369255428727587043 # B[1221, [29, 5, 4, 5], [33, 6, 0, 6]] + -0.000553149628059141762 # B[1222, [29, 5, 4, 5], [34, 6, 1, 7]] + 0.00315275275750991242 # B[1223, [29, 5, 4, 5], [35, 6, 2, 6]] + 0.00138540352181828336 # B[1224, [29, 5, 4, 5], [36, 6, 2, 8]] + 0.000776256233303879162 # B[1225, [29, 5, 4, 5], [37, 6, 3, 7]] + 0.000594477884906325672 # B[1226, [29, 5, 4, 5], [38, 6, 4, 6]] + 0.000757712543509288586 # B[1227, [29, 5, 4, 5], [39, 6, 4, 8]] + -0.000917903532807641184 # B[1228, [29, 5, 4, 5], [40, 6, 5, 7]] + -0.000915313398456763742 # B[1229, [29, 5, 4, 5], [41, 6, 6, 6]] + -0.00116732293566375843 # B[1230, [29, 5, 4, 5], [42, 6, 6, 8]] + 0.000172432189541951719 # B[1231, [29, 5, 4, 5], [43, 7, 0, 7]] + 0.000845370011774060912 # B[1232, [29, 5, 4, 5], [44, 7, 1, 8]] + 0.00178029205661471915 # B[1233, [29, 5, 4, 5], [45, 7, 2, 7]] + 0.00129739636685697463 # B[1234, [29, 5, 4, 5], [46, 7, 3, 8]] + 0.000282865369400489564 # B[1235, [29, 5, 4, 5], [47, 7, 4, 7]] + -0.00178988233479955398 # B[1236, [29, 5, 4, 5], [48, 7, 5, 8]] + 0.00023603474784275949 # B[1237, [29, 5, 4, 5], [49, 7, 6, 7]] + -0.000461436431325358207 # B[1238, [29, 5, 4, 5], [50, 7, 7, 8]] + 0.000234131705926524103 # B[1239, [29, 5, 4, 5], [51, 8, 0, 8]] + 0.00216254821351878363 # B[1240, [29, 5, 4, 5], [52, 8, 2, 8]] + 0.000831658742681578439 # B[1241, [29, 5, 4, 5], [53, 8, 4, 8]] + -0.00046318901257626742 # B[1242, [29, 5, 4, 5], [54, 8, 6, 8]] + -0.000607580535321294163 # B[1243, [29, 5, 4, 5], [55, 8, 8, 8]] + 0.00158347719827001653 # B[1244, [30, 5, 4, 7], [30, 5, 4, 7]] + 0.00120733638068271261 # B[1245, [30, 5, 4, 7], [31, 5, 5, 6]] + -0.000191610125195333311 # B[1246, [30, 5, 4, 7], [32, 5, 5, 8]] + -0.000363280761575070915 # B[1247, [30, 5, 4, 7], [33, 6, 0, 6]] + 0.0015080393447339897 # B[1248, [30, 5, 4, 7], [34, 6, 1, 7]] + 0.00144737958774105498 # B[1249, [30, 5, 4, 7], [35, 6, 2, 6]] + -0.000191256340607337365 # B[1250, [30, 5, 4, 7], [36, 6, 2, 8]] + 0.00324542123326504103 # B[1251, [30, 5, 4, 7], [37, 6, 3, 7]] + 0.00135369467391198949 # B[1252, [30, 5, 4, 7], [38, 6, 4, 6]] + 0.00077393986417062131 # B[1253, [30, 5, 4, 7], [39, 6, 4, 8]] + 0.00187057819081324836 # B[1254, [30, 5, 4, 7], [40, 6, 5, 7]] + 4.06728949024891956e-05 # B[1255, [30, 5, 4, 7], [41, 6, 6, 6]] + -0.000100060243024913467 # B[1256, [30, 5, 4, 7], [42, 6, 6, 8]] + -0.000170624797097965186 # B[1257, [30, 5, 4, 7], [43, 7, 0, 7]] + -0.00157200294852092963 # B[1258, [30, 5, 4, 7], [44, 7, 1, 8]] + -5.099465391029262e-05 # B[1259, [30, 5, 4, 7], [45, 7, 2, 7]] + 0.00166973065524506255 # B[1260, [30, 5, 4, 7], [46, 7, 3, 8]] + 0.000976468235486894175 # B[1261, [30, 5, 4, 7], [47, 7, 4, 7]] + -0.000570830124590235299 # B[1262, [30, 5, 4, 7], [48, 7, 5, 8]] + 0.000667250794893839427 # B[1263, [30, 5, 4, 7], [49, 7, 6, 7]] + -0.000273376565753529832 # B[1264, [30, 5, 4, 7], [50, 7, 7, 8]] + 0.000206233716860107844 # B[1265, [30, 5, 4, 7], [51, 8, 0, 8]] + 0.00260342927157033218 # B[1266, [30, 5, 4, 7], [52, 8, 2, 8]] + 0.000943954042545826558 # B[1267, [30, 5, 4, 7], [53, 8, 4, 8]] + -0.00022781927635321525 # B[1268, [30, 5, 4, 7], [54, 8, 6, 8]] + -0.000448456045604168733 # B[1269, [30, 5, 4, 7], [55, 8, 8, 8]] + 0.00102985782764508475 # B[1270, [31, 5, 5, 6], [31, 5, 5, 6]] + -8.89908688742153606e-05 # B[1271, [31, 5, 5, 6], [32, 5, 5, 8]] + -0.000162481274467801695 # B[1272, [31, 5, 5, 6], [33, 6, 0, 6]] + 0.00263772603538907271 # B[1273, [31, 5, 5, 6], [34, 6, 1, 7]] + -0.00223528099165903275 # B[1274, [31, 5, 5, 6], [35, 6, 2, 6]] + 0.000441657599119526373 # B[1275, [31, 5, 5, 6], [36, 6, 2, 8]] + 0.00165514785004864176 # B[1276, [31, 5, 5, 6], [37, 6, 3, 7]] + 0.000898928585103351413 # B[1277, [31, 5, 5, 6], [38, 6, 4, 6]] + -0.00026071204606309753 # B[1278, [31, 5, 5, 6], [39, 6, 4, 8]] + -0.000251612913047311385 # B[1279, [31, 5, 5, 6], [40, 6, 5, 7]] + -0.00022773870089292346 # B[1280, [31, 5, 5, 6], [41, 6, 6, 6]] + -0.000449951686975022525 # B[1281, [31, 5, 5, 6], [42, 6, 6, 8]] + -0.000252400784021909741 # B[1282, [31, 5, 5, 6], [43, 7, 0, 7]] + 0.000574433272355396977 # B[1283, [31, 5, 5, 6], [44, 7, 1, 8]] + -0.0014040949400035245 # B[1284, [31, 5, 5, 6], [45, 7, 2, 7]] + 0.00124516802775002586 # B[1285, [31, 5, 5, 6], [46, 7, 3, 8]] + 0.000875572292146320832 # B[1286, [31, 5, 5, 6], [47, 7, 4, 7]] + -0.000509730931921630048 # B[1287, [31, 5, 5, 6], [48, 7, 5, 8]] + 0.000422266146488117777 # B[1288, [31, 5, 5, 6], [49, 7, 6, 7]] + -0.000239146684560266956 # B[1289, [31, 5, 5, 6], [50, 7, 7, 8]] + 9.95899703990707486e-05 # B[1290, [31, 5, 5, 6], [51, 8, 0, 8]] + -0.0020784147827535588 # B[1291, [31, 5, 5, 6], [52, 8, 2, 8]] + 0.000735684723224858811 # B[1292, [31, 5, 5, 6], [53, 8, 4, 8]] + -0.000248804810033285279 # B[1293, [31, 5, 5, 6], [54, 8, 6, 8]] + -0.000598263607047986451 # B[1294, [31, 5, 5, 6], [55, 8, 8, 8]] + 0.000131065920905359436 # B[1295, [32, 5, 5, 8], [32, 5, 5, 8]] + 0.000100196796943449913 # B[1296, [32, 5, 5, 8], [33, 6, 0, 6]] + -0.00173991171955805834 # B[1297, [32, 5, 5, 8], [34, 6, 1, 7]] + -0.000490539010579770906 # B[1298, [32, 5, 5, 8], [35, 6, 2, 6]] + 0.000676191083650941674 # B[1299, [32, 5, 5, 8], [36, 6, 2, 8]] + 0.000446932761165407325 # B[1300, [32, 5, 5, 8], [37, 6, 3, 7]] + -0.000153107558622965576 # B[1301, [32, 5, 5, 8], [38, 6, 4, 6]] + 1.67752859932734574e-05 # B[1302, [32, 5, 5, 8], [39, 6, 4, 8]] + 0.000215146896189506113 # B[1303, [32, 5, 5, 8], [40, 6, 5, 7]] + -0.000188466441880926362 # B[1304, [32, 5, 5, 8], [41, 6, 6, 6]] + -4.80917708388720055e-06 # B[1305, [32, 5, 5, 8], [42, 6, 6, 8]] + -5.04429979448911547e-05 # B[1306, [32, 5, 5, 8], [43, 7, 0, 7]] + -0.000494944862407609067 # B[1307, [32, 5, 5, 8], [44, 7, 1, 8]] + -0.000424473825928651724 # B[1308, [32, 5, 5, 8], [45, 7, 2, 7]] + 0.000417544384337296959 # B[1309, [32, 5, 5, 8], [46, 7, 3, 8]] + 0.000431586591455488614 # B[1310, [32, 5, 5, 8], [47, 7, 4, 7]] + 0.000187341827588022357 # B[1311, [32, 5, 5, 8], [48, 7, 5, 8]] + -6.87669988055673864e-05 # B[1312, [32, 5, 5, 8], [49, 7, 6, 7]] + 0.000147867669408649482 # B[1313, [32, 5, 5, 8], [50, 7, 7, 8]] + -7.32201679551347517e-06 # B[1314, [32, 5, 5, 8], [51, 8, 0, 8]] + -0.000392519615947300787 # B[1315, [32, 5, 5, 8], [52, 8, 2, 8]] + 8.78465325612771269e-05 # B[1316, [32, 5, 5, 8], [53, 8, 4, 8]] + -6.3960070015590606e-05 # B[1317, [32, 5, 5, 8], [54, 8, 6, 8]] + -7.97839909379757101e-06 # B[1318, [32, 5, 5, 8], [55, 8, 8, 8]] + 3.95695067041609838e-05 # B[1319, [33, 6, 0, 6], [33, 6, 0, 6]] + -0.000611658005184461534 # B[1320, [33, 6, 0, 6], [34, 6, 1, 7]] + -0.000277914808470863806 # B[1321, [33, 6, 0, 6], [35, 6, 2, 6]] + 0.000987938388973043716 # B[1322, [33, 6, 0, 6], [36, 6, 2, 8]] + 0.000198558948919527745 # B[1323, [33, 6, 0, 6], [37, 6, 3, 7]] + 9.76274805398642809e-05 # B[1324, [33, 6, 0, 6], [38, 6, 4, 6]] + 9.92197766131464043e-05 # B[1325, [33, 6, 0, 6], [39, 6, 4, 8]] + -4.16996931875308896e-05 # B[1326, [33, 6, 0, 6], [40, 6, 5, 7]] + -5.3495059095630057e-05 # B[1327, [33, 6, 0, 6], [41, 6, 6, 6]] + 1.0720822351671655e-05 # B[1328, [33, 6, 0, 6], [42, 6, 6, 8]] + 0.000114464898537391946 # B[1329, [33, 6, 0, 6], [43, 7, 0, 7]] + -0.00033593422820483651 # B[1330, [33, 6, 0, 6], [44, 7, 1, 8]] + -0.00061665800523461739 # B[1331, [33, 6, 0, 6], [45, 7, 2, 7]] + -0.000258302532232180387 # B[1332, [33, 6, 0, 6], [46, 7, 3, 8]] + 3.78181072490033077e-05 # B[1333, [33, 6, 0, 6], [47, 7, 4, 7]] + -0.000326273283142861775 # B[1334, [33, 6, 0, 6], [48, 7, 5, 8]] + 1.74277156155672186e-05 # B[1335, [33, 6, 0, 6], [49, 7, 6, 7]] + -0.000206600107910874173 # B[1336, [33, 6, 0, 6], [50, 7, 7, 8]] + 2.12855018918572947e-05 # B[1337, [33, 6, 0, 6], [51, 8, 0, 8]] + -0.000696835386532819456 # B[1338, [33, 6, 0, 6], [52, 8, 2, 8]] + 8.06841007746916805e-05 # B[1339, [33, 6, 0, 6], [53, 8, 4, 8]] + 1.96129469472779844e-05 # B[1340, [33, 6, 0, 6], [54, 8, 6, 8]] + 7.35114191380559223e-05 # B[1341, [33, 6, 0, 6], [55, 8, 8, 8]] + 0.00360109138862139185 # B[1342, [34, 6, 1, 7], [34, 6, 1, 7]] + 0.00304872474261531218 # B[1343, [34, 6, 1, 7], [35, 6, 2, 6]] + -0.00546316824530662139 # B[1344, [34, 6, 1, 7], [36, 6, 2, 8]] + 0.000721988419001898946 # B[1345, [34, 6, 1, 7], [37, 6, 3, 7]] + -0.00254968694435141717 # B[1346, [34, 6, 1, 7], [38, 6, 4, 6]] + -0.00102187793811427596 # B[1347, [34, 6, 1, 7], [39, 6, 4, 8]] + 0.000977866285507509106 # B[1348, [34, 6, 1, 7], [40, 6, 5, 7]] + 0.00129156024637028417 # B[1349, [34, 6, 1, 7], [41, 6, 6, 6]] + 8.43980229575398005e-05 # B[1350, [34, 6, 1, 7], [42, 6, 6, 8]] + -0.000854491821273548058 # B[1351, [34, 6, 1, 7], [43, 7, 0, 7]] + -0.00229655360277009144 # B[1352, [34, 6, 1, 7], [44, 7, 1, 8]] + 0.00392740594657482126 # B[1353, [34, 6, 1, 7], [45, 7, 2, 7]] + 0.00282086313880587115 # B[1354, [34, 6, 1, 7], [46, 7, 3, 8]] + -0.00269367822401865922 # B[1355, [34, 6, 1, 7], [47, 7, 4, 7]] + 0.00120544917432826269 # B[1356, [34, 6, 1, 7], [48, 7, 5, 8]] + 0.00137213082032611872 # B[1357, [34, 6, 1, 7], [49, 7, 6, 7]] + 0.00278774897747785522 # B[1358, [34, 6, 1, 7], [50, 7, 7, 8]] + -1.00075929411755707e-05 # B[1359, [34, 6, 1, 7], [51, 8, 0, 8]] + 0.00331402709384703321 # B[1360, [34, 6, 1, 7], [52, 8, 2, 8]] + -0.00220016465090739841 # B[1361, [34, 6, 1, 7], [53, 8, 4, 8]] + 0.000794479619849004434 # B[1362, [34, 6, 1, 7], [54, 8, 6, 8]] + 0.000207117210070053084 # B[1363, [34, 6, 1, 7], [55, 8, 8, 8]] + 0.000547206364960122621 # B[1364, [35, 6, 2, 6], [35, 6, 2, 6]] + 0.00243529980905243717 # B[1365, [35, 6, 2, 6], [36, 6, 2, 8]] + 0.000346076245330416421 # B[1366, [35, 6, 2, 6], [37, 6, 3, 7]] + 0.00220550296989585788 # B[1367, [35, 6, 2, 6], [38, 6, 4, 6]] + 0.00101934408216735467 # B[1368, [35, 6, 2, 6], [39, 6, 4, 8]] + 6.76995447894471192e-05 # B[1369, [35, 6, 2, 6], [40, 6, 5, 7]] + -4.61734905116591154e-05 # B[1370, [35, 6, 2, 6], [41, 6, 6, 6]] + 0.000809543629624515093 # B[1371, [35, 6, 2, 6], [42, 6, 6, 8]] + 0.000219078295465409238 # B[1372, [35, 6, 2, 6], [43, 7, 0, 7]] + -0.00316872925249137884 # B[1373, [35, 6, 2, 6], [44, 7, 1, 8]] + 0.000676713636760976206 # B[1374, [35, 6, 2, 6], [45, 7, 2, 7]] + -0.00100477918211841141 # B[1375, [35, 6, 2, 6], [46, 7, 3, 8]] + 0.000400524978896980161 # B[1376, [35, 6, 2, 6], [47, 7, 4, 7]] + -0.00197634098305848622 # B[1377, [35, 6, 2, 6], [48, 7, 5, 8]] + 0.000367979983554051621 # B[1378, [35, 6, 2, 6], [49, 7, 6, 7]] + -0.00126672502130457942 # B[1379, [35, 6, 2, 6], [50, 7, 7, 8]] + 0.000161373464169148675 # B[1380, [35, 6, 2, 6], [51, 8, 0, 8]] + 0.00258770627559228462 # B[1381, [35, 6, 2, 6], [52, 8, 2, 8]] + 0.000816135012742828661 # B[1382, [35, 6, 2, 6], [53, 8, 4, 8]] + -3.28991122771973843e-05 # B[1383, [35, 6, 2, 6], [54, 8, 6, 8]] + -4.18127338362338707e-05 # B[1384, [35, 6, 2, 6], [55, 8, 8, 8]] + 0.00658745572292138409 # B[1385, [36, 6, 2, 8], [36, 6, 2, 8]] + -0.00238764687643479301 # B[1386, [36, 6, 2, 8], [37, 6, 3, 7]] + -0.000831950910425274803 # B[1387, [36, 6, 2, 8], [38, 6, 4, 6]] + 0.00351737364404769177 # B[1388, [36, 6, 2, 8], [39, 6, 4, 8]] + -0.00276293358095670936 # B[1389, [36, 6, 2, 8], [40, 6, 5, 7]] + -0.00115031008308692437 # B[1390, [36, 6, 2, 8], [41, 6, 6, 6]] + -0.000921624256609663434 # B[1391, [36, 6, 2, 8], [42, 6, 6, 8]] + 0.000810924380859275734 # B[1392, [36, 6, 2, 8], [43, 7, 0, 7]] + -0.00488922361819911239 # B[1393, [36, 6, 2, 8], [44, 7, 1, 8]] + 0.00170426259508682162 # B[1394, [36, 6, 2, 8], [45, 7, 2, 7]] + -0.000698037236981145087 # B[1395, [36, 6, 2, 8], [46, 7, 3, 8]] + -0.00159293071425275958 # B[1396, [36, 6, 2, 8], [47, 7, 4, 7]] + 0.00145526568566858513 # B[1397, [36, 6, 2, 8], [48, 7, 5, 8]] + -0.0034526631911915729 # B[1398, [36, 6, 2, 8], [49, 7, 6, 7]] + 0.00136118079841816148 # B[1399, [36, 6, 2, 8], [50, 7, 7, 8]] + -0.000519558666561149851 # B[1400, [36, 6, 2, 8], [51, 8, 0, 8]] + -0.00125430728243427136 # B[1401, [36, 6, 2, 8], [52, 8, 2, 8]] + 0.000225746730173992209 # B[1402, [36, 6, 2, 8], [53, 8, 4, 8]] + 0.000144081610870761424 # B[1403, [36, 6, 2, 8], [54, 8, 6, 8]] + 0.000848192939185923693 # B[1404, [36, 6, 2, 8], [55, 8, 8, 8]] + 0.00209760366601450393 # B[1405, [37, 6, 3, 7], [37, 6, 3, 7]] + -0.00114098142783233825 # B[1406, [37, 6, 3, 7], [38, 6, 4, 6]] + -0.00012482798433224862 # B[1407, [37, 6, 3, 7], [39, 6, 4, 8]] + 0.000414303981445450498 # B[1408, [37, 6, 3, 7], [40, 6, 5, 7]] + -2.06949976952613968e-05 # B[1409, [37, 6, 3, 7], [41, 6, 6, 6]] + 0.000986658381613915447 # B[1410, [37, 6, 3, 7], [42, 6, 6, 8]] + 0.000196361012595618056 # B[1411, [37, 6, 3, 7], [43, 7, 0, 7]] + 0.000421620511108736218 # B[1412, [37, 6, 3, 7], [44, 7, 1, 8]] + -0.00121366957406692996 # B[1413, [37, 6, 3, 7], [45, 7, 2, 7]] + 0.000319772245183778947 # B[1414, [37, 6, 3, 7], [46, 7, 3, 8]] + -0.00189440310525268441 # B[1415, [37, 6, 3, 7], [47, 7, 4, 7]] + -0.000420808921505540223 # B[1416, [37, 6, 3, 7], [48, 7, 5, 8]] + -0.000833056882638676111 # B[1417, [37, 6, 3, 7], [49, 7, 6, 7]] + -0.000210394181928773294 # B[1418, [37, 6, 3, 7], [50, 7, 7, 8]] + 4.67415997983874898e-05 # B[1419, [37, 6, 3, 7], [51, 8, 0, 8]] + -0.000629437221263145228 # B[1420, [37, 6, 3, 7], [52, 8, 2, 8]] + -0.000561739301858470846 # B[1421, [37, 6, 3, 7], [53, 8, 4, 8]] + -0.000244403089656959616 # B[1422, [37, 6, 3, 7], [54, 8, 6, 8]] + 0.000170058213410727299 # B[1423, [37, 6, 3, 7], [55, 8, 8, 8]] + 0.000190580820336867102 # B[1424, [38, 6, 4, 6], [38, 6, 4, 6]] + -5.17086422710446442e-05 # B[1425, [38, 6, 4, 6], [39, 6, 4, 8]] + -0.000870479233908965505 # B[1426, [38, 6, 4, 6], [40, 6, 5, 7]] + 8.56431173592298034e-05 # B[1427, [38, 6, 4, 6], [41, 6, 6, 6]] + -0.000219028113680014638 # B[1428, [38, 6, 4, 6], [42, 6, 6, 8]] + 6.99094597341239771e-05 # B[1429, [38, 6, 4, 6], [43, 7, 0, 7]] + -0.00217214753267054063 # B[1430, [38, 6, 4, 6], [44, 7, 1, 8]] + 0.00103452950595812193 # B[1431, [38, 6, 4, 6], [45, 7, 2, 7]] + 0.000131158053198399821 # B[1432, [38, 6, 4, 6], [46, 7, 3, 8]] + -0.000991288929959081421 # B[1433, [38, 6, 4, 6], [47, 7, 4, 7]] + -0.000321058899826150157 # B[1434, [38, 6, 4, 6], [48, 7, 5, 8]] + -0.000126379357764709599 # B[1435, [38, 6, 4, 6], [49, 7, 6, 7]] + 0.000513859397020456632 # B[1436, [38, 6, 4, 6], [50, 7, 7, 8]] + -2.72482190626921472e-05 # B[1437, [38, 6, 4, 6], [51, 8, 0, 8]] + 0.000742781076179950886 # B[1438, [38, 6, 4, 6], [52, 8, 2, 8]] + -9.17701606060090935e-05 # B[1439, [38, 6, 4, 6], [53, 8, 4, 8]] + 1.49768390447675703e-05 # B[1440, [38, 6, 4, 6], [54, 8, 6, 8]] + -5.94521118466549703e-05 # B[1441, [38, 6, 4, 6], [55, 8, 8, 8]] + 0.00161400415689978271 # B[1442, [39, 6, 4, 8], [39, 6, 4, 8]] + -0.000149892220376375129 # B[1443, [39, 6, 4, 8], [40, 6, 5, 7]] + -0.000242832088631229209 # B[1444, [39, 6, 4, 8], [41, 6, 6, 6]] + -4.23223006292567511e-05 # B[1445, [39, 6, 4, 8], [42, 6, 6, 8]] + 0.000145544599928226076 # B[1446, [39, 6, 4, 8], [43, 7, 0, 7]] + -0.000846976149028450323 # B[1447, [39, 6, 4, 8], [44, 7, 1, 8]] + 0.000313402576083809947 # B[1448, [39, 6, 4, 8], [45, 7, 2, 7]] + -0.00105304559168569421 # B[1449, [39, 6, 4, 8], [46, 7, 3, 8]] + -0.000563622717067245593 # B[1450, [39, 6, 4, 8], [47, 7, 4, 7]] + -0.000176248327800098206 # B[1451, [39, 6, 4, 8], [48, 7, 5, 8]] + -0.000523005481859822874 # B[1452, [39, 6, 4, 8], [49, 7, 6, 7]] + 0.000327425878709725754 # B[1453, [39, 6, 4, 8], [50, 7, 7, 8]] + -0.000214075091648432969 # B[1454, [39, 6, 4, 8], [51, 8, 0, 8]] + 0.000892962890338189208 # B[1455, [39, 6, 4, 8], [52, 8, 2, 8]] + 0.000483016760753301674 # B[1456, [39, 6, 4, 8], [53, 8, 4, 8]] + 0.000385986009520520711 # B[1457, [39, 6, 4, 8], [54, 8, 6, 8]] + 0.000210387221014841225 # B[1458, [39, 6, 4, 8], [55, 8, 8, 8]] + 0.000423894835630976054 # B[1459, [40, 6, 5, 7], [40, 6, 5, 7]] + 2.52152593651043533e-05 # B[1460, [40, 6, 5, 7], [41, 6, 6, 6]] + 0.0001406783760301792 # B[1461, [40, 6, 5, 7], [42, 6, 6, 8]] + -0.000402862939603353815 # B[1462, [40, 6, 5, 7], [43, 7, 0, 7]] + -0.000764679971924708997 # B[1463, [40, 6, 5, 7], [44, 7, 1, 8]] + 0.000690122720081854865 # B[1464, [40, 6, 5, 7], [45, 7, 2, 7]] + 0.00135911524951161378 # B[1465, [40, 6, 5, 7], [46, 7, 3, 8]] + 5.52075818169902449e-06 # B[1466, [40, 6, 5, 7], [47, 7, 4, 7]] + -0.000149902773226399076 # B[1467, [40, 6, 5, 7], [48, 7, 5, 8]] + 0.000389894625400750289 # B[1468, [40, 6, 5, 7], [49, 7, 6, 7]] + 0.000257807843360047251 # B[1469, [40, 6, 5, 7], [50, 7, 7, 8]] + -3.67912373811542237e-05 # B[1470, [40, 6, 5, 7], [51, 8, 0, 8]] + -0.000174743024771516643 # B[1471, [40, 6, 5, 7], [52, 8, 2, 8]] + 0.000276798622678277838 # B[1472, [40, 6, 5, 7], [53, 8, 4, 8]] + 0.000152459620483783032 # B[1473, [40, 6, 5, 7], [54, 8, 6, 8]] + -0.000616599602238733502 # B[1474, [40, 6, 5, 7], [55, 8, 8, 8]] + -5.12324624723156652e-05 # B[1475, [41, 6, 6, 6], [41, 6, 6, 6]] + -4.23334509430418893e-05 # B[1476, [41, 6, 6, 6], [42, 6, 6, 8]] + -0.000111212733055157664 # B[1477, [41, 6, 6, 6], [43, 7, 0, 7]] + 0.000882360189618891337 # B[1478, [41, 6, 6, 6], [44, 7, 1, 8]] + -0.000581964842687935843 # B[1479, [41, 6, 6, 6], [45, 7, 2, 7]] + 0.000211138997961872465 # B[1480, [41, 6, 6, 6], [46, 7, 3, 8]] + 7.79906436828414068e-05 # B[1481, [41, 6, 6, 6], [47, 7, 4, 7]] + -0.000201461425275273331 # B[1482, [41, 6, 6, 6], [48, 7, 5, 8]] + 6.87828589884392771e-05 # B[1483, [41, 6, 6, 6], [49, 7, 6, 7]] + 0.000150653067204437052 # B[1484, [41, 6, 6, 6], [50, 7, 7, 8]] + 3.87532549918634395e-05 # B[1485, [41, 6, 6, 6], [51, 8, 0, 8]] + 0.000361299779465781672 # B[1486, [41, 6, 6, 6], [52, 8, 2, 8]] + -0.000217385549744270783 # B[1487, [41, 6, 6, 6], [53, 8, 4, 8]] + 6.09508622621875856e-05 # B[1488, [41, 6, 6, 6], [54, 8, 6, 8]] + -0.000174447165900721429 # B[1489, [41, 6, 6, 6], [55, 8, 8, 8]] + 4.08451735536830007e-05 # B[1490, [42, 6, 6, 8], [42, 6, 6, 8]] + -0.000100109250872669128 # B[1491, [42, 6, 6, 8], [43, 7, 0, 7]] + 0.000543796967600337564 # B[1492, [42, 6, 6, 8], [44, 7, 1, 8]] + 0.000744432946735457124 # B[1493, [42, 6, 6, 8], [45, 7, 2, 7]] + 0.0010803210667922683 # B[1494, [42, 6, 6, 8], [46, 7, 3, 8]] + 0.000151445105968722347 # B[1495, [42, 6, 6, 8], [47, 7, 4, 7]] + -0.000100848877598445907 # B[1496, [42, 6, 6, 8], [48, 7, 5, 8]] + -0.000109088350721993355 # B[1497, [42, 6, 6, 8], [49, 7, 6, 7]] + -0.000287924009882135207 # B[1498, [42, 6, 6, 8], [50, 7, 7, 8]] + 1.48405987461727729e-05 # B[1499, [42, 6, 6, 8], [51, 8, 0, 8]] + 0.00133229142431166023 # B[1500, [42, 6, 6, 8], [52, 8, 2, 8]] + -0.00019157481902659472 # B[1501, [42, 6, 6, 8], [53, 8, 4, 8]] + -0.000214414469154704246 # B[1502, [42, 6, 6, 8], [54, 8, 6, 8]] + -0.000145460173238021184 # B[1503, [42, 6, 6, 8], [55, 8, 8, 8]] + 0.000122164068846408735 # B[1504, [43, 7, 0, 7], [43, 7, 0, 7]] + -0.000271198052548764657 # B[1505, [43, 7, 0, 7], [44, 7, 1, 8]] + -7.53020792218089818e-05 # B[1506, [43, 7, 0, 7], [45, 7, 2, 7]] + -0.000522043739406908344 # B[1507, [43, 7, 0, 7], [46, 7, 3, 8]] + -4.818852612961666e-05 # B[1508, [43, 7, 0, 7], [47, 7, 4, 7]] + -0.000220542438614808323 # B[1509, [43, 7, 0, 7], [48, 7, 5, 8]] + -0.000160998835878327362 # B[1510, [43, 7, 0, 7], [49, 7, 6, 7]] + -2.41628428966911279e-05 # B[1511, [43, 7, 0, 7], [50, 7, 7, 8]] + -1.41474469189661889e-05 # B[1512, [43, 7, 0, 7], [51, 8, 0, 8]] + -0.000160534811881916234 # B[1513, [43, 7, 0, 7], [52, 8, 2, 8]] + -1.73735621299461046e-05 # B[1514, [43, 7, 0, 7], [53, 8, 4, 8]] + 4.73251016045242445e-05 # B[1515, [43, 7, 0, 7], [54, 8, 6, 8]] + 0.000182463508348683356 # B[1516, [43, 7, 0, 7], [55, 8, 8, 8]] + -0.000629134879565343137 # B[1517, [44, 7, 1, 8], [44, 7, 1, 8]] + -0.00207361578267727673 # B[1518, [44, 7, 1, 8], [45, 7, 2, 7]] + 0.0031686999001355326 # B[1519, [44, 7, 1, 8], [46, 7, 3, 8]] + -0.000405403647932546952 # B[1520, [44, 7, 1, 8], [47, 7, 4, 7]] + -0.000111251617971438489 # B[1521, [44, 7, 1, 8], [48, 7, 5, 8]] + 0.0014482690523848242 # B[1522, [44, 7, 1, 8], [49, 7, 6, 7]] + 0.000818892450912583197 # B[1523, [44, 7, 1, 8], [50, 7, 7, 8]] + 0.000100422502558870572 # B[1524, [44, 7, 1, 8], [51, 8, 0, 8]] + -0.000412863674396233161 # B[1525, [44, 7, 1, 8], [52, 8, 2, 8]] + -0.000905494278120194153 # B[1526, [44, 7, 1, 8], [53, 8, 4, 8]] + 0.00126932173443552359 # B[1527, [44, 7, 1, 8], [54, 8, 6, 8]] + -0.000374814469421512735 # B[1528, [44, 7, 1, 8], [55, 8, 8, 8]] + -0.00330341133748704441 # B[1529, [45, 7, 2, 7], [45, 7, 2, 7]] + 0.00131616674488897398 # B[1530, [45, 7, 2, 7], [46, 7, 3, 8]] + -0.000483635326292886428 # B[1531, [45, 7, 2, 7], [47, 7, 4, 7]] + -0.00177550615332965067 # B[1532, [45, 7, 2, 7], [48, 7, 5, 8]] + 0.00226091969304176299 # B[1533, [45, 7, 2, 7], [49, 7, 6, 7]] + -0.00142635978155006456 # B[1534, [45, 7, 2, 7], [50, 7, 7, 8]] + 0.000289476939908078768 # B[1535, [45, 7, 2, 7], [51, 8, 0, 8]] + 0.000582488578419503846 # B[1536, [45, 7, 2, 7], [52, 8, 2, 8]] + -0.000228795123723987606 # B[1537, [45, 7, 2, 7], [53, 8, 4, 8]] + 0.000478658611037000373 # B[1538, [45, 7, 2, 7], [54, 8, 6, 8]] + -0.00101956994563059782 # B[1539, [45, 7, 2, 7], [55, 8, 8, 8]] + 0.00268648192223141895 # B[1540, [46, 7, 3, 8], [46, 7, 3, 8]] + 0.000515570689344949529 # B[1541, [46, 7, 3, 8], [47, 7, 4, 7]] + 0.000903689215066725768 # B[1542, [46, 7, 3, 8], [48, 7, 5, 8]] + 0.00180650309403464215 # B[1543, [46, 7, 3, 8], [49, 7, 6, 7]] + -7.48574841450792838e-05 # B[1544, [46, 7, 3, 8], [50, 7, 7, 8]] + -2.90930360741237237e-05 # B[1545, [46, 7, 3, 8], [51, 8, 0, 8]] + 0.00139057844941538594 # B[1546, [46, 7, 3, 8], [52, 8, 2, 8]] + -0.000263907165716330272 # B[1547, [46, 7, 3, 8], [53, 8, 4, 8]] + -5.74521512815137289e-05 # B[1548, [46, 7, 3, 8], [54, 8, 6, 8]] + -0.00030234445629373323 # B[1549, [46, 7, 3, 8], [55, 8, 8, 8]] + -0.000842080339294604824 # B[1550, [47, 7, 4, 7], [47, 7, 4, 7]] + -1.8677234631915389e-05 # B[1551, [47, 7, 4, 7], [48, 7, 5, 8]] + 0.000150434033167294937 # B[1552, [47, 7, 4, 7], [49, 7, 6, 7]] + 0.000201922161197246736 # B[1553, [47, 7, 4, 7], [50, 7, 7, 8]] + 5.63689077359152968e-05 # B[1554, [47, 7, 4, 7], [51, 8, 0, 8]] + 0.000490229079971716761 # B[1555, [47, 7, 4, 7], [52, 8, 2, 8]] + -0.00019335269881828529 # B[1556, [47, 7, 4, 7], [53, 8, 4, 8]] + -0.000118664083374402096 # B[1557, [47, 7, 4, 7], [54, 8, 6, 8]] + -0.000397263359111398734 # B[1558, [47, 7, 4, 7], [55, 8, 8, 8]] + -0.000724261739409587726 # B[1559, [48, 7, 5, 8], [48, 7, 5, 8]] + 0.000186853474209224685 # B[1560, [48, 7, 5, 8], [49, 7, 6, 7]] + -0.000533321040010020266 # B[1561, [48, 7, 5, 8], [50, 7, 7, 8]] + 9.95102706208284005e-08 # B[1562, [48, 7, 5, 8], [51, 8, 0, 8]] + -0.00093755398196557671 # B[1563, [48, 7, 5, 8], [52, 8, 2, 8]] + 0.000483236780374178207 # B[1564, [48, 7, 5, 8], [53, 8, 4, 8]] + -5.03524206302112531e-05 # B[1565, [48, 7, 5, 8], [54, 8, 6, 8]] + -0.000586245052440398373 # B[1566, [48, 7, 5, 8], [55, 8, 8, 8]] + -0.000207118017941997773 # B[1567, [49, 7, 6, 7], [49, 7, 6, 7]] + -9.40116364012005823e-05 # B[1568, [49, 7, 6, 7], [50, 7, 7, 8]] + 0.000124266884770383307 # B[1569, [49, 7, 6, 7], [51, 8, 0, 8]] + 0.00118479186165786239 # B[1570, [49, 7, 6, 7], [52, 8, 2, 8]] + -0.000129238345120056067 # B[1571, [49, 7, 6, 7], [53, 8, 4, 8]] + -0.000383875224777865259 # B[1572, [49, 7, 6, 7], [54, 8, 6, 8]] + -0.000457194559055141767 # B[1573, [49, 7, 6, 7], [55, 8, 8, 8]] + -0.000450510261664234871 # B[1574, [50, 7, 7, 8], [50, 7, 7, 8]] + 7.52704593073999506e-05 # B[1575, [50, 7, 7, 8], [51, 8, 0, 8]] + -0.00128732840082427732 # B[1576, [50, 7, 7, 8], [52, 8, 2, 8]] + 0.000293225651298797269 # B[1577, [50, 7, 7, 8], [53, 8, 4, 8]] + -0.000306521733645761033 # B[1578, [50, 7, 7, 8], [54, 8, 6, 8]] + -0.000370268243746852549 # B[1579, [50, 7, 7, 8], [55, 8, 8, 8]] + -4.00747887657759705e-06 # B[1580, [51, 8, 0, 8], [51, 8, 0, 8]] + -0.000179079356204300821 # B[1581, [51, 8, 0, 8], [52, 8, 2, 8]] + -6.37205046857824975e-06 # B[1582, [51, 8, 0, 8], [53, 8, 4, 8]] + 5.20087282658288075e-05 # B[1583, [51, 8, 0, 8], [54, 8, 6, 8]] + 6.68015373273544988e-05 # B[1584, [51, 8, 0, 8], [55, 8, 8, 8]] + 0.00160592146390294661 # B[1585, [52, 8, 2, 8], [52, 8, 2, 8]] + 0.000454049229948232103 # B[1586, [52, 8, 2, 8], [53, 8, 4, 8]] + 0.00110675066334388339 # B[1587, [52, 8, 2, 8], [54, 8, 6, 8]] + -0.000191060465051852771 # B[1588, [52, 8, 2, 8], [55, 8, 8, 8]] + -0.000131765455753670314 # B[1589, [53, 8, 4, 8], [53, 8, 4, 8]] + -7.05704764431217685e-05 # B[1590, [53, 8, 4, 8], [54, 8, 6, 8]] + -1.82263105369812051e-05 # B[1591, [53, 8, 4, 8], [55, 8, 8, 8]] + -0.00032731873727259329 # B[1592, [54, 8, 6, 8], [54, 8, 6, 8]] + -0.000198178389384386089 # B[1593, [54, 8, 6, 8], [55, 8, 8, 8]] + -0.000136309758672861769 # B[1594, [55, 8, 8, 8], [55, 8, 8, 8]] + +# End of potential From 5c94806a1d307d5552adeecf634fb9221abb1d71 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Thu, 23 Mar 2023 01:59:38 -0400 Subject: [PATCH 050/448] update doc --- doc/src/fix_pimd.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index db6700633f..eca58a409d 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -95,8 +95,10 @@ beads on the other ring-polymers with the same imaginary time index (the second term in the effective potential above). The quasi-beads also interact with the two neighboring quasi-beads through the spring potential in imaginary-time space (first term in effective potential). -To sample the canonical ensemble, a Nose-Hoover massive chain thermostat -is applied :ref:`(Tuckerman) `. With the massive chain +To sample the canonical ensemble, any thermostat can be applied. + +Fix *pimd/nvt* applies a Nose-Hoover massive chain thermostat +:ref:`(Tuckerman) `. With the massive chain algorithm, a chain of NH thermostats is coupled to each degree of freedom for each quasi-bead. The keyword *temp* sets the target temperature for the system and the keyword *nhc* sets the number *Nc* of @@ -104,16 +106,15 @@ thermostats in each chain. For example, for a simulation of N particles with P beads in each ring-polymer, the total number of NH thermostats would be 3 x N x P x Nc. +Fix *pimd/langevin* implements a Langevin thermostat in the normal mode +representation, and also provides a barostat to sample the NPH/NPT ensembles. + .. note:: - Fix *pimd/nvt* implements a complete velocity-verlet integrator - combined with NH massive chain thermostat, so no other time + Both these *fix* styles implement a complete velocity-verlet integrator + combined with a thermostat, so no other time integration fix should be used. - Fix *pimd/langevin* implements a complete velocity-verlet integrator - combined with Langevin thermostat in the normal mode representation, and - also provides a barostat to sample the NPH/NPT ensembles. - The *method* keyword determines what style of PIMD is performed. A value of *pimd* is standard PIMD. A value of *nmpimd* is for normal-mode PIMD. A value of *cmd* is for centroid molecular dynamics From 83b4e18704843c86de7cf26e91bae18851b6165a Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Thu, 23 Mar 2023 21:05:07 -0400 Subject: [PATCH 051/448] update doc --- doc/src/fix_pimd.rst | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index eca58a409d..78aa5fa107 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -112,8 +112,7 @@ representation, and also provides a barostat to sample the NPH/NPT ensembles. .. note:: Both these *fix* styles implement a complete velocity-verlet integrator - combined with a thermostat, so no other time - integration fix should be used. + combined with a thermostat, so no other time integration fix should be used. The *method* keyword determines what style of PIMD is performed. A value of *pimd* is standard PIMD. A value of *nmpimd* is for @@ -121,7 +120,7 @@ normal-mode PIMD. A value of *cmd* is for centroid molecular dynamics (CMD). The difference between the styles is as follows. In standard PIMD, the value used for a bead's fictitious mass is - arbitrary. A common choice is to use Mi = m/P, which results in the + arbitrary. A common choice is to use :math:`M_i = m/P`, which results in the mass of the entire ring-polymer being equal to the real quantum particle. But it can be difficult to efficiently integrate the equations of motion for the stiff harmonic interactions in the ring @@ -152,6 +151,10 @@ normal-mode PIMD. A value of *cmd* is for centroid molecular dynamics only the k > 0 modes are thermostatted, not the centroid degrees of freedom. +The keyword *integrator* specifies the Trotter splitting method used by *fix pimd/langevin*. +See :ref:`(Liu) ` for a discussion on the OBABO and BAOAB splitting schemes. Typically +either of the two should work fine. + The keyword *fmass* sets a further scaling factor for the fictitious masses of beads, which can be used for the Partial Adiabatic CMD :ref:`(Hone) `, or to be set as P, which results in the fictitious @@ -201,7 +204,7 @@ a positive floating-point number. for nve pimd, since the spring elastic frequency between the beads will be affected by the temperature. The keyword *thermostat* reads *style* and *seed* of thermostat for fix style *pimd/langevin*. *style* can only -be *PILE_L* (path integral Langevin equation local thermostat, as described in :ref:`Ceriotti `), and *seed* should a positive integer number, which serves as the seed of the pseudo random number generator. +be *PILE_L* (path integral Langevin equation local thermostat, as described in :ref:`Ceriotti `), and *seed* should a positive integer number, which serves as the seed of the pseudo random number generator. .. note:: The fix style *pimd/langevin* uses the stochastic PILE_L thermostat to control temperature. This thermostat works on the normal modes @@ -216,7 +219,7 @@ The barostat parameters for fix style *pimd/langevin* with *npt* or *nph* ensemb keywords. A *pressure* value should be given with pressure unit. The keyword *iso* means couple all 3 diagonal components together when pressure is computed (hydrostatic pressure), and dilate/contract the dimensions together. The keyword *aniso* means x, y, and z dimensions are controlled independently using the Pxx, Pyy, and Pzz components of the stress tensor as the driving forces, and the specified scalar external pressure. The keyword *barostat* reads *style* of barostat for fix style *pimd/langevin*. *style* can -be *BZP* (Bussi-Zykova-Parrinello, as described in :ref:`Bussi `) or *MTTK* (Martyna-Tuckerman-Tobias-Klein, as described in :ref:`Martyna1 ` and :ref:`Martyna2 `). +be *BZP* (Bussi-Zykova-Parrinello, as described in :ref:`Bussi `) or *MTTK* (Martyna-Tuckerman-Tobias-Klein, as described in :ref:`Martyna1 ` and :ref:`Martyna2 `). The keyword *taup* specifies the barostat damping time parameter for fix style *pimd/langevin*. It is in time unit. @@ -258,9 +261,18 @@ related tasks for each of the partitions, e.g. .. code-block:: LAMMPS dump dcd all dcd 10 system_${ibead}.dcd + dump 1 all custom 100 ${ibead}.xyz id type x y z vx vy vz ix iy iz fx fy fz restart 1000 system_${ibead}.restart1 system_${ibead}.restart2 read_restart system_${ibead}.restart2 +.. note:: + Fix *pimd/langevin* dumps the Catersian coordinates, but dumps the velocities and + forces in the normal mode representation. If the Catersian velocities and forces are + needed, it is easy to perform the transformation when doing post-processing. + + It is recommended to dump the image flags (*ix iy iz*) for fix *pimd/langevin*. It + will be useful if you want to calculate some estimators during post-processing. + Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" @@ -287,6 +299,10 @@ the global vector are: The vector values calculated by fix *pimd/nvt* are "extensive", except for the temperature, which is "intensive". +Fix *pimd/langevin* computes a global vector of quantities, which +can be accessed by various :doc:`output commands `. If *ensemble* +is *nve* or *nvt*, the vector has 10 values. + No parameter of fix *pimd/nvt* can be used with the *start/stop* keywords of the :doc:`run ` command. Fix *pimd/nvt* is not invoked during :doc:`energy minimization `. @@ -355,14 +371,18 @@ Path Integrals, McGraw-Hill, New York (1965). **(Bussi)** G. Bussi, T. Zykova-Timan, M. Parrinello, J Chem Phys, 130, 074101 (2009). -.. _Ceriotti: +.. _Ceriotti2: **(Ceriotti)** M. Ceriotti, M. Parrinello, T. Markland, D. Manolopoulos, J. Chem. Phys. 133, 124104 (2010). -.. _Martyna1: +.. _Martyna3: **(Martyna1)** G. Martyna, D. Tobias, M. Klein, J. Chem. Phys. 101, 4177 (1994). -.. _Martyna2: +.. _Martyna4: **(Martyna2)** G. Martyna, A. Hughes, M. Tuckerman, J. Chem. Phys. 110, 3275 (1999). + +.. _Liujian: + +**(Liu)** J. Liu, D. Li, X. Liu, J. Chem. Phys. 145, 024103 (2016). From 4e4ae34de601159ffaf8af10eacefeab57781570 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 27 Mar 2023 22:16:41 -0400 Subject: [PATCH 052/448] update doc with output info and reduced unit instructions --- doc/src/fix_pimd.rst | 66 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 62 insertions(+), 4 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 78aa5fa107..e4a59b0078 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -226,6 +226,9 @@ The keyword *taup* specifies the barostat damping time parameter for fix style * The keyword *fixcom* specifies whether the center-of-mass of the extended ring-polymer system is fixed during the pimd simulation. Once *fixcom* is set to be *yes*, the center-of-mass velocity will be distracted from the centroid-mode velocities in each step. +The keyword *lj* should be used if :doc:`lj units ` is used for *fix pimd/langevin*. Typically one may want to use +reduced units to run the simulation, and then convert the results into some physical units (for example, :doc:`metal units `). In this case, the 5 quantities in the physical mass units are needed: epsilon (energy scale), sigma (length scale), mass, Planck's constant, mvv2e (mass * velocity^2 to energy conversion factor). Planck's constant and mvv2e can be found in src/update.cpp. If there is no need to convert reduced units to physical units, set all these five value to 1. + The PIMD algorithm in LAMMPS is implemented as a hyper-parallel scheme as described in :ref:`Calhoun `. In LAMMPS this is done by using :doc:`multi-replica feature ` in LAMMPS, where each @@ -300,11 +303,65 @@ The vector values calculated by fix *pimd/nvt* are "extensive", except for the temperature, which is "intensive". Fix *pimd/langevin* computes a global vector of quantities, which -can be accessed by various :doc:`output commands `. If *ensemble* -is *nve* or *nvt*, the vector has 10 values. +can be accessed by various :doc:`output commands `. Note that +it outputs multiple log files, and different log files contain information +about different beads or modes (see detailed explanations below). If *ensemble* +is *nve* or *nvt*, the vector has 10 values: -No parameter of fix *pimd/nvt* can be used with the *start/stop* keywords -of the :doc:`run ` command. Fix *pimd/nvt* is not invoked during + #. kinetic energy of the normal mode + #. spring elastic energy of the normal mode + #. potential energy of the bead + #. total energy of all beads (conserved if *ensemble* is *nve*) + #. primitive kinetic energy estimator + #. virial energy estimator + #. centroid-virial energy estimator + #. primitive pressure estimator + #. thermodynamic pressure estimator + #. centroid-virial pressure estimator + +The first 3 are different for different log files, and the others are the same for different log files. + +If *ensemble* is *nph* or *npt*, the vector stores internal variables of the barostat. If *iso* is used, +the vector has 15 values: + + #. kinetic energy of the normal mode + #. spring elastic energy of the normal mode + #. potential energy of the bead + #. total energy of all beads (conserved if *ensemble* is *nve*) + #. primitive kinetic energy estimator + #. virial energy estimator + #. centroid-virial energy estimator + #. primitive pressure estimator + #. thermodynamic pressure estimator + #. centroid-virial pressure estimator + #. barostat velocity + #. barostat kinetic energy + #. barostat potential energy + #. barostat cell Jacobian + #. enthalpy of the extended system (sum of 4, 12, 13, and 14; conserved if *ensemble* is *nph*) + +If *aniso* or *x* or *y* or *z* is used for the barostat, the vector has 17 values: + + #. kinetic energy of the normal mode + #. spring elastic energy of the normal mode + #. potential energy of the bead + #. total energy of all beads (conserved if *ensemble* is *nve*) + #. primitive kinetic energy estimator + #. virial energy estimator + #. centroid-virial energy estimator + #. primitive pressure estimator + #. thermodynamic pressure estimator + #. centroid-virial pressure estimator + #. x component of barostat velocity + #. y component of barostat velocity + #. z component of barostat velocity + #. barostat kinetic energy + #. barostat potential energy + #. barostat cell Jacobian + #. enthalpy of the extended system (sum of 4, 14, 15, and 16; conserved if *ensemble* is *nph*) + +No parameter of fix *pimd/nvt* or *pimd/langevin* can be used with the *start/stop* keywords +of the :doc:`run ` command. Fix *pimd/nvt* or *pimd/langevin* is not invoked during :doc:`energy minimization `. Restrictions @@ -315,6 +372,7 @@ LAMMPS was built with that package. See the :doc:`Build package ` page for more info. Fix *pimd/nvt* cannot be used with :doc:`lj units `. +Fix *pimd/langevin* can be used with :doc:`lj units `. See the above part for how to use it. A PIMD simulation can be initialized with a single data file read via the :doc:`read_data ` command. However, this means all From 561f80ccc731715049fcaa9c9663944089c4353a Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 27 Mar 2023 22:21:38 -0400 Subject: [PATCH 053/448] add example for fix pimd/langevin with reduced units --- .../PACKAGES/pimd/lj_reduced_units/data.lj01 | 219 ++++++++++++++++++ .../PACKAGES/pimd/lj_reduced_units/data.lj02 | 219 ++++++++++++++++++ .../PACKAGES/pimd/lj_reduced_units/in.lmp | 26 +++ .../PACKAGES/pimd/lj_reduced_units/run.sh | 1 + 4 files changed, 465 insertions(+) create mode 100644 examples/PACKAGES/pimd/lj_reduced_units/data.lj01 create mode 100644 examples/PACKAGES/pimd/lj_reduced_units/data.lj02 create mode 100644 examples/PACKAGES/pimd/lj_reduced_units/in.lmp create mode 100644 examples/PACKAGES/pimd/lj_reduced_units/run.sh diff --git a/examples/PACKAGES/pimd/lj_reduced_units/data.lj01 b/examples/PACKAGES/pimd/lj_reduced_units/data.lj01 new file mode 100644 index 0000000000..e3d6b816a3 --- /dev/null +++ b/examples/PACKAGES/pimd/lj_reduced_units/data.lj01 @@ -0,0 +1,219 @@ +LAMMPS data file via write_data, version 8 Feb 2023, timestep = 2000 + +200 atoms +1 atom types + +-3.4945130603740377 3.4945130603740377 xlo xhi +-3.4945130603740377 3.4945130603740377 ylo yhi +-3.4945130603740377 3.4945130603740377 zlo zhi + +Masses + +1 1 + +Pair Coeffs # lj/cut + +1 1 1 + +Atoms # atomic + +108 1 -2.7795690566068996 -2.0367677788080942 3.4238258338844894 2 1 -1 +102 1 -2.609481280743025 -1.8912619121268304 -2.399753092988466 1 -1 -1 +141 1 -3.140749645549514 -2.8903241627869427 -2.7071762462261537 2 0 0 +49 1 -2.3658136681990007 -3.088812044820056 3.4760124445890623 0 1 -1 +88 1 -1.6158710173914035 -2.3369020600614756 3.233517474511907 0 1 -1 +192 1 -1.2960228223928079 -3.237522585981233 -3.1506262911155765 1 1 2 +113 1 -0.5058112539671865 -2.175265580488635 -2.895948573481031 -1 0 0 +147 1 -0.22721902013037146 -3.2095321965856187 -2.5444416457809185 0 1 0 +55 1 0.6250447384071113 -2.6446349401275255 -2.959767417439857 -1 0 -1 +63 1 1.6783992808137906 -3.22203513406057 -3.1652676844989256 -1 1 1 +95 1 1.3579478870419064 -2.684729254303277 -2.052496056604152 0 2 -1 +105 1 1.4496281787006915 -1.9673030959679096 -3.332658945278261 0 0 0 +84 1 2.4045875426768606 -1.8297724699275564 -2.7874627893944544 0 0 0 +65 1 -2.68682939849047 -0.8114540186440395 -3.126687818057689 0 -1 0 +112 1 -1.7203801180145006 -0.8038481618523634 -2.0163240721427838 0 0 0 +174 1 -1.4968933339977661 -1.3290620346554367 -3.064010040861048 -1 0 -1 +189 1 -0.6249709402997541 -1.252931712435372 -1.9882716349469658 0 0 2 +9 1 -0.23886293275872486 -1.0612344376875333 -3.025432389188406 0 0 1 +146 1 -0.9802936024515303 -0.3953988402073487 -2.8364522494017708 2 1 2 +171 1 0.39730078560778914 -1.7846492070113664 -2.443607407553737 0 2 -1 +140 1 0.5573788374911133 -0.5990036144148324 -2.402963062521378 -1 0 0 +152 1 3.4379847727225346 -1.3055938268830742 -2.4905074589410936 -2 -1 0 +11 1 3.1992117767992068 -1.191883736793153 -3.4723419170834338 -1 2 1 +69 1 2.6376153053668867 -0.2845436411244765 -2.788279844473203 0 -2 0 +173 1 -1.967038944001471 0.06098718735032446 -2.58940519609616 1 0 1 +190 1 -2.8711350478349926 0.9129034739862979 -3.477848194666021 0 0 0 +164 1 -2.8409776961511124 1.1599509265598786 -2.2464830240939375 0 0 1 +161 1 -1.6469671018177567 0.9360204597700993 -3.3491365145788827 1 0 2 +74 1 -0.028453987680887038 0.3739399392930446 -2.9891764409930484 1 -1 1 +162 1 -0.9152119867762214 1.8538003710645874 -2.0787458665529313 0 0 1 +165 1 0.20472499231506947 0.41157279287578097 -1.7804952487691292 0 0 0 +28 1 0.9556568956317052 0.9070586383550882 -3.051580171737043 0 -1 -1 +107 1 0.27101548210140264 1.6697625775553313 3.256398876364515 -1 1 0 +53 1 -2.2768986954542476 1.9520208666344268 -2.905899876141582 -1 -1 1 +60 1 -2.3748565234893153 3.1415519659534046 -2.6903226937570888 1 1 0 +172 1 -1.3831407623603917 2.6439383680022495 -2.988114399273657 0 0 2 +35 1 -1.9040946957475922 2.4850230251463294 -1.8238074088896814 1 -1 0 +90 1 -0.6407155002729499 2.891205873820353 -2.184576201275668 0 -1 1 +183 1 -0.7452468270399182 1.6958511415691964 -3.2646018242495516 1 0 0 +46 1 -0.22701759376730096 2.672935498985858 -3.2296828094464414 1 -1 -1 +26 1 0.3607641531328818 1.9915770180932266 -2.4322620664253045 0 -1 1 +41 1 0.6373758855225722 3.1576967379383136 -2.2076729513672273 0 0 1 +62 1 1.2599715479139464 2.4637352645229535 -2.996655642771261 0 0 1 +114 1 0.7095094175128512 3.3529225376529834 -3.446569928809617 0 -1 1 +29 1 -3.4441516076858747 3.186682881361427 -3.164290558791177 1 -1 0 +120 1 -2.7699397214807666 -3.0679149510930377 -1.4586405778286127 2 1 1 +166 1 -2.9639598123456348 -1.8230569851379879 -1.1336421298957986 0 1 0 +19 1 -2.219481001384856 -2.718720936926987 -0.17152653954078959 1 1 -1 +143 1 -3.3367462911096637 -2.646710289319255 -0.08639804580378332 1 1 0 +14 1 -0.8080539703460301 -3.3138674801902015 -1.5513416052298858 -1 0 1 +17 1 -1.2519028473371163 -1.9834151764617522 -0.4751925051419198 -2 0 0 +7 1 -0.6422036076119758 -2.1822637849150257 -1.309964136714573 -1 0 1 +76 1 0.002896678458885543 -2.2620445897063184 -0.2330303144789453 0 0 0 +25 1 0.3195487317939559 -2.5915964162672633 -1.6847661018972104 -1 0 1 +122 1 0.9437732996524034 -3.076308154774796 -1.0301951566376644 1 0 -1 +188 1 1.3149323047475332 -2.0202232851439175 -0.9332517483120624 -1 0 0 +196 1 2.4252816482051065 -2.9991133261256717 -0.2915609413585816 0 2 1 +154 1 1.617010887740887 -2.199305270305938 0.15712874770371849 -1 2 0 +64 1 2.934967635633404 -1.92620475221537 -0.7077313528493354 0 1 0 +79 1 -2.8111804533557017 -0.5176533778232942 -2.0486672107634094 0 1 0 +80 1 -2.079807139196039 -1.2506968999173758 -0.6878784167189951 0 0 1 +12 1 -2.996784469690298 -1.494057160171672 -0.09378065633433766 0 0 1 +87 1 -1.4786937501974577 -0.24572242955022147 -1.0411298155891553 0 -1 1 +118 1 -1.5219571471797697 -0.6469152337096267 0.07790607124041445 0 1 0 +106 1 1.1039107347748043 -0.9982945968846851 -1.4358613477546331 -1 0 0 +6 1 0.2994229743009 -1.5755502164022743 -1.1025451212735877 2 0 0 +98 1 0.14422647245316755 -0.4562748967814887 -1.1288823927075846 -1 0 0 +36 1 1.117403260546369 -0.6258611972204157 -0.45746732579129296 1 -1 0 +133 1 0.859517194013173 -1.4579095853876511 0.2223121798831755 1 1 1 +1 1 1.9750704226304612 -1.2226584851722493 -0.5050391499153623 0 -1 0 +91 1 2.930212504963826 -0.8900603772487206 0.31326990070574257 0 -1 -1 +135 1 -1.8704119131145511 1.4151617424236407 -2.0299493395071555 1 0 0 +145 1 -2.5978280185456044 0.23771261564216897 -0.6973478660383656 0 -2 -1 +194 1 -0.802106175542123 1.5380363524561962 -1.0014646333327863 0 1 -1 +177 1 -0.4209642163497379 1.4081511815239465 0.048786606404428355 0 1 -1 +56 1 0.1655081354187105 0.488612868229853 -0.6685586469118172 0 0 1 +137 1 1.0403444543974962 0.29392106264506496 -1.157047853549803 -1 1 -1 +3 1 1.426791637331859 1.1994824011018168 -0.7391487398561316 0 -1 1 +125 1 0.6384933993980926 1.4087406696008793 -0.04513978672724809 0 1 0 +85 1 3.492386221258323 -0.022918569575539983 -0.18415289757087 1 0 1 +37 1 1.9446560065460998 0.32690249887078415 -1.557848909197346 1 0 1 +157 1 2.2693311785439514 1.4234672203444076 -1.3950756204319474 -1 -1 1 +81 1 2.2043144165939133 0.7734976358785483 -0.1443989261496442 -1 0 1 +193 1 -2.800913203549158 3.3913795040038752 -0.3002902442199323 1 0 0 +127 1 -1.832485514575906 -3.475177695698571 -1.0143919033965547 0 0 0 +104 1 -0.9864189902172598 -3.128510029811542 -0.3946109581791233 0 0 -1 +72 1 -1.091863924309645 2.651695772194485 -1.1525574140711645 1 -1 0 +99 1 -1.376188772302252 2.1367308970905112 -0.22414000562735564 0 -1 0 +24 1 1.0798151658945965 1.8088284522753606 -1.611839691529319 1 -1 0 +42 1 3.3099578488331143 2.7636832208891664 -0.11775790598994411 -1 1 -1 +38 1 -2.6469918571054945 -2.446265188540552 0.8006326688775777 1 0 1 +86 1 -3.3982593364606077 -1.9911707046121028 1.4129412590921573 -1 0 0 +116 1 -3.3782151164102614 3.3939134790192074 0.6418244028431277 1 0 0 +144 1 -2.152212571536467 -2.8119708535854224 1.6778364082976118 0 1 0 +179 1 -0.8263021362457004 -1.7214596406733806 0.6812305480127513 -1 3 1 +151 1 -1.5217298498042864 -2.5933593936403763 0.7963122225368328 0 1 2 +130 1 -0.41366866285633624 -2.851509016203123 0.6773665297002652 -1 1 0 +149 1 -0.8196954968551895 -2.4620140380344058 1.6681749543249536 1 1 0 +123 1 0.42149982032625755 -2.3318080821151144 1.1400194349387576 -1 1 -1 +142 1 1.7676090653529768 -2.7694388971884765 1.0411093428968425 1 1 0 +43 1 1.2651581412723922 -1.7350310325188918 1.2119129817343088 -1 -1 1 +156 1 2.796603060966876 -1.975811297437484 0.5269881248554414 0 -1 0 +30 1 -2.572197786362113 -0.5211520888332514 0.06478473226429171 1 -1 0 +200 1 -2.796037525463158 -1.2242406753887405 0.9147806710233006 -1 0 0 +75 1 -3.264195451754593 -0.2758623474229462 0.8501703715118789 1 -1 0 +199 1 -1.8606891200301348 -0.81109530705794 1.234068196576104 1 -1 1 +119 1 -1.8952925629684365 -1.6742391291961565 0.3056526633582653 0 -1 0 +153 1 -0.6179778569135823 -0.6812551828045249 0.8822634033092613 1 1 0 +31 1 0.1434804396367878 -0.5352374975985325 0.00065681711961239 0 -1 0 +8 1 0.9896949675708329 -0.5825805499366115 0.8390036708294969 0 0 0 +198 1 0.20957042666083733 -1.2300305579788615 1.1505092305231928 0 0 1 +22 1 0.11282413745771128 -0.029722367543426716 1.1299864513218787 -1 0 -1 +195 1 2.9662277270739343 -0.9097471611972223 1.378968815531931 1 0 2 +32 1 1.9176581701385829 -1.0963885598161285 0.612637989357651 1 0 -1 +139 1 2.2034635745403706 -0.09403988556633318 0.8645554281632429 -1 2 0 +77 1 1.7035877859699526 -0.8133688575022073 1.6318409740615665 0 -1 1 +111 1 -3.223221512681343 0.8515794477136406 0.5304444380887284 1 1 1 +138 1 -2.102339643808083 0.3205080511040257 0.6397061187151873 0 1 -1 +103 1 -2.8441279458234914 0.5800051690180812 1.512417106043963 -1 1 0 +184 1 -2.4512811422970944 1.4407376078485292 1.024840909070544 0 0 1 +73 1 -1.2083083753201984 0.16913042396249212 1.31830897028215 0 -2 0 +89 1 -0.622943103836138 0.15695545887374523 0.03344907944561345 0 0 -1 +93 1 -0.6871612783719626 1.4782545941619265 1.7130745398216136 0 -1 0 +94 1 -1.209899480419889 1.1419050120740204 0.768566708093127 0 0 0 +181 1 0.8338139283938067 0.2955625473112081 0.1708175991674893 -1 1 -1 +129 1 1.1355758059362249 0.3630461551808931 1.290797674214222 -1 0 0 +182 1 0.08831527814343061 0.9709201913937692 0.9217855950625892 0 1 -1 +158 1 1.4062820374169525 1.1517166598840343 0.6269036353613398 0 0 0 +100 1 2.8360458941172935 1.5280995172170748 0.62642849190607 0 1 0 +59 1 3.120666407088228 0.49773318717092796 1.2390797462592613 0 -1 1 +40 1 2.1784673001300465 0.9493086808156442 1.37690657576216 0 0 0 +110 1 3.092811420136352 1.457598231264991 1.8333488137634408 0 0 -2 +71 1 -2.704068160468349 3.198799130983575 1.5420861670955985 0 -1 -1 +187 1 -3.3809787804159894 2.339193447924602 0.9253127201661663 1 1 0 +58 1 -1.8161128905276918 3.295453805825648 0.4419286058239596 0 -1 0 +39 1 -1.9288855291902436 2.399541640622866 1.1856795461879515 0 -2 0 +115 1 -1.3188418056778684 -3.426962627878111 1.3071043811339145 1 1 0 +109 1 0.7422148102651713 1.9772692916114134 0.8946623229549697 -1 1 0 +48 1 1.212990075236676 2.7637861839630933 1.668138216427735 0 0 -1 +44 1 1.8875283020177747 2.01954806585405 0.15097670327664356 -1 -1 1 +16 1 2.5088486436667465 3.2867062332187165 0.5352876678637931 0 -2 1 +150 1 2.339993315563226 2.225227215494749 1.201791196292386 0 -1 1 +101 1 -2.7232595674410254 -2.5310321070553594 2.520173028347837 1 3 1 +121 1 -0.1371595891679715 -2.734037361783574 3.2547541081110136 -1 1 -1 +131 1 -1.616105025949218 -1.97873290984862 2.2250110182725185 1 0 0 +50 1 -0.9774458776093428 -3.080336575399165 2.647294574069851 0 1 0 +78 1 -0.6388640381972747 -1.8358994538797384 3.0793625374288474 1 -1 1 +126 1 0.2617829860592282 -3.185635897887874 2.046978007125428 0 1 -1 +185 1 0.3910180046792306 -1.7476201774885758 3.460179487049301 -2 1 -1 +27 1 0.9216706073777299 -2.620009754961919 2.980059759810019 0 0 1 +5 1 0.14805884420723833 -2.060999311749248 2.194803632818035 0 -1 -1 +10 1 1.3885697256222325 -2.5811721069430047 1.960299612344295 0 0 1 +68 1 1.2305537223759786 3.452417391198064 2.5060768204562396 0 0 1 +92 1 3.2579931163558924 -3.0623298587917547 1.8252693484803535 0 2 -1 +178 1 2.26419751848874 -1.7585846281228215 1.7123805014943867 1 1 0 +96 1 2.599921016729558 -2.6427367710738228 3.4145177684858803 -2 2 -1 +57 1 3.2402592062064213 -1.9899576048001384 2.7907002699370937 1 0 0 +155 1 2.209613988042176 -1.7162524781709796 2.7271827572979834 0 0 -1 +168 1 3.477326382335708 -3.4068959852573992 2.821891114170504 -1 1 -2 +175 1 -3.1260125076640937 -0.1261845495956751 3.231607373653429 0 0 0 +117 1 -2.5082381499858095 -1.6201356456498082 1.916360867966056 0 0 0 +4 1 -3.1142920073981517 -0.7023062901592412 1.8555906719306698 0 0 -1 +51 1 -1.9626772134484154 -1.4010881760394245 3.033958867461655 0 0 -1 +148 1 -3.011516485433896 -1.1469037793442038 2.7610753028279933 0 0 0 +197 1 -2.0048159662329326 -0.6749211621392989 2.344679442661877 0 -1 -1 +70 1 -1.8654941392471802 -0.3319695813423535 3.329224742630753 0 1 1 +23 1 -1.0720302561208543 -0.8796307974060223 2.9652586368172633 0 0 -2 +134 1 -0.9769774773292339 -1.023866537972646 1.8133872200496586 -1 0 0 +66 1 0.0812156007450339 -1.0967406204476347 2.677696992399577 -1 -1 -1 +33 1 -0.42833987516917704 0.2127920276630183 3.0504271041557827 0 -1 -1 +18 1 0.8738459806171345 -0.7301638515378504 3.451151027750579 0 -1 -2 +167 1 1.1687036142366616 -1.4517802174625138 2.5014340704062015 0 1 -1 +136 1 1.795137560517328 -0.5623222017058748 2.761148573575212 0 -1 -2 +176 1 0.8667263057428289 -0.39855552371320657 2.157386135628261 0 0 0 +132 1 2.7791570748849397 -0.1854473725861777 3.06331164881256 0 0 -1 +163 1 2.861161516036147 -0.9653887253660198 2.3742914745631665 -1 -1 0 +159 1 -1.638440405488927 1.040992844593558 1.6945368306541542 0 0 0 +34 1 -2.319980614869211 0.615010700172925 2.607891496520952 1 0 -1 +67 1 -1.8758084270870021 1.7856292006021222 2.9794597615239873 1 0 0 +82 1 3.450078342208421 0.43347862445962865 2.3965330453749276 -1 -1 -1 +20 1 -0.3345634991984191 0.4474749361055883 2.021125197093307 1 0 -1 +160 1 -1.337826167757788 0.19507650189296638 2.4559469377176044 0 0 0 +191 1 -0.9433598322448645 1.0765639185970945 2.7978676989244713 1 -1 0 +97 1 1.4995074975439164 1.4827775589636611 2.8582397165142885 0 -1 -1 +83 1 0.7440931705195399 0.28485269404070884 2.8824261695219513 0 -2 0 +186 1 0.4501325900005473 1.1817617584793225 2.171005382838285 1 1 0 +21 1 1.5799209373811796 0.5165927484280916 2.197344395644513 1 0 -1 +170 1 1.781383760665039 0.4589516263468447 3.2606047972968697 -1 1 -1 +15 1 2.5264882009659457 -0.10271458568953422 1.9429509270634897 -1 0 -1 +54 1 2.4907565610148112 1.0443458588262453 2.659572052524602 0 -1 -1 +45 1 -2.3851170089162586 2.7278135027281576 3.2923683043438063 1 0 -1 +47 1 -2.417816843075144 1.911767591397239 2.070179319067279 0 1 0 +52 1 -3.4931268842957652 2.50155605132379 2.127865658713496 0 -1 0 +180 1 -1.9509177290095516 3.309670529089689 2.349688492929276 1 -1 1 +13 1 -0.12240867021598209 3.2141258686958913 2.833411182871058 -1 -1 1 +2 1 -1.340442106022601 2.2849149851767008 2.069093746173476 1 -2 -1 +124 1 -0.41265942682553436 2.1334074442091007 2.592421577863454 1 -1 -1 +61 1 0.7799049336891462 2.500510040165389 2.633457440959517 -1 -2 0 +128 1 2.8514020342376654 2.399755896897204 3.251183881976271 0 0 -2 +169 1 2.1185477137097575 2.27540363851787 2.3296903855745934 0 0 0 diff --git a/examples/PACKAGES/pimd/lj_reduced_units/data.lj02 b/examples/PACKAGES/pimd/lj_reduced_units/data.lj02 new file mode 100644 index 0000000000..aab14fd30f --- /dev/null +++ b/examples/PACKAGES/pimd/lj_reduced_units/data.lj02 @@ -0,0 +1,219 @@ +LAMMPS data file via write_data, version 8 Feb 2023, timestep = 8000 + +200 atoms +1 atom types + +-3.4945130603740377 3.4945130603740377 xlo xhi +-3.4945130603740377 3.4945130603740377 ylo yhi +-3.4945130603740377 3.4945130603740377 zlo zhi + +Masses + +1 1 + +Pair Coeffs # lj/cut + +1 1 1 + +Atoms # atomic + +141 1 -1.763209980389579 -2.6156484242195064 -2.931843780833984 2 0 0 +152 1 -1.5928871542954757 3.3501884422702433 -1.8656866405706811 -1 -2 0 +49 1 -2.7539752553137182 -3.2181862303090325 -3.2982185001231508 0 1 0 +113 1 -0.7003027892165357 -2.1799819378730754 -2.999588953057854 -1 0 0 +147 1 -0.9066147762335637 -3.0721536393085946 -3.451497569202878 0 1 0 +25 1 -0.8348129272923334 -3.2010555139777104 -2.4342714727995403 -1 0 1 +7 1 -1.155032969500839 -2.109409697780318 -2.01960214884411 -1 0 1 +122 1 -0.11210230788570166 -2.6275713274626975 -1.900506384406081 1 0 -1 +55 1 0.23346664931542635 -2.573966195106371 -3.0437128589517024 -1 0 -1 +95 1 0.716981854784511 -1.7560064219465084 -1.6999612600924723 0 2 -1 +105 1 1.1248014998718883 -1.7403082354703703 -3.356758018801178 0 0 0 +84 1 2.225043764737794 -2.1031554472806464 -3.42558560520243 0 0 0 +65 1 -2.8977942390562763 -2.1977837904725823 -3.370623324950664 0 -1 0 +175 1 -3.151432241251456 -0.37515180280237564 3.4437485581764316 0 0 0 +173 1 -2.3157350741156972 -0.12943144237356516 -2.753320161369244 1 0 1 +174 1 -1.4393153013859372 -1.4595317956467175 -2.895392195630071 -1 0 -1 +189 1 -0.9035292808774392 -0.8049470303120404 -2.0013910310988474 0 0 2 +171 1 -0.09043747063992294 -1.5712222691835853 -2.3464524824680155 0 2 -1 +9 1 -0.38933479997274456 -0.745737254721562 -3.0928316849953847 0 0 1 +37 1 0.8181444837942082 -0.7091668788083872 -2.594933610756206 1 0 1 +170 1 1.3754078695474516 -0.09950193181623739 -3.3522400330808644 -1 1 0 +69 1 1.8294621328196188 -1.0504767914076205 -2.8686605757666803 0 -2 0 +11 1 3.053917621871791 -1.2494689141836135 -3.2389748560412586 -1 2 1 +132 1 2.7977059570311695 -0.2496088420677755 -3.341775035063612 0 0 0 +190 1 3.4919178496580034 0.673724849434539 3.4160908466980175 -1 0 -1 +146 1 -0.6231884714133011 0.14913282842463038 -2.641949381637644 2 1 2 +135 1 -1.5674517925968012 0.6290709302591437 -2.3856462153486317 1 0 0 +183 1 -0.49431360672463004 1.4890871743231773 -2.7350680810605428 1 0 0 +74 1 0.37022638217671316 0.08409992531451556 -3.033741105582725 1 -1 1 +26 1 0.4574609043057575 1.0299917975368564 -2.3172978982485737 0 -1 1 +28 1 1.1181699312197082 1.1244486490934802 -3.1866832135712855 0 -1 -1 +29 1 -2.5977690868714194 2.5288932865762908 -3.4450145823917615 1 -1 0 +60 1 -1.7983398047844672 3.3151201773371946 -2.9557747417019304 1 1 0 +35 1 -2.341675516391612 2.5752707942079995 -2.1932303039293837 1 -1 0 +172 1 -1.5906394201515217 2.0015866768978423 -2.97713376733703 0 0 2 +90 1 -0.9570316941978154 2.7341944347748575 -2.39704430602322 0 -1 1 +41 1 0.17097469683906785 3.422589740764926 -2.7250117611585174 0 0 1 +102 1 -2.1834144246935057 -1.9708341062049972 -1.651792998752301 1 -1 -1 +19 1 -2.799899482947646 -2.4762586983196475 -0.30170497621753223 1 1 -1 +193 1 -1.8524344777477728 -2.9040612754975954 -0.9352876177978476 1 1 0 +76 1 -0.14754768813509733 -2.534237145454477 -0.5903298333231304 0 0 0 +104 1 -1.4292162927828058 -1.8887180032986757 -0.7510048521253992 0 0 -1 +14 1 -0.7531800111600084 -3.202737076324235 -1.3992046647831564 -1 0 1 +188 1 1.0895178734825146 -2.3416281855941414 0.09937021752979631 -1 0 0 +157 1 1.53648073670157 -2.278353849103656 -0.9969007844888839 -1 -1 1 +64 1 3.2685116460755688 -1.7040641958682559 -0.168149877537844 0 1 0 +196 1 3.243226770875574 -2.735431073745969 -0.24543333692900807 0 2 1 +120 1 -2.7480834527815015 -1.2726347498238166 -0.7010605053509458 2 1 1 +166 1 -2.5409778907446827 -0.09698240322803402 -1.3435121782531134 0 1 0 +30 1 -2.536346720442665 -0.46539641115594493 0.008770351469747525 1 -1 0 +80 1 -1.716490207148261 -0.7528793181105096 -0.6170398381312646 0 0 1 +17 1 -0.8652064576231921 -1.1974714632304932 -0.15888843807113082 -2 0 0 +98 1 -0.5496242692202938 -0.5939149881300675 -0.9303624863402448 -1 0 0 +6 1 -0.45332547354146785 -1.6738816451677578 -1.1232699958219994 2 0 0 +140 1 0.09381666738090248 -0.533597973200848 -1.8865070415277823 -1 0 0 +106 1 0.5488648307350995 -1.2535162508826685 -0.8256886196074045 -1 0 0 +36 1 0.7889198394938511 -0.3476398702185327 -0.04547023889787161 1 -1 0 +24 1 1.3300945978662577 -0.35153772413771023 -0.9700284287655409 1 -1 0 +81 1 2.0630098337462903 -0.9138666208698583 -0.13962068859670462 -1 0 1 +91 1 -3.4535066291698033 -0.4796384079540839 -0.5221884185889151 1 -1 -1 +164 1 -1.8003776637651108 1.3095354466285742 -0.9389018844249196 0 0 1 +87 1 -1.8547858498275616 0.3065099544053662 -0.4980768850921695 0 -1 1 +145 1 -3.090772587596814 0.5837989607708169 -0.6251810283740868 0 -2 -1 +111 1 -2.534664983415859 1.34688446772606 0.11460128889340086 1 1 1 +79 1 -1.380899470765548 0.24370827853097413 -1.4854169578503262 0 1 0 +162 1 -1.1815902722068103 1.6597770188121743 -1.9852434376303232 0 0 1 +112 1 -0.32558743037491716 0.7106169572157139 -1.615285962267308 0 0 0 +56 1 -0.8283072702254036 0.4564624534306639 -0.5700689028075459 0 0 1 +182 1 0.04863074266364189 0.7978824700683131 -0.008284573593351257 0 1 -1 +177 1 -0.6481696376748467 1.7650890642565358 -0.05338043165294714 0 1 -1 +137 1 0.32639925685778487 -0.05353328668133155 -0.9586895874383917 -1 1 -1 +165 1 0.9387159980444888 0.2522291776639033 -1.8478441123660552 0 0 0 +3 1 1.0844300875316264 0.6025889724525081 -0.4582563908829376 0 -1 1 +194 1 0.8662415299163716 1.2219273986337442 -1.3857941220556813 0 1 -1 +158 1 2.0486184184859972 0.9634063040985638 -0.3354215045861158 0 0 0 +42 1 -1.5693584560601268 2.9075068816274467 -0.8387140667909673 0 1 -1 +99 1 -1.6113116181616747 2.147179220461499 0.1775215873578245 0 -1 0 +72 1 -0.6293873725016741 2.630010118252137 -0.9564776518035689 1 -1 0 +38 1 -2.8640470065198236 -2.2435586739017785 1.3910743129711478 1 0 1 +143 1 -3.0743396057883414 -3.212849746838124 0.5259359570888149 1 1 0 +58 1 -1.9981958681612715 -3.1822656548185346 0.09920225142503952 0 0 0 +144 1 -2.279979967578157 -3.0851896187054515 1.4084093697981352 0 1 0 +151 1 -2.0216078245666655 -2.2216580360079643 0.7457122321748793 0 1 2 +130 1 -0.17493166269242383 -2.4315359476317373 0.444080856211588 -1 1 0 +149 1 -1.3750250274960272 -1.974930490228725 1.5829454078902832 1 1 0 +115 1 -1.2118995350185076 -2.9035919135907267 0.8179968023020373 1 1 0 +126 1 -0.25733050703242866 -2.3407760209116555 1.6674720764378244 0 1 -1 +123 1 0.5187414713973443 -1.8755931680751559 1.2290889493691715 -1 1 -1 +92 1 3.2842270894719214 -2.336991573654636 0.7621232582722934 0 2 -1 +142 1 2.8537576665436712 -3.369110508718591 0.5560526759827451 1 1 0 +1 1 2.08557845839204 -2.010493903326111 0.46603456602394955 0 -1 0 +12 1 -2.813558556370972 -1.5225310581093578 0.39881007051362743 0 0 1 +200 1 -2.620780645842095 -0.6334500549042138 1.1697962611458572 -1 0 0 +117 1 -2.3409262065663707 -1.4262844598718953 1.577896400637549 0 0 0 +199 1 -1.6721028915736709 -0.3937836671461621 1.764496832035196 1 -1 1 +119 1 -1.3702172421751233 -0.982726844411586 0.8109159599445125 0 -1 0 +118 1 -1.22523977151256 0.049111500972962366 0.34422431168243056 0 1 0 +179 1 -0.48400468992080004 -1.5634732075160336 0.9724005879568145 -1 3 1 +153 1 -0.7754078116015299 -0.12746028844271876 1.3139844087365358 1 1 0 +31 1 -0.21960550339589976 -0.3692535839546128 0.27760883173133294 0 -1 0 +154 1 1.1892001894282327 -1.234463776085168 0.4980011557336487 -1 2 0 +198 1 0.208959161472621 -0.7925251742172552 1.1981697813594612 0 0 1 +133 1 0.2021894978277857 -1.321629803385425 0.21342138424976495 1 1 1 +8 1 1.290866486655316 -0.32315323656178685 1.238429676489808 0 0 0 +43 1 1.4755875560077207 -1.5038423322367462 1.5696783276393578 -1 -1 1 +178 1 2.5595353005590473 -1.8548623704973153 1.5265130435507075 1 1 0 +156 1 3.10009336795942 -1.1347768292920712 0.7103971454931245 0 -1 0 +195 1 3.0488535895478486 -0.3819070637556806 1.6994009663148437 1 0 2 +32 1 2.1785721999000907 -0.8868183892594861 1.0608219538420214 1 0 -1 +75 1 -3.330023312049968 -0.13053199225722137 0.5772143324801579 1 -1 0 +138 1 -2.126928513622699 0.2705982397065681 0.9031685365715656 0 1 -1 +103 1 -2.5233875332738447 1.119832203926971 1.7143082124863906 -1 1 0 +89 1 -1.5625051595744621 1.0842527403417836 0.48114251556352683 0 0 -1 +73 1 -1.3841491529474708 0.7735632155517752 1.4917172788469495 0 -2 0 +93 1 -0.8459409435273203 1.6986071717879083 1.233579181789839 0 -1 0 +22 1 0.23130054165086983 0.3973595019638049 1.136265889331469 -1 0 -1 +181 1 1.6715679048902568 0.38189497066002065 0.5813616713777726 -1 1 -1 +125 1 0.7657348058398646 1.4638634812356126 0.3595929949039634 0 1 0 +129 1 1.187621376432971 0.7432781269466477 1.4756104377419834 -1 0 0 +186 1 0.12119836338531766 1.4258158866314226 1.7139997055217806 1 1 0 +44 1 3.246466614044557 0.935266979887072 0.09504504915790167 -1 -1 1 +139 1 2.294764083473655 0.2623628592978102 1.523064327633417 -1 2 0 +85 1 2.6715078057197426 -0.13923978779568133 0.48921080221894214 1 0 1 +100 1 2.179445623029225 1.1813699866412055 0.929258254331208 0 1 0 +59 1 3.199013987449739 0.7056213255691308 1.3011789902622373 0 -1 1 +184 1 -3.3541957825280964 1.6540170153788636 1.314525393258615 0 0 1 +116 1 -2.5607854807212633 2.8662954762956563 0.2561876654735037 1 0 0 +94 1 -2.209938696472392 1.817908573668992 0.9714554983444477 0 0 0 +16 1 3.462148790854558 2.750688132987863 1.1678814516580918 0 -2 1 +127 1 -0.6724215018270191 2.910608435174655 0.1393721830184081 0 -1 0 +39 1 -1.4963936644183389 2.8490269023893804 1.0397387839630663 0 -2 0 +109 1 1.2282064333649392 2.002097356660932 1.219647219360347 -1 1 0 +13 1 -0.038761589919005045 2.283368111259498 0.6285508805046305 -1 -1 1 +68 1 1.8122507294414043 2.919628635322565 1.388388027502655 0 0 1 +187 1 2.839543107439997 1.9712312705165291 0.44701965347775696 0 1 0 +150 1 2.6350933896773805 2.228885886643039 1.6430472643318494 0 -1 1 +101 1 -2.9845915106276357 -2.643240276070094 2.6131611879137338 1 3 1 +180 1 -2.4664624391703636 3.2461534604898077 2.2991216200041777 1 -1 1 +131 1 -2.1198879143055582 -2.5254800707290985 2.2468458013290475 1 0 0 +88 1 -1.8261664412558902 -3.2761989619835945 3.0217607589697706 0 1 -1 +51 1 -1.7527244407627123 -2.1114193587023125 3.178648460302574 0 0 -1 +121 1 -0.8632847382707834 -2.364486787477818 2.5298242427842235 -1 1 -1 +50 1 -1.3127850841438964 -3.332989957578539 1.7903541140988317 0 1 0 +63 1 1.6040989853168577 -2.8917377487223326 2.9749125296584396 -1 1 0 +27 1 0.22872838010698016 -2.994984028716655 2.6653598205127595 0 0 1 +10 1 0.9362147196804173 -2.581105523755157 1.9878669654444103 0 0 1 +185 1 0.06742724446398485 -1.8726052150227481 3.179787889614259 -2 1 -1 +62 1 0.9381874848569671 3.2183812476038773 2.122950032967029 0 0 0 +108 1 3.2075816395574557 -2.6473251670969744 3.3899630726255054 1 1 -1 +168 1 -3.4886505297786643 -3.024902771510678 1.648075348189236 0 1 -2 +96 1 2.193516168781477 -3.220451114036294 2.031971070369377 -2 2 -1 +57 1 2.897670474066688 -1.7869273194590956 2.7802854592878443 1 0 0 +155 1 2.0203257801003764 -2.093908363815807 2.3651374010253265 0 0 -1 +70 1 -2.289198729241698 -1.0693505000499786 3.3341581014665116 0 1 1 +86 1 3.4317154036170927 -1.33629793948954 1.5868690985104916 -2 0 0 +4 1 -2.642034929204445 -0.5735696636076526 2.24988074624273 0 0 -1 +148 1 -2.7958435550832177 -1.6271830272245196 2.4651167378398258 0 0 0 +197 1 -1.6297637248397103 -1.2496732630952756 2.4653302717640746 0 -1 -1 +23 1 -1.4165843839294037 -0.23332219410733462 -3.3887252652014874 0 0 -1 +78 1 -0.8539129642965406 -1.4368914881460948 3.1097976169270467 1 -1 1 +134 1 -0.7681520363929484 -1.1354013495310054 1.8538106613640677 -1 0 0 +66 1 -0.23373724912576396 -0.5882558302750734 2.5656269999794135 -1 -1 -1 +160 1 -1.1132775718863501 0.16126595419727965 2.3994619853672896 0 0 0 +18 1 0.6168554097448792 -0.8675105647197154 3.3233443940314107 0 -1 -2 +5 1 0.21124689546372627 -1.527936340282886 2.128421015823146 0 -1 -1 +167 1 1.157996163161525 -1.3890474926504965 2.5930120556899743 0 1 -1 +176 1 0.7227757787132028 -0.4265054817409199 2.130677354553178 0 0 0 +77 1 2.0007502274099562 -0.6930768409753575 2.0562080526704536 0 -1 1 +136 1 2.059758900185651 -1.052357318680519 3.1194387358517117 0 -1 -2 +163 1 3.3650479388293877 -0.7812523229666395 2.7231341802578797 -1 -1 0 +53 1 -2.3141819292399695 1.20855609162257 -3.127003289906138 -1 -1 1 +34 1 -2.2520285035649175 0.34377072469492165 3.2433897655354262 1 0 -1 +82 1 -3.1361148993392707 0.2917712829104399 2.508598507937298 0 -1 -1 +47 1 -2.903472142580087 1.2996380231419302 2.6614912616951822 0 1 0 +159 1 -1.8421866316781088 1.3742261871908503 2.7832166426856038 0 0 0 +161 1 -1.2319440636738626 0.9387211724622819 -3.4892930122068617 1 0 2 +33 1 -0.4449542140900899 0.2769280403688486 3.289217283277774 0 -1 -1 +191 1 -0.8687075277531521 1.281273999295463 2.3493691514045447 1 -1 0 +20 1 -0.12835229617409075 0.4001437971686418 2.091186274425671 1 0 -1 +21 1 1.5590447736292827 0.23116165627532026 2.4331182207698356 1 0 -1 +83 1 0.6019872094726322 0.17868421219256525 2.965010196172179 0 -2 0 +107 1 -0.09314344901480053 1.8386195873289717 2.9198165047206524 -1 1 0 +97 1 0.9500008570521725 1.1147256892756756 2.5445482565685626 0 -1 -1 +15 1 2.6866827472081427 0.05611542822496954 2.621280841687164 -1 0 -1 +40 1 2.0535009935702107 1.3482348414084473 2.153119101811638 0 0 0 +110 1 3.037377950690711 1.1454318013031137 2.4602998295324308 0 0 -2 +54 1 2.1368310833242825 0.6989281938007096 3.190545712320829 0 -1 -1 +71 1 -2.6906257490825327 2.3188264822083675 1.851572369390678 0 -1 -1 +45 1 -1.8822606439217724 2.5464355632785174 2.887157746831732 1 0 -1 +2 1 -1.527738763941238 2.1784215473644295 1.8498426738676617 1 -2 -1 +67 1 -1.014923597719753 2.0522310481028465 3.091487536680741 1 0 0 +192 1 -0.8672155474955553 3.087168735274927 2.6165250257240618 1 0 1 +124 1 -0.37769468839105996 2.5506571887551175 1.8053870882842125 1 -1 -1 +46 1 -0.2092884053324724 2.562694157698328 -3.2372195292692605 1 -1 -1 +114 1 -0.2001222858286487 -3.429888000295159 1.8301280696628333 0 0 0 +61 1 0.5140644440329998 2.208326878392573 2.2153556959139413 -1 -2 0 +169 1 1.5629071468921552 2.2983930760888316 2.2366483189031316 0 0 0 +128 1 -3.438885935852406 3.376929578988928 3.002455750479755 1 0 -2 +52 1 -3.4549495641597217 2.178628786705743 2.923210719991474 0 -1 0 +48 1 2.502392696348409 2.9340155922847346 2.5991521468190113 0 0 -1 diff --git a/examples/PACKAGES/pimd/lj_reduced_units/in.lmp b/examples/PACKAGES/pimd/lj_reduced_units/in.lmp new file mode 100644 index 0000000000..012214c4b2 --- /dev/null +++ b/examples/PACKAGES/pimd/lj_reduced_units/in.lmp @@ -0,0 +1,26 @@ +variable ibead uloop 32 pad + +units lj +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 2.8015 +read_data data.lj${ibead} + +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +mass 1 1.0 + +timestep 0.00044905847 + +fix 1 all pimd/langevin ensemble nvt integrator obabo temp 1.00888 lj 0.00965188 3.4 39.948 4.135667403e-3 1.03646168908e-4 thermostat PILE_L ${ibead} + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no format line "%d %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f" + +dump dcd all custom 1 ${ibead}.xyz id type x y z vx vy vz ix iy iz fx fy fz +dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 diff --git a/examples/PACKAGES/pimd/lj_reduced_units/run.sh b/examples/PACKAGES/pimd/lj_reduced_units/run.sh new file mode 100644 index 0000000000..adc7f4b955 --- /dev/null +++ b/examples/PACKAGES/pimd/lj_reduced_units/run.sh @@ -0,0 +1 @@ +mpirun -np 2 $LMP -in in.lmp -p 2x1 -log log -screen screen From f6d94a95dddc33e7407e256e79374a69044fc01f Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 27 Mar 2023 22:45:14 -0400 Subject: [PATCH 054/448] fix whitespace in fix pimd doc --- doc/src/fix_pimd.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index e4a59b0078..1767acb134 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -106,7 +106,7 @@ thermostats in each chain. For example, for a simulation of N particles with P beads in each ring-polymer, the total number of NH thermostats would be 3 x N x P x Nc. -Fix *pimd/langevin* implements a Langevin thermostat in the normal mode +Fix *pimd/langevin* implements a Langevin thermostat in the normal mode representation, and also provides a barostat to sample the NPH/NPT ensembles. .. note:: @@ -273,7 +273,7 @@ related tasks for each of the partitions, e.g. forces in the normal mode representation. If the Catersian velocities and forces are needed, it is easy to perform the transformation when doing post-processing. - It is recommended to dump the image flags (*ix iy iz*) for fix *pimd/langevin*. It + It is recommended to dump the image flags (*ix iy iz*) for fix *pimd/langevin*. It will be useful if you want to calculate some estimators during post-processing. Restart, fix_modify, output, run start/stop, minimize info From 849933a687610642ff26bf3af5ead984f8634e22 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 27 Mar 2023 23:06:05 -0400 Subject: [PATCH 055/448] add difference part in fix pimd doc --- doc/src/fix_pimd.rst | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 1767acb134..fda002484a 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -269,13 +269,25 @@ related tasks for each of the partitions, e.g. read_restart system_${ibead}.restart2 .. note:: - Fix *pimd/langevin* dumps the Catersian coordinates, but dumps the velocities and - forces in the normal mode representation. If the Catersian velocities and forces are + Fix *pimd/langevin* dumps the Cartesian coordinates, but dumps the velocities and + forces in the normal mode representation. If the Cartesian velocities and forces are needed, it is easy to perform the transformation when doing post-processing. It is recommended to dump the image flags (*ix iy iz*) for fix *pimd/langevin*. It will be useful if you want to calculate some estimators during post-processing. +Major differences of *fix pimd/nvt* and *fix pimd/langevin* are: + + #. *Fix pimd/nvt* includes Cartesian pimd, normal mode pimd, and centroid md. *Fix pimd/langevin* only intends to support normal mode pimd, as it is commonly enough for thermodynamic sampling. + #. *Fix pimd/nvt* uses Nose-Hoover chain thermostat. *Fix pimd/langevin* uses Langevin thermostat. + #. *Fix pimd/langevin* provides barostat, so the npt ensemble can be sampled. *Fix pimd/nvt* only support nvt ensemble. + #. *Fix pimd/langevin* provides several quantum estimators in output. + #. *Fix pimd/langevin* allows multiple processes for each bead. For *fix pimd/nvt*, there is a large chance that multi-process tasks for each bead may fail. + #. The dump of *fix pimd/nvt* are all Cartesian. *Fix pimd/langevin* dumps normal-mode velocities and forces, and Cartesian coordinates. + +Initially, the inter-replica communication and normal mode transformation parts of *fix pimd/langevin* are written based on +those of *fix pimd/nvt*, but are significantly revised. + Restart, fix_modify, output, run start/stop, minimize info """"""""""""""""""""""""""""""""""""""""""""""""""""""""""" From 19da998932f4df73954d81bc810d96d9f3df2981 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Mon, 27 Mar 2023 23:11:24 -0400 Subject: [PATCH 056/448] add Jacobian into utils/sphinx-config/false_positives.txt --- doc/utils/sphinx-config/false_positives.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index fda9fb2b08..6a29c84974 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1613,6 +1613,7 @@ Izumi Izvekov izz Izz +Jacobian Jacobsen Jadhao Jadhav From 18e4ed2e322a51734ca3250ee9aa593a15ef9864 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 31 Mar 2023 00:59:35 -0400 Subject: [PATCH 057/448] do not transform velocity to normal mode in setup --- src/REPLICA/fix_pimd_langevin.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index d64d948ecf..6c5b1a0b09 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -450,13 +450,6 @@ void FixPIMDLangevin::setup(int vflag) for (int i = 0; i < nlocal; i++) domain->unmap_inv(x[i], image[i]); } - if (method == NMPIMD) { - inter_replica_comm(v); - if (cmode == SINGLE_PROC) - nmpimd_transform(bufsortedall, v, M_x2xp[universe->iworld]); - else if (cmode == MULTI_PROC) - nmpimd_transform(bufbeads, v, M_x2xp[universe->iworld]); - } post_force(vflag); compute_totke(); end_of_step(); From 25c449df8e2b78de7e4c29c8a8ec42ba71fbc8c5 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 31 Mar 2023 03:03:17 -0400 Subject: [PATCH 058/448] enable restart in fix pimd/langevin --- src/REPLICA/fix_pimd_langevin.cpp | 53 +++++++++++++++++++++++++++++-- src/REPLICA/fix_pimd_langevin.h | 5 +++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 6c5b1a0b09..b4ea68d49b 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -65,6 +65,7 @@ enum { SINGLE_PROC, MULTI_PROC }; FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) { + restart_global = 1; time_integrate = 1; tagsend = tagrecv = nullptr; bufsend = bufrecv = nullptr; @@ -254,6 +255,8 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : } } extvector = 1; + kBT = force->boltz * temp; + if (pstat_flag) baro_init(); // some initilizations @@ -376,7 +379,6 @@ void FixPIMDLangevin::init() } planck *= sp; hbar = planck / (2.0 * MY_PI); - kBT = force->boltz * temp; double beta = 1.0 / (force->boltz * temp); double _fbond = 1.0 * np * np / (beta * beta * hbar * hbar); @@ -408,7 +410,6 @@ void FixPIMDLangevin::init() nmpimd_init(); Langevin_init(); - if (pstat_flag) baro_init(); c_pe = modify->get_compute_by_id(id_pe); c_press = modify->get_compute_by_id(id_press); @@ -1371,6 +1372,54 @@ void FixPIMDLangevin::compute_totenthalpy() totenthalpy = tote + 1.5 * W * vw[0] * vw[0] * inverse_np + p_hydro * (volume - vol0); } +/* ---------------------------------------------------------------------- + pack entire state of Fix into one write +------------------------------------------------------------------------- */ + +void FixPIMDLangevin::write_restart(FILE *fp) +{ + int nsize = size_restart_global(); + + double *list; + memory->create(list,nsize,"FixPIMDLangevin:list"); + + pack_restart_data(list); + + if (comm->me == 0) { + int size = nsize * sizeof(double); + fwrite(&size,sizeof(int),1,fp); + fwrite(list,sizeof(double),nsize,fp); + } + + memory->destroy(list); +} +/* ---------------------------------------------------------------------- */ + +int FixPIMDLangevin::size_restart_global() +{ + int nsize = 6; + + return nsize; +} + +/* ---------------------------------------------------------------------- */ + +int FixPIMDLangevin::pack_restart_data(double *list) +{ + int n = 0; + for (int i=0; i<6; i++) { list[n++] = vw[i]; } + return n; +} + +/* ---------------------------------------------------------------------- */ + +void FixPIMDLangevin::restart(char *buf) +{ + int n = 0; + auto list = (double *) buf; + for (int i=0; i<6; i++) { vw[i] = list[n++]; } +} + /* ---------------------------------------------------------------------- */ double FixPIMDLangevin::compute_vector(int n) diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 6d236718c7..79a2ee7477 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -175,6 +175,11 @@ class FixPIMDLangevin : public Fix { void compute_vir(); void compute_cvir(); void compute_totenthalpy(); + + void write_restart(FILE *fp) override; + int size_restart_global(); + int pack_restart_data(double *list); + void restart(char *buf) override; }; } // namespace LAMMPS_NS #endif From c37247eb5a75469493b7a81008c1b2fef9aa30e6 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 31 Mar 2023 03:09:34 -0400 Subject: [PATCH 059/448] add restart info in doc --- doc/src/fix_pimd.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index fda002484a..ae325023fd 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -297,7 +297,11 @@ quasi-beads to :doc:`binary restart files `. See the a fix in an input script that reads a restart file, so that the operation of the fix continues in an uninterrupted fashion. -Fix *pimd/langevin* ... +Fix *pimd/langevin* writes the state of the barostat overall beads to +:doc:`binary restart files `. Since it uses a stochastic thermostat, +the state of the thermostat is not written. However, the state of the system +can be restored by reading the restart file, execpt that it will re-initialize +the random number generator. None of the :doc:`fix_modify ` options are relevant to fix pimd/nvt. From f444fe8fdf0b139a44f33e4b47120dd45173dea1 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 31 Mar 2023 03:12:38 -0400 Subject: [PATCH 060/448] fix spelling error --- doc/src/fix_pimd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index ae325023fd..7116ce526b 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -300,7 +300,7 @@ operation of the fix continues in an uninterrupted fashion. Fix *pimd/langevin* writes the state of the barostat overall beads to :doc:`binary restart files `. Since it uses a stochastic thermostat, the state of the thermostat is not written. However, the state of the system -can be restored by reading the restart file, execpt that it will re-initialize +can be restored by reading the restart file, except that it will re-initialize the random number generator. None of the :doc:`fix_modify ` options From 42758d0780835ded30631f8ed1a815f98fff6ec2 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Fri, 31 Mar 2023 03:28:09 -0400 Subject: [PATCH 061/448] delete dynamically allocated arrays in destructor --- src/REPLICA/fix_pimd_langevin.cpp | 39 +++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index b4ea68d49b..4d1ca2eb62 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -341,6 +341,45 @@ FixPIMDLangevin::~FixPIMDLangevin() delete[] id_pe; delete[] id_press; delete random; + delete c_pe; + delete c_press; + delete[] mass; + delete[] _omega_k; + delete[] Lan_c; + delete[] Lan_s; + delete[] tau_k; + delete[] c1_k; + delete[] c2_k; + delete[] plansend; + delete[] planrecv; + delete[] modeindex; + memory->destroy(xcall); + if (cmode == SINGLE_PROC) { + memory->destroy(bufsorted); + memory->destroy(outsorted); + memory->destroy(bufsortedall); + memory->destroy(buftransall); + memory->destroy(counts); + memory->destroy(displacements); + } + + if (cmode == MULTI_PROC) { + memory->destroy(bufsendall); + memory->destroy(bufrecvall); + memory->destroy(tagsendall); + memory->destroy(tagrecvall); + memory->destroy(counts); + memory->destroy(displacements); + } + memory->destroy(M_x2xp); + memory->destroy(M_xp2x); + memory->destroy(xc); + memory->destroy(x_unwrap); + memory->destroy(bufsend); + memory->destroy(bufrecv); + memory->destroy(tagsend); + memory->destroy(tagrecv); + memory->destroy(bufbeads); } /* ---------------------------------------------------------------------- */ From 5cb3d15ada2910ef174e0cf2d13ca0f81cdf24b5 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 19 Apr 2023 12:47:38 -0600 Subject: [PATCH 062/448] Add Kokkos support for atom sorting on device --- src/KOKKOS/atom_kokkos.cpp | 137 ++++++++++------------- src/KOKKOS/atom_kokkos.h | 4 + src/KOKKOS/atom_vec_angle_kokkos.cpp | 29 +++++ src/KOKKOS/atom_vec_angle_kokkos.h | 1 + src/KOKKOS/atom_vec_atomic_kokkos.cpp | 18 +++ src/KOKKOS/atom_vec_atomic_kokkos.h | 1 + src/KOKKOS/atom_vec_bond_kokkos.cpp | 24 ++++ src/KOKKOS/atom_vec_bond_kokkos.h | 1 + src/KOKKOS/atom_vec_charge_kokkos.cpp | 19 ++++ src/KOKKOS/atom_vec_charge_kokkos.h | 1 + src/KOKKOS/atom_vec_dipole_kokkos.cpp | 20 ++++ src/KOKKOS/atom_vec_dipole_kokkos.h | 1 + src/KOKKOS/atom_vec_dpd_kokkos.cpp | 24 ++++ src/KOKKOS/atom_vec_dpd_kokkos.h | 1 + src/KOKKOS/atom_vec_full_kokkos.cpp | 42 +++++++ src/KOKKOS/atom_vec_full_kokkos.h | 1 + src/KOKKOS/atom_vec_hybrid_kokkos.cpp | 10 ++ src/KOKKOS/atom_vec_hybrid_kokkos.h | 1 + src/KOKKOS/atom_vec_kokkos.h | 8 +- src/KOKKOS/atom_vec_molecular_kokkos.cpp | 41 +++++++ src/KOKKOS/atom_vec_molecular_kokkos.h | 1 + src/KOKKOS/atom_vec_sphere_kokkos.cpp | 21 ++++ src/KOKKOS/atom_vec_sphere_kokkos.h | 1 + src/KOKKOS/atom_vec_spin_kokkos.cpp | 19 ++++ src/KOKKOS/atom_vec_spin_kokkos.h | 2 +- src/KOKKOS/fix_acks2_reaxff_kokkos.cpp | 20 ++++ src/KOKKOS/fix_acks2_reaxff_kokkos.h | 4 +- src/KOKKOS/fix_langevin_kokkos.cpp | 20 ++++ src/KOKKOS/fix_langevin_kokkos.h | 4 +- src/KOKKOS/fix_minimize_kokkos.cpp | 17 +++ src/KOKKOS/fix_minimize_kokkos.h | 4 +- src/KOKKOS/fix_neigh_history_kokkos.cpp | 24 +++- src/KOKKOS/fix_neigh_history_kokkos.h | 1 + src/KOKKOS/fix_qeq_reaxff_kokkos.cpp | 21 +++- src/KOKKOS/fix_qeq_reaxff_kokkos.h | 1 + src/KOKKOS/fix_shake_kokkos.cpp | 24 +++- src/KOKKOS/fix_shake_kokkos.h | 1 + src/KOKKOS/fix_wall_gran_kokkos.cpp | 18 ++- src/KOKKOS/fix_wall_gran_kokkos.h | 1 + src/KOKKOS/kokkos.cpp | 25 +++++ src/KOKKOS/kokkos.h | 2 + src/KOKKOS/kokkos_base.h | 7 ++ src/atom.cpp | 5 + src/atom.h | 2 +- src/fix.cpp | 2 +- src/fix.h | 1 + 46 files changed, 545 insertions(+), 87 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 938d9709e9..9bbbb2acc3 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -22,6 +22,11 @@ #include "kokkos.h" #include "memory_kokkos.h" #include "update.h" +#include "kokkos_base.h" +#include "modify.h" +#include "fix.h" + +#include using namespace LAMMPS_NS; @@ -103,6 +108,15 @@ AtomKokkos::~AtomKokkos() /* ---------------------------------------------------------------------- */ +void AtomKokkos::init() +{ + Atom::init(); + + sort_classic = lmp->kokkos->sort_classic; +} + +/* ---------------------------------------------------------------------- */ + void AtomKokkos::sync(const ExecutionSpace space, unsigned int mask) { if (space == Device && lmp->kokkos->auto_sync) avecKK->modified(Host, mask); @@ -140,8 +154,36 @@ void AtomKokkos::allocate_type_arrays() void AtomKokkos::sort() { - int i, m, n, ix, iy, iz, ibin, empty; + // check if all fixes with atom-based arrays support sort on device + if (!sort_classic) { + int flag = 1; + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) { + auto fix_iextra = modify->fix[atom->extra_grow[iextra]]; + if (!fix_iextra->sort_device) { + flag = 0; + break; + } + } + if (!flag) { + if (comm->me == 0) { + error->warning(FLERR,"Fix with atom-based arrays not compatible with Kokkos sorting on device, " + "switching to classic host sorting"); + } + } + } + + if (sort_classic) { + sync(Host, ALL_MASK); + Atom::sort(); + modified(Host, ALL_MASK); + } else sort_device(); +} + +/* ---------------------------------------------------------------------- */ + +void AtomKokkos::sort_device() +{ // set next timestep for sorting to take place nextsort = (update->ntimestep / sortfreq) * sortfreq + sortfreq; @@ -151,88 +193,32 @@ void AtomKokkos::sort() if (domain->box_change) setup_sort_bins(); if (nbins == 1) return; - // reallocate per-atom vectors if needed + auto d_x = k_x.d_view; + sync(Device, X_MASK); - if (atom->nmax > maxnext) { - memory->destroy(next); - memory->destroy(permute); - maxnext = atom->nmax; - memory->create(next, maxnext, "atom:next"); - memory->create(permute, maxnext, "atom:permute"); - } + // sort - // ensure there is one extra atom location at end of arrays for swaps + int max_bins[3]; + max_bins[0] = nbinx; + max_bins[1] = nbiny; + max_bins[2] = nbinz; - if (nlocal == nmax) avec->grow(0); + using KeyViewType = DAT::t_x_array; + using BinOp = Kokkos::BinOp3DReverse; + BinOp binner(max_bins, bboxlo, bboxhi); + Kokkos::BinSort Sorter(d_x, 0, nlocal, binner, false); + Sorter.create_permute_vector(LMPDeviceType()); - sync(Host, ALL_MASK); - modified(Host, ALL_MASK); + avecKK->sort_kokkos(Sorter); - // bin atoms in reverse order so linked list will be in forward order + if (atom->nextra_grow) { + for (int iextra = 0; iextra < atom->nextra_grow; iextra++) { + auto fix_iextra = modify->fix[atom->extra_grow[iextra]]; + KokkosBase *kkbase = dynamic_cast(fix_iextra); - for (i = 0; i < nbins; i++) binhead[i] = -1; - - HAT::t_x_array_const h_x = k_x.view(); - for (i = nlocal - 1; i >= 0; i--) { - ix = static_cast((h_x(i, 0) - bboxlo[0]) * bininvx); - iy = static_cast((h_x(i, 1) - bboxlo[1]) * bininvy); - iz = static_cast((h_x(i, 2) - bboxlo[2]) * bininvz); - ix = MAX(ix, 0); - iy = MAX(iy, 0); - iz = MAX(iz, 0); - ix = MIN(ix, nbinx - 1); - iy = MIN(iy, nbiny - 1); - iz = MIN(iz, nbinz - 1); - ibin = iz * nbiny * nbinx + iy * nbinx + ix; - next[i] = binhead[ibin]; - binhead[ibin] = i; - } - - // permute = desired permutation of atoms - // permute[I] = J means Ith new atom will be Jth old atom - - n = 0; - for (m = 0; m < nbins; m++) { - i = binhead[m]; - while (i >= 0) { - permute[n++] = i; - i = next[i]; + kkbase->sort_kokkos(Sorter); } } - - // current = current permutation, just reuse next vector - // current[I] = J means Ith current atom is Jth old atom - - int *current = next; - for (i = 0; i < nlocal; i++) current[i] = i; - - // reorder local atom list, when done, current = permute - // perform "in place" using copy() to extra atom location at end of list - // inner while loop processes one cycle of the permutation - // copy before inner-loop moves an atom to end of atom list - // copy after inner-loop moves atom at end of list back into list - // empty = location in atom list that is currently empty - - for (i = 0; i < nlocal; i++) { - if (current[i] == permute[i]) continue; - avec->copy(i, nlocal, 0); - empty = i; - while (permute[empty] != i) { - avec->copy(permute[empty], empty, 0); - empty = current[empty] = permute[empty]; - } - avec->copy(nlocal, empty, 0); - current[empty] = permute[empty]; - } - - // sanity check that current = permute - - //int flag = 0; - //for (i = 0; i < nlocal; i++) - // if (current[i] != permute[i]) flag = 1; - //int flagall; - //MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); - //if (flagall) errorX->all(FLERR,"Atom sort did not operate correctly"); } /* ---------------------------------------------------------------------- @@ -241,7 +227,6 @@ void AtomKokkos::sort() void AtomKokkos::grow(unsigned int mask) { - if (mask & SPECIAL_MASK) { memoryKK->destroy_kokkos(k_special, special); sync(Device, mask); diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index 8d2ae47f0e..84bb7a56eb 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -22,6 +22,8 @@ namespace LAMMPS_NS { class AtomKokkos : public Atom { public: + bool sort_classic; + DAT::tdual_tagint_1d k_tag; DAT::tdual_int_1d k_type, k_mask; DAT::tdual_imageint_1d k_image; @@ -108,6 +110,7 @@ class AtomKokkos : public Atom { return local; } + void init() override; void allocate_type_arrays() override; void sync(const ExecutionSpace space, unsigned int mask); void modified(const ExecutionSpace space, unsigned int mask); @@ -119,6 +122,7 @@ class AtomKokkos : public Atom { virtual void deallocate_topology(); void sync_modify(ExecutionSpace, unsigned int, unsigned int) override; private: + void sort_device(); class AtomVec *new_avec(const std::string &, int, int &) override; }; diff --git a/src/KOKKOS/atom_vec_angle_kokkos.cpp b/src/KOKKOS/atom_vec_angle_kokkos.cpp index f132298c2d..dd6be164c0 100644 --- a/src/KOKKOS/atom_vec_angle_kokkos.cpp +++ b/src/KOKKOS/atom_vec_angle_kokkos.cpp @@ -155,6 +155,35 @@ void AtomVecAngleKokkos::grow_pointers() h_angle_atom3 = atomKK->k_angle_atom3.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecAngleKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_molecule); + Sorter.sort(LMPDeviceType(), d_num_bond); + Sorter.sort(LMPDeviceType(), d_bond_type); + Sorter.sort(LMPDeviceType(), d_bond_atom); + Sorter.sort(LMPDeviceType(), d_nspecial); + Sorter.sort(LMPDeviceType(), d_special); + Sorter.sort(LMPDeviceType(), d_num_angle); + Sorter.sort(LMPDeviceType(), d_angle_type); + Sorter.sort(LMPDeviceType(), d_angle_atom1); + Sorter.sort(LMPDeviceType(), d_angle_atom2); + Sorter.sort(LMPDeviceType(), d_angle_atom3); + + atomKK->modified(Device, ALL_MASK & ~F_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_angle_kokkos.h b/src/KOKKOS/atom_vec_angle_kokkos.h index a1c20c103b..44f1d824b2 100644 --- a/src/KOKKOS/atom_vec_angle_kokkos.h +++ b/src/KOKKOS/atom_vec_angle_kokkos.h @@ -34,6 +34,7 @@ class AtomVecAngleKokkos : public AtomVecKokkos, public AtomVecAngle { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, const int & iswap, const DAT::tdual_xfloat_2d &buf, diff --git a/src/KOKKOS/atom_vec_atomic_kokkos.cpp b/src/KOKKOS/atom_vec_atomic_kokkos.cpp index e37779ace5..1ea8377a68 100644 --- a/src/KOKKOS/atom_vec_atomic_kokkos.cpp +++ b/src/KOKKOS/atom_vec_atomic_kokkos.cpp @@ -100,6 +100,24 @@ void AtomVecAtomicKokkos::grow_pointers() h_f = atomKK->k_f.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecAtomicKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + + atomKK->modified(Device, ALL_MASK & ~F_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_atomic_kokkos.h b/src/KOKKOS/atom_vec_atomic_kokkos.h index f72af73537..07631dda98 100644 --- a/src/KOKKOS/atom_vec_atomic_kokkos.h +++ b/src/KOKKOS/atom_vec_atomic_kokkos.h @@ -35,6 +35,7 @@ class AtomVecAtomicKokkos : public AtomVecKokkos, public AtomVecAtomic { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap, int pbc_flag, int *pbc, ExecutionSpace space) override; diff --git a/src/KOKKOS/atom_vec_bond_kokkos.cpp b/src/KOKKOS/atom_vec_bond_kokkos.cpp index dcbe1876f4..c45bdedf38 100644 --- a/src/KOKKOS/atom_vec_bond_kokkos.cpp +++ b/src/KOKKOS/atom_vec_bond_kokkos.cpp @@ -126,6 +126,30 @@ void AtomVecBondKokkos::grow_pointers() h_bond_atom = atomKK->k_bond_atom.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecBondKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_molecule); + Sorter.sort(LMPDeviceType(), d_num_bond); + Sorter.sort(LMPDeviceType(), d_bond_type); + Sorter.sort(LMPDeviceType(), d_bond_atom); + Sorter.sort(LMPDeviceType(), d_nspecial); + Sorter.sort(LMPDeviceType(), d_special); + + atomKK->modified(Device, ALL_MASK & ~F_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_bond_kokkos.h b/src/KOKKOS/atom_vec_bond_kokkos.h index fc3f02e916..5ed59432de 100644 --- a/src/KOKKOS/atom_vec_bond_kokkos.h +++ b/src/KOKKOS/atom_vec_bond_kokkos.h @@ -34,6 +34,7 @@ class AtomVecBondKokkos : public AtomVecKokkos, public AtomVecBond { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap, int pbc_flag, int *pbc, ExecutionSpace space) override; diff --git a/src/KOKKOS/atom_vec_charge_kokkos.cpp b/src/KOKKOS/atom_vec_charge_kokkos.cpp index a9975c1bb4..22fc63ff91 100644 --- a/src/KOKKOS/atom_vec_charge_kokkos.cpp +++ b/src/KOKKOS/atom_vec_charge_kokkos.cpp @@ -106,6 +106,25 @@ void AtomVecChargeKokkos::grow_pointers() h_q = atomKK->k_q.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecChargeKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_q); + + atomKK->modified(Device, ALL_MASK & ~F_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_charge_kokkos.h b/src/KOKKOS/atom_vec_charge_kokkos.h index 072b5e6894..397a5ee4c0 100644 --- a/src/KOKKOS/atom_vec_charge_kokkos.h +++ b/src/KOKKOS/atom_vec_charge_kokkos.h @@ -35,6 +35,7 @@ class AtomVecChargeKokkos : public AtomVecKokkos, public AtomVecCharge { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap, int pbc_flag, int *pbc, ExecutionSpace space) override; diff --git a/src/KOKKOS/atom_vec_dipole_kokkos.cpp b/src/KOKKOS/atom_vec_dipole_kokkos.cpp index b2357ccb41..ad06570cdc 100644 --- a/src/KOKKOS/atom_vec_dipole_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dipole_kokkos.cpp @@ -107,6 +107,26 @@ void AtomVecDipoleKokkos::grow_pointers() h_mu = atomKK->k_mu.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecDipoleKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_q); + Sorter.sort(LMPDeviceType(), d_mu); + + atomKK->modified(Device, ALL_MASK & ~F_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_dipole_kokkos.h b/src/KOKKOS/atom_vec_dipole_kokkos.h index f9abfc9a2a..97ec92c6c6 100644 --- a/src/KOKKOS/atom_vec_dipole_kokkos.h +++ b/src/KOKKOS/atom_vec_dipole_kokkos.h @@ -35,6 +35,7 @@ class AtomVecDipoleKokkos : public AtomVecKokkos, public AtomVecDipole { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap, int pbc_flag, int *pbc, ExecutionSpace space) override; diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.cpp b/src/KOKKOS/atom_vec_dpd_kokkos.cpp index 6fa3277350..eda26a92dc 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.cpp +++ b/src/KOKKOS/atom_vec_dpd_kokkos.cpp @@ -135,6 +135,30 @@ void AtomVecDPDKokkos::grow_pointers() h_duChem = atomKK->k_duChem.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecDPDKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK & ~DPDRHO_MASK & ~DUCHEM_MASK & ~DVECTOR_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_dpdTheta); + Sorter.sort(LMPDeviceType(), d_uCond); + Sorter.sort(LMPDeviceType(), d_uMech); + Sorter.sort(LMPDeviceType(), d_uChem); + Sorter.sort(LMPDeviceType(), d_uCG); + Sorter.sort(LMPDeviceType(), d_uCGnew); + + atomKK->modified(Device, ALL_MASK & ~F_MASK & ~DPDRHO_MASK & ~DUCHEM_MASK & ~DVECTOR_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_dpd_kokkos.h b/src/KOKKOS/atom_vec_dpd_kokkos.h index c605246eba..a76d7f908a 100644 --- a/src/KOKKOS/atom_vec_dpd_kokkos.h +++ b/src/KOKKOS/atom_vec_dpd_kokkos.h @@ -35,6 +35,7 @@ class AtomVecDPDKokkos : public AtomVecKokkos, public AtomVecDPD { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, const int & iswap, const DAT::tdual_xfloat_2d &buf, diff --git a/src/KOKKOS/atom_vec_full_kokkos.cpp b/src/KOKKOS/atom_vec_full_kokkos.cpp index bb61c7fb46..829ebc75e6 100644 --- a/src/KOKKOS/atom_vec_full_kokkos.cpp +++ b/src/KOKKOS/atom_vec_full_kokkos.cpp @@ -225,6 +225,48 @@ void AtomVecFullKokkos::grow_pointers() h_improper_atom4 = atomKK->k_improper_atom4.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecFullKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_q); + Sorter.sort(LMPDeviceType(), d_molecule); + Sorter.sort(LMPDeviceType(), d_num_bond); + Sorter.sort(LMPDeviceType(), d_bond_type); + Sorter.sort(LMPDeviceType(), d_bond_atom); + Sorter.sort(LMPDeviceType(), d_nspecial); + Sorter.sort(LMPDeviceType(), d_special); + Sorter.sort(LMPDeviceType(), d_num_angle); + Sorter.sort(LMPDeviceType(), d_angle_type); + Sorter.sort(LMPDeviceType(), d_angle_atom1); + Sorter.sort(LMPDeviceType(), d_angle_atom2); + Sorter.sort(LMPDeviceType(), d_angle_atom3); + Sorter.sort(LMPDeviceType(), d_num_dihedral); + Sorter.sort(LMPDeviceType(), d_dihedral_type); + Sorter.sort(LMPDeviceType(), d_dihedral_atom1); + Sorter.sort(LMPDeviceType(), d_dihedral_atom2); + Sorter.sort(LMPDeviceType(), d_dihedral_atom3); + Sorter.sort(LMPDeviceType(), d_dihedral_atom4); + Sorter.sort(LMPDeviceType(), d_num_improper); + Sorter.sort(LMPDeviceType(), d_improper_type); + Sorter.sort(LMPDeviceType(), d_improper_atom1); + Sorter.sort(LMPDeviceType(), d_improper_atom2); + Sorter.sort(LMPDeviceType(), d_improper_atom3); + Sorter.sort(LMPDeviceType(), d_improper_atom4); + + atomKK->modified(Device, ALL_MASK & ~F_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_full_kokkos.h b/src/KOKKOS/atom_vec_full_kokkos.h index e6fcfd7e40..4937ef4152 100644 --- a/src/KOKKOS/atom_vec_full_kokkos.h +++ b/src/KOKKOS/atom_vec_full_kokkos.h @@ -34,6 +34,7 @@ class AtomVecFullKokkos : public AtomVecKokkos, public AtomVecFull { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap, int pbc_flag, int *pbc, ExecutionSpace space) override; diff --git a/src/KOKKOS/atom_vec_hybrid_kokkos.cpp b/src/KOKKOS/atom_vec_hybrid_kokkos.cpp index 03311d1c32..4e01ab5794 100644 --- a/src/KOKKOS/atom_vec_hybrid_kokkos.cpp +++ b/src/KOKKOS/atom_vec_hybrid_kokkos.cpp @@ -51,6 +51,16 @@ void AtomVecHybridKokkos::grow(int n) f = atom->f; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecHybridKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + for (int k = 0; k < nstyles; k++) + (dynamic_cast(styles[k]))->sort_kokkos(Sorter); +} + /* ---------------------------------------------------------------------- */ int AtomVecHybridKokkos::pack_comm_kokkos(const int &/*n*/, const DAT::tdual_int_2d &/*k_sendlist*/, diff --git a/src/KOKKOS/atom_vec_hybrid_kokkos.h b/src/KOKKOS/atom_vec_hybrid_kokkos.h index 862b43d80b..6f81c93673 100644 --- a/src/KOKKOS/atom_vec_hybrid_kokkos.h +++ b/src/KOKKOS/atom_vec_hybrid_kokkos.h @@ -34,6 +34,7 @@ class AtomVecHybridKokkos : public AtomVecKokkos, public AtomVecHybrid { AtomVecHybridKokkos(class LAMMPS *); void grow(int) override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, const int & iswap, diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index dfb4aecfcf..ef6a3fcbc8 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -20,6 +20,8 @@ #include "kokkos_type.h" #include +#include + namespace LAMMPS_NS { union d_ubuf { @@ -38,6 +40,11 @@ class AtomVecKokkos : virtual public AtomVec { AtomVecKokkos(class LAMMPS *); ~AtomVecKokkos() override; + using KeyViewType = DAT::t_x_array; + using BinOp = Kokkos::BinOp3DReverse; + virtual void + sort_kokkos(Kokkos::BinSort &Sorter) = 0; + virtual void sync(ExecutionSpace space, unsigned int mask) = 0; virtual void modified(ExecutionSpace space, unsigned int mask) = 0; virtual void sync_overlapping_device(ExecutionSpace space, unsigned int mask) = 0; @@ -117,7 +124,6 @@ class AtomVecKokkos : virtual public AtomVec { ExecutionSpace space, DAT::tdual_int_1d &k_indices) = 0; - int no_comm_vel_flag,no_border_vel_flag; int unpack_exchange_indices_flag; int size_exchange; diff --git a/src/KOKKOS/atom_vec_molecular_kokkos.cpp b/src/KOKKOS/atom_vec_molecular_kokkos.cpp index 1bb75a1906..471dd0ad58 100644 --- a/src/KOKKOS/atom_vec_molecular_kokkos.cpp +++ b/src/KOKKOS/atom_vec_molecular_kokkos.cpp @@ -217,6 +217,47 @@ void AtomVecMolecularKokkos::grow_pointers() h_improper_atom4 = atomKK->k_improper_atom4.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecMolecularKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_molecule); + Sorter.sort(LMPDeviceType(), d_num_bond); + Sorter.sort(LMPDeviceType(), d_bond_type); + Sorter.sort(LMPDeviceType(), d_bond_atom); + Sorter.sort(LMPDeviceType(), d_nspecial); + Sorter.sort(LMPDeviceType(), d_special); + Sorter.sort(LMPDeviceType(), d_num_angle); + Sorter.sort(LMPDeviceType(), d_angle_type); + Sorter.sort(LMPDeviceType(), d_angle_atom1); + Sorter.sort(LMPDeviceType(), d_angle_atom2); + Sorter.sort(LMPDeviceType(), d_angle_atom3); + Sorter.sort(LMPDeviceType(), d_num_dihedral); + Sorter.sort(LMPDeviceType(), d_dihedral_type); + Sorter.sort(LMPDeviceType(), d_dihedral_atom1); + Sorter.sort(LMPDeviceType(), d_dihedral_atom2); + Sorter.sort(LMPDeviceType(), d_dihedral_atom3); + Sorter.sort(LMPDeviceType(), d_dihedral_atom4); + Sorter.sort(LMPDeviceType(), d_num_improper); + Sorter.sort(LMPDeviceType(), d_improper_type); + Sorter.sort(LMPDeviceType(), d_improper_atom1); + Sorter.sort(LMPDeviceType(), d_improper_atom2); + Sorter.sort(LMPDeviceType(), d_improper_atom3); + Sorter.sort(LMPDeviceType(), d_improper_atom4); + + atomKK->modified(Device, ALL_MASK & ~F_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_molecular_kokkos.h b/src/KOKKOS/atom_vec_molecular_kokkos.h index af8a2258e1..eb976e9073 100644 --- a/src/KOKKOS/atom_vec_molecular_kokkos.h +++ b/src/KOKKOS/atom_vec_molecular_kokkos.h @@ -34,6 +34,7 @@ class AtomVecMolecularKokkos : public AtomVecKokkos, public AtomVecMolecular { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, const int & iswap, const DAT::tdual_xfloat_2d &buf, diff --git a/src/KOKKOS/atom_vec_sphere_kokkos.cpp b/src/KOKKOS/atom_vec_sphere_kokkos.cpp index 40af56489b..a9b64fc835 100644 --- a/src/KOKKOS/atom_vec_sphere_kokkos.cpp +++ b/src/KOKKOS/atom_vec_sphere_kokkos.cpp @@ -123,6 +123,27 @@ void AtomVecSphereKokkos::grow_pointers() h_torque = atomKK->k_torque.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecSphereKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, ALL_MASK & ~F_MASK & ~TORQUE_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_radius); + Sorter.sort(LMPDeviceType(), d_rmass); + Sorter.sort(LMPDeviceType(), d_omega); + + atomKK->modified(Device, ALL_MASK & ~F_MASK & ~TORQUE_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_sphere_kokkos.h b/src/KOKKOS/atom_vec_sphere_kokkos.h index 32357fb600..34529320d9 100644 --- a/src/KOKKOS/atom_vec_sphere_kokkos.h +++ b/src/KOKKOS/atom_vec_sphere_kokkos.h @@ -35,6 +35,7 @@ class AtomVecSphereKokkos : public AtomVecKokkos, public AtomVecSphere { void grow(int) override; void grow_pointers() override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_comm_kokkos(const int &n, const DAT::tdual_int_2d &k_sendlist, const int & iswap, diff --git a/src/KOKKOS/atom_vec_spin_kokkos.cpp b/src/KOKKOS/atom_vec_spin_kokkos.cpp index 662072ead9..ac1c5a9294 100644 --- a/src/KOKKOS/atom_vec_spin_kokkos.cpp +++ b/src/KOKKOS/atom_vec_spin_kokkos.cpp @@ -129,6 +129,25 @@ void AtomVecSpinKokkos::grow_pointers() h_fm_long = atomKK->k_fm_long.h_view; } +/* ---------------------------------------------------------------------- + sort atom arrays on device +------------------------------------------------------------------------- */ + +void AtomVecSpinKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + atomKK->sync(Device, TAG_MASK|TYPE_MASK|MASK_MASK|IMAGE_MASK|X_MASK|V_MASK|SP_MASK); + + Sorter.sort(LMPDeviceType(), d_tag); + Sorter.sort(LMPDeviceType(), d_type); + Sorter.sort(LMPDeviceType(), d_mask); + Sorter.sort(LMPDeviceType(), d_image); + Sorter.sort(LMPDeviceType(), d_x); + Sorter.sort(LMPDeviceType(), d_v); + Sorter.sort(LMPDeviceType(), d_sp; + + atomKK->modified(Device, TAG_MASK|TYPE_MASK|MASK_MASK|IMAGE_MASK|X_MASK|V_MASK|SP_MASK); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/atom_vec_spin_kokkos.h b/src/KOKKOS/atom_vec_spin_kokkos.h index 6a48d195a2..d14d01fb62 100644 --- a/src/KOKKOS/atom_vec_spin_kokkos.h +++ b/src/KOKKOS/atom_vec_spin_kokkos.h @@ -34,7 +34,7 @@ class AtomVecSpinKokkos : public AtomVecKokkos, public AtomVecSpin { AtomVecSpinKokkos(class LAMMPS *); void grow(int) override; void grow_pointers() override; - // input lists to be checked + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_border_kokkos(int n, DAT::tdual_int_2d k_sendlist, DAT::tdual_xfloat_2d buf,int iswap, int pbc_flag, int *pbc, ExecutionSpace space) override; diff --git a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp index 3a2447461e..d49d60d6ce 100644 --- a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp @@ -49,6 +49,7 @@ FixACKS2ReaxFFKokkos(LAMMPS *lmp, int narg, char **arg) : FixACKS2ReaxFF(lmp, narg, arg) { kokkosable = 1; + sort_device = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; @@ -1912,6 +1913,25 @@ void FixACKS2ReaxFFKokkos::copy_arrays(int i, int j, int delflag) k_s_hist_X.template modify(); } +/* ---------------------------------------------------------------------- + sort local atom-based arrays +------------------------------------------------------------------------- */ + +template +void FixACKS2ReaxFFKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + // always sort on the device + + k_s_hist.sync_device(); + k_s_hist_X.sync_device(); + + Sorter.sort(LMPDeviceType(), k_s_hist.d_view); + Sorter.sort(LMPDeviceType(), k_s_hist_X.d_view); + + k_s_hist.modify_device(); + k_s_hist_X.modify_device(); +} + /* ---------------------------------------------------------------------- pack values in local atom-based array for exchange with another proc ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_acks2_reaxff_kokkos.h b/src/KOKKOS/fix_acks2_reaxff_kokkos.h index 664f4dcb81..f6f787523d 100644 --- a/src/KOKKOS/fix_acks2_reaxff_kokkos.h +++ b/src/KOKKOS/fix_acks2_reaxff_kokkos.h @@ -27,6 +27,7 @@ FixStyle(acks2/reax/kk/host,FixACKS2ReaxFFKokkos); #include "fix_acks2_reaxff.h" #include "kokkos_type.h" +#include "kokkos_base.h" #include "neigh_list.h" #include "neigh_list_kokkos.h" @@ -57,7 +58,7 @@ struct TagACKS2ZeroQGhosts{}; struct TagACKS2CalculateQ{}; template -class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF { +class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF, public KokkosBase { public: typedef DeviceType device_type; typedef double value_type; @@ -252,6 +253,7 @@ class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF { void grow_arrays(int); void copy_arrays(int, int, int); + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *); int unpack_exchange(int, double *); void get_chi_field(); diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index b7305644c9..6b8ffbb2ab 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -44,6 +44,7 @@ FixLangevinKokkos::FixLangevinKokkos(LAMMPS *lmp, int narg, char **a FixLangevin(lmp, narg, arg),rand_pool(seed + comm->me) { kokkosable = 1; + sort_device = 1; atomKK = (AtomKokkos *) atom; int ntypes = atomKK->ntypes; @@ -889,6 +890,25 @@ void FixLangevinKokkos::copy_arrays(int i, int j, int /*delflag*/) } +/* ---------------------------------------------------------------------- + sort local atom-based arrays +------------------------------------------------------------------------- */ + +template +void FixLangevinKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + // always sort on the device + + k_franprev.sync_device(); + k_lv.sync_device(); + + Sorter.sort(LMPDeviceType(), k_franprev.d_view); + Sorter.sort(LMPDeviceType(), k_lv.d_view); + + k_franprev.modify_device(); + k_lv.modify_device(); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/fix_langevin_kokkos.h b/src/KOKKOS/fix_langevin_kokkos.h index f7142e6286..3f23f57cc3 100644 --- a/src/KOKKOS/fix_langevin_kokkos.h +++ b/src/KOKKOS/fix_langevin_kokkos.h @@ -25,6 +25,7 @@ FixStyle(langevin/kk/host,FixLangevinKokkos); #include "fix_langevin.h" #include "kokkos_type.h" +#include "kokkos_base.h" #include "Kokkos_Random.hpp" #include "comm_kokkos.h" @@ -61,7 +62,7 @@ namespace LAMMPS_NS { template struct FixLangevinKokkosTallyEnergyFunctor; template - class FixLangevinKokkos : public FixLangevin { + class FixLangevinKokkos : public FixLangevin, public KokkosBase { public: FixLangevinKokkos(class LAMMPS *, int, char **); ~FixLangevinKokkos() override; @@ -73,6 +74,7 @@ namespace LAMMPS_NS { void reset_dt() override; void grow_arrays(int) override; void copy_arrays(int i, int j, int delflag) override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; double compute_scalar() override; void end_of_step() override; diff --git a/src/KOKKOS/fix_minimize_kokkos.cpp b/src/KOKKOS/fix_minimize_kokkos.cpp index 07c78e86a3..5f4b62d67d 100644 --- a/src/KOKKOS/fix_minimize_kokkos.cpp +++ b/src/KOKKOS/fix_minimize_kokkos.cpp @@ -27,6 +27,8 @@ using namespace FixConst; FixMinimizeKokkos::FixMinimizeKokkos(LAMMPS *lmp, int narg, char **arg) : FixMinimize(lmp, narg, arg) { + kokkosable = 1; + sort_device = 1; atomKK = (AtomKokkos *) atom; } @@ -217,6 +219,21 @@ void FixMinimizeKokkos::copy_arrays(int i, int j, int /*delflag*/) k_vectors.modify(); } +/* ---------------------------------------------------------------------- + sort local atom-based arrays +------------------------------------------------------------------------- */ + +void FixMinimizeKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + // always sort on the device + + k_vectors.sync_device(); + + Sorter.sort(LMPDeviceType(), k_vectors.d_view); + + k_vectors.modify_device(); +} + /* ---------------------------------------------------------------------- pack values in local atom-based arrays for exchange with another proc ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_minimize_kokkos.h b/src/KOKKOS/fix_minimize_kokkos.h index e84cbd1ec2..121711b4e4 100644 --- a/src/KOKKOS/fix_minimize_kokkos.h +++ b/src/KOKKOS/fix_minimize_kokkos.h @@ -25,10 +25,11 @@ FixStyle(MINIMIZE/kk/host,FixMinimizeKokkos); #include "fix_minimize.h" #include "kokkos_type.h" +#include "kokkos_base.h" namespace LAMMPS_NS { -class FixMinimizeKokkos : public FixMinimize { +class FixMinimizeKokkos : public FixMinimize, public KokkosBase { friend class MinLineSearchKokkos; public: @@ -38,6 +39,7 @@ class FixMinimizeKokkos : public FixMinimize { void grow_arrays(int) override; void copy_arrays(int, int, int) override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index 198ab555f3..ba189e38d9 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -32,7 +32,7 @@ FixNeighHistoryKokkos::FixNeighHistoryKokkos(LAMMPS *lmp, int narg, FixNeighHistory(lmp, narg, arg) { kokkosable = 1; - exchange_comm_device = 1; + exchange_comm_device = sort_device = 1; atomKK = (AtomKokkos *)atom; execution_space = ExecutionSpaceFromDevice::space; @@ -325,6 +325,28 @@ void FixNeighHistoryKokkos::copy_arrays(int i, int j, int /*delflag* k_valuepartner.modify_host(); } +/* ---------------------------------------------------------------------- + sort local atom-based arrays +------------------------------------------------------------------------- */ + +template +void FixNeighHistoryKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + // always sort on the device + + k_npartner.sync_device(); + k_partner.sync_device(); + k_valuepartner.sync_device(); + + Sorter.sort(LMPDeviceType(), k_npartner.d_view); + Sorter.sort(LMPDeviceType(), k_partner.d_view); + Sorter.sort(LMPDeviceType(), k_valuepartner.d_view); + + k_npartner.modify_device(); + k_partner.modify_device(); + k_valuepartner.modify_device(); +} + /* ---------------------------------------------------------------------- pack values in local atom-based array for exchange with another proc ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_neigh_history_kokkos.h b/src/KOKKOS/fix_neigh_history_kokkos.h index 6f29c817b8..9c07a953c4 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.h +++ b/src/KOKKOS/fix_neigh_history_kokkos.h @@ -48,6 +48,7 @@ class FixNeighHistoryKokkos : public FixNeighHistory, public KokkosBase { void post_neighbor() override; void grow_arrays(int) override; void copy_arrays(int, int, int) override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; double memory_usage() override; diff --git a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp index c1695843a7..e003f4b4f9 100644 --- a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp @@ -58,7 +58,7 @@ FixQEqReaxFFKokkos(LAMMPS *lmp, int narg, char **arg) : { kokkosable = 1; comm_forward = comm_reverse = 2; // fused - forward_comm_device = exchange_comm_device = 1; + forward_comm_device = exchange_comm_device = sort_device = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; @@ -1338,6 +1338,25 @@ void FixQEqReaxFFKokkos::copy_arrays(int i, int j, int /*delflag*/) k_t_hist.template modify(); } +/* ---------------------------------------------------------------------- + sort local atom-based arrays +------------------------------------------------------------------------- */ + +template +void FixQEqReaxFFKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + // always sort on the device + + k_s_hist.sync_device(); + k_t_hist.sync_device(); + + Sorter.sort(LMPDeviceType(), k_s_hist.d_view); + Sorter.sort(LMPDeviceType(), k_t_hist.d_view); + + k_s_hist.modify_device(); + k_t_hist.modify_device(); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/fix_qeq_reaxff_kokkos.h b/src/KOKKOS/fix_qeq_reaxff_kokkos.h index 29faefe56b..9bc38b0492 100644 --- a/src/KOKKOS/fix_qeq_reaxff_kokkos.h +++ b/src/KOKKOS/fix_qeq_reaxff_kokkos.h @@ -280,6 +280,7 @@ class FixQEqReaxFFKokkos : public FixQEqReaxFF, public KokkosBase { void grow_arrays(int) override; void copy_arrays(int, int, int) override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; void get_chi_field() override; diff --git a/src/KOKKOS/fix_shake_kokkos.cpp b/src/KOKKOS/fix_shake_kokkos.cpp index b00195e5fd..465536d63f 100644 --- a/src/KOKKOS/fix_shake_kokkos.cpp +++ b/src/KOKKOS/fix_shake_kokkos.cpp @@ -53,7 +53,7 @@ FixShakeKokkos::FixShakeKokkos(LAMMPS *lmp, int narg, char **arg) : FixShake(lmp, narg, arg) { kokkosable = 1; - forward_comm_device = exchange_comm_device = 1; + forward_comm_device = exchange_comm_device = sort_device = 1; maxexchange = 9; atomKK = (AtomKokkos *)atom; execution_space = ExecutionSpaceFromDevice::space; @@ -1484,6 +1484,28 @@ void FixShakeKokkos::copy_arrays(int i, int j, int delflag) k_shake_type.modify_host(); } +/* ---------------------------------------------------------------------- + sort local atom-based arrays +------------------------------------------------------------------------- */ + +template +void FixShakeKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + // always sort on the device + + k_shake_flag.sync_device(); + k_shake_atom.sync_device(); + k_shake_type.sync_device(); + + Sorter.sort(LMPDeviceType(), k_shake_flag.d_view); + Sorter.sort(LMPDeviceType(), k_shake_atom.d_view); + Sorter.sort(LMPDeviceType(), k_shake_type.d_view); + + k_shake_flag.modify_device(); + k_shake_atom.modify_device(); + k_shake_type.modify_device(); +} + /* ---------------------------------------------------------------------- initialize one atom's array values, called when atom is created ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_shake_kokkos.h b/src/KOKKOS/fix_shake_kokkos.h index 650ad52287..185e69ce86 100644 --- a/src/KOKKOS/fix_shake_kokkos.h +++ b/src/KOKKOS/fix_shake_kokkos.h @@ -61,6 +61,7 @@ class FixShakeKokkos : public FixShake, public KokkosBase { void grow_arrays(int) override; void copy_arrays(int, int, int) override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; void set_arrays(int) override; void update_arrays(int, int) override; void set_molecule(int, tagint, int, double *, double *, double *) override; diff --git a/src/KOKKOS/fix_wall_gran_kokkos.cpp b/src/KOKKOS/fix_wall_gran_kokkos.cpp index 1569065bbe..0499477649 100644 --- a/src/KOKKOS/fix_wall_gran_kokkos.cpp +++ b/src/KOKKOS/fix_wall_gran_kokkos.cpp @@ -32,7 +32,7 @@ FixWallGranKokkos::FixWallGranKokkos(LAMMPS *lmp, int narg, char **a FixWallGranOld(lmp, narg, arg) { kokkosable = 1; - exchange_comm_device = 1; + exchange_comm_device = sort_device = 1; maxexchange = size_history; atomKK = (AtomKokkos *)atom; execution_space = ExecutionSpaceFromDevice::space; @@ -313,6 +313,22 @@ void FixWallGranKokkos::copy_arrays(int i, int j, int delflag) } } +/* ---------------------------------------------------------------------- + sort local atom-based arrays +------------------------------------------------------------------------- */ + +template +void FixWallGranKokkos::sort_kokkos(Kokkos::BinSort &Sorter) +{ + // always sort on the device + + k_history_one.sync_device(); + + Sorter.sort(LMPDeviceType(), k_history_one.d_view); + + k_history_one.modify_device(); +} + /* ---------------------------------------------------------------------- */ template diff --git a/src/KOKKOS/fix_wall_gran_kokkos.h b/src/KOKKOS/fix_wall_gran_kokkos.h index 4d80528fb8..c7d566ec72 100644 --- a/src/KOKKOS/fix_wall_gran_kokkos.h +++ b/src/KOKKOS/fix_wall_gran_kokkos.h @@ -47,6 +47,7 @@ class FixWallGranKokkos : public FixWallGranOld, public KokkosBase { void post_force(int) override; void grow_arrays(int) override; void copy_arrays(int, int, int) override; + void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 8b45c786e5..91ea6d37ac 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -93,6 +93,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) reverse_pair_comm_changed = 0; forward_fix_comm_changed = 0; reverse_comm_changed = 0; + sort_changed = 0; delete memory; memory = new MemoryKokkos(lmp); @@ -250,6 +251,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) exchange_comm_classic = forward_comm_classic = reverse_comm_classic = 0; forward_pair_comm_classic = reverse_pair_comm_classic = forward_fix_comm_classic = 0; + sort_classic = 0; exchange_comm_on_host = forward_comm_on_host = reverse_comm_on_host = 0; } else { @@ -264,6 +266,7 @@ KokkosLMP::KokkosLMP(LAMMPS *lmp, int narg, char **arg) : Pointers(lmp) exchange_comm_classic = forward_comm_classic = reverse_comm_classic = 1; forward_pair_comm_classic = reverse_pair_comm_classic = forward_fix_comm_classic = 1; + sort_classic = 1; exchange_comm_on_host = forward_comm_on_host = reverse_comm_on_host = 0; } @@ -478,6 +481,14 @@ void KokkosLMP::accelerator(int narg, char **arg) } else error->all(FLERR,"Illegal package kokkos command"); reverse_comm_changed = 0; iarg += 2; + } else if (strcmp(arg[iarg],"sort") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); + else if (strcmp(arg[iarg+1],"no") == 0) sort_classic = 1; + else if (strcmp(arg[iarg+1],"host") == 0) sort_classic = 1; + else if (strcmp(arg[iarg+1],"device") == 0) sort_classic = 0; + else error->all(FLERR,"Illegal package kokkos command"); + sort_changed = 0; + iarg += 2; } else if ((strcmp(arg[iarg],"gpu/aware") == 0) || (strcmp(arg[iarg],"cuda/aware") == 0)) { if (iarg+2 > narg) error->all(FLERR,"Illegal package kokkos command"); @@ -533,6 +544,13 @@ void KokkosLMP::accelerator(int narg, char **arg) } } + if (lmp->pair_only_flag) { + if (sort_classic == 0) { + sort_classic = 1; + sort_changed = 1; + } + } + // if "gpu/aware on" and "pair/only off", and comm flags were changed previously, change them back if (gpu_aware_flag && !lmp->pair_only_flag) { @@ -562,6 +580,13 @@ void KokkosLMP::accelerator(int narg, char **arg) } } + if (lmp->pair_only_flag) { + if (sort_changed) { + sort_classic = 0; + sort_changed = 0; + } + } + #endif // set newton flags diff --git a/src/KOKKOS/kokkos.h b/src/KOKKOS/kokkos.h index 08b6730e50..adfc1fc646 100644 --- a/src/KOKKOS/kokkos.h +++ b/src/KOKKOS/kokkos.h @@ -33,6 +33,7 @@ class KokkosLMP : protected Pointers { int reverse_pair_comm_classic; int forward_fix_comm_classic; int reverse_comm_classic; + int sort_classic; int exchange_comm_on_host; int forward_comm_on_host; int reverse_comm_on_host; @@ -42,6 +43,7 @@ class KokkosLMP : protected Pointers { int reverse_pair_comm_changed; int forward_fix_comm_changed; int reverse_comm_changed; + int sort_changed; int nthreads,ngpus; int auto_sync; int gpu_aware_flag; diff --git a/src/KOKKOS/kokkos_base.h b/src/KOKKOS/kokkos_base.h index 463b271269..b78c88eacd 100644 --- a/src/KOKKOS/kokkos_base.h +++ b/src/KOKKOS/kokkos_base.h @@ -17,6 +17,8 @@ #include "kokkos_type.h" +#include + namespace LAMMPS_NS { class KokkosBase { @@ -51,6 +53,11 @@ class KokkosBase { virtual void unpack_exchange_kokkos(DAT::tdual_xfloat_2d & /*k_buf*/, DAT::tdual_int_1d & /*indices*/, int /*nrecv*/, ExecutionSpace /*space*/) {} + + using KeyViewType = DAT::t_x_array; + using BinOp = Kokkos::BinOp3DReverse; + virtual void + sort_kokkos(Kokkos::BinSort & /*Sorter*/) {} }; } diff --git a/src/atom.cpp b/src/atom.cpp index 29e1bb6305..00dc0369b0 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -33,6 +33,7 @@ #include "tokenizer.h" #include "update.h" #include "variable.h" +#include "accelerator_kokkos.h" #include "library.h" @@ -2356,6 +2357,10 @@ void Atom::setup_sort_bins() return; } + if (userbinsize == 0 && lmp->kokkos && lmp->kokkos->ngpus > 0) { + binsize = neighbor->cutneighmax; + } + #ifdef LMP_GPU if (userbinsize == 0.0) { auto ifix = dynamic_cast(modify->get_fix_by_id("package_gpu")); diff --git a/src/atom.h b/src/atom.h index d2e8030108..810a2829ed 100644 --- a/src/atom.h +++ b/src/atom.h @@ -312,7 +312,7 @@ class Atom : protected Pointers { void create_avec(const std::string &, int, char **, int); virtual AtomVec *new_avec(const std::string &, int, int &); - void init(); + virtual void init(); void setup(); std::string get_style(); diff --git a/src/fix.cpp b/src/fix.cpp index 1d41ad3943..f0cc8a20ea 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -109,7 +109,7 @@ Fix::Fix(LAMMPS *lmp, int /*narg*/, char **arg) : datamask_modify = ALL_MASK; kokkosable = 0; - forward_comm_device = exchange_comm_device = 0; + forward_comm_device = exchange_comm_device = sort_device = 0; copymode = 0; } diff --git a/src/fix.h b/src/fix.h index b47cfb2f4a..334f61ff2b 100644 --- a/src/fix.h +++ b/src/fix.h @@ -132,6 +132,7 @@ class Fix : protected Pointers { int kokkosable; // 1 if Kokkos fix int forward_comm_device; // 1 if forward comm on Device int exchange_comm_device; // 1 if exchange comm on Device + int sort_device; // 1 if sort on Device ExecutionSpace execution_space; unsigned int datamask_read, datamask_modify; From f5e55bb6d95a3a767931926f96453edfb4035a09 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 19 Apr 2023 12:56:47 -0600 Subject: [PATCH 063/448] Need to set var --- src/KOKKOS/atom_kokkos.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 9bbbb2acc3..cb932a79ed 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -170,6 +170,7 @@ void AtomKokkos::sort() error->warning(FLERR,"Fix with atom-based arrays not compatible with Kokkos sorting on device, " "switching to classic host sorting"); } + sort_classic = true; } } From cf2e55f4acce00e12f7ee460c91786ba36277125 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 19 Apr 2023 13:16:38 -0600 Subject: [PATCH 064/448] Update docs --- doc/src/atom_modify.rst | 4 +++- doc/src/package.rst | 28 +++++++++++++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/doc/src/atom_modify.rst b/doc/src/atom_modify.rst index 9049a24fde..f845c15b24 100644 --- a/doc/src/atom_modify.rst +++ b/doc/src/atom_modify.rst @@ -176,7 +176,9 @@ larger than 1 million, otherwise the default is hash. By default, a "first" group is not defined. By default, sorting is enabled with a frequency of 1000 and a binsize of 0.0, which means the neighbor cutoff will be used to set the bin size. If no neighbor cutoff is -defined, sorting will be turned off. +defined, sorting will be turned off. When running with the KOKKOS +package on one or more GPUs, the default binsize for sorting is twice +the CPU default. ---------- diff --git a/doc/src/package.rst b/doc/src/package.rst index 76bf20a97f..14d978c3c9 100644 --- a/doc/src/package.rst +++ b/doc/src/package.rst @@ -71,7 +71,7 @@ Syntax *no_affinity* values = none *kokkos* args = keyword value ... zero or more keyword/value pairs may be appended - keywords = *neigh* or *neigh/qeq* or *neigh/thread* or *neigh/transpose* or *newton* or *binsize* or *comm* or *comm/exchange* or *comm/forward* or *comm/pair/forward* or *comm/fix/forward* or *comm/reverse* or *comm/pair/reverse* or *gpu/aware* or *pair/only* + keywords = *neigh* or *neigh/qeq* or *neigh/thread* or *neigh/transpose* or *newton* or *binsize* or *comm* or *comm/exchange* or *comm/forward* or *comm/pair/forward* or *comm/fix/forward* or *comm/reverse* or *comm/pair/reverse* or *sort* or *gpu/aware* or *pair/only* *neigh* value = *full* or *half* full = full neighbor list half = half neighbor list built in thread-safe manner @@ -102,6 +102,9 @@ Syntax *comm/pair/reverse* value = *no* or *device* *no* = perform communication pack/unpack in non-KOKKOS mode *device* = perform pack/unpack on device (e.g. on GPU) + *sort* value = *no* or *device* + *no* = perform atom sorting in non-KOKKOS mode + *device* = perform atom sorting on device (e.g. on GPU) *gpu/aware* = *off* or *on* *off* = do not use GPU-aware MPI *on* = use GPU-aware MPI (default) @@ -554,6 +557,17 @@ pack/unpack communicated data. When running small systems on a GPU, performing the exchange pack/unpack on the host CPU can give speedup since it reduces the number of CUDA kernel launches. +The *sort* keyword determines whether the host or device performs atom +sorting, see the :doc:`atom_modify sort ` command. The +value options for the *sort* keyword are *no* or *device* similar to the +*comm* keywords above. If a value of *host* is used it will be +automatically be changed to *no* since the *sort* keyword doesn't +support *host* mode. The value of *no* will also always be used when +running on the CPU, i.e. setting the value to *device* will have no +effect if the simulation is running on the CPU. Not all fix styles with +extra atom data support *device* mode and in that case a warning will be +given and atom sorting will run in *no* mode instead. + The *gpu/aware* keyword chooses whether GPU-aware MPI will be used. When this keyword is set to *on*, buffers in GPU memory are passed directly through MPI send/receive calls. This reduces overhead of first copying @@ -705,12 +719,12 @@ script or via the "-pk intel" :doc:`command-line switch `. For the KOKKOS package, the option defaults for GPUs are neigh = full, neigh/qeq = full, newton = off, binsize for GPUs = 2x LAMMPS default -value, comm = device, neigh/transpose = off, gpu/aware = on. When -LAMMPS can safely detect that GPU-aware MPI is not available, the -default value of gpu/aware becomes "off". For CPUs or Xeon Phis, the -option defaults are neigh = half, neigh/qeq = half, newton = on, -binsize = 0.0, and comm = no. The option neigh/thread = on when there -are 16K atoms or less on an MPI rank, otherwise it is "off". These +value, comm = device, sort = device, neigh/transpose = off, gpu/aware = +on. When LAMMPS can safely detect that GPU-aware MPI is not available, +the default value of gpu/aware becomes "off". For CPUs or Xeon Phis, the +option defaults are neigh = half, neigh/qeq = half, newton = on, binsize += 0.0, comm = no, and sort = no. The option neigh/thread = on when +there are 16K atoms or less on an MPI rank, otherwise it is "off". These settings are made automatically by the required "-k on" :doc:`command-line switch `. You can change them by using the package kokkos command in your input script or via the :doc:`-pk From b58368dc341cd706a7e543ca8ed111416da8e9c6 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 19 Apr 2023 13:31:37 -0600 Subject: [PATCH 065/448] whitespace --- src/KOKKOS/fix_acks2_reaxff_kokkos.cpp | 10 +++++----- src/KOKKOS/fix_langevin_kokkos.cpp | 2 +- src/KOKKOS/fix_minimize_kokkos.cpp | 10 +++++----- src/KOKKOS/fix_neigh_history_kokkos.cpp | 2 +- src/KOKKOS/fix_qeq_reaxff_kokkos.cpp | 2 +- src/KOKKOS/fix_shake_kokkos.cpp | 2 +- src/KOKKOS/fix_wall_gran_kokkos.cpp | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp index d49d60d6ce..1280a4d9a7 100644 --- a/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_acks2_reaxff_kokkos.cpp @@ -1919,15 +1919,15 @@ void FixACKS2ReaxFFKokkos::copy_arrays(int i, int j, int delflag) template void FixACKS2ReaxFFKokkos::sort_kokkos(Kokkos::BinSort &Sorter) -{ - // always sort on the device - +{ + // always sort on the device + k_s_hist.sync_device(); k_s_hist_X.sync_device(); - + Sorter.sort(LMPDeviceType(), k_s_hist.d_view); Sorter.sort(LMPDeviceType(), k_s_hist_X.d_view); - + k_s_hist.modify_device(); k_s_hist_X.modify_device(); } diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index 6b8ffbb2ab..96fa58f601 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -897,7 +897,7 @@ void FixLangevinKokkos::copy_arrays(int i, int j, int /*delflag*/) template void FixLangevinKokkos::sort_kokkos(Kokkos::BinSort &Sorter) { - // always sort on the device + // always sort on the device k_franprev.sync_device(); k_lv.sync_device(); diff --git a/src/KOKKOS/fix_minimize_kokkos.cpp b/src/KOKKOS/fix_minimize_kokkos.cpp index 5f4b62d67d..90ef0f4525 100644 --- a/src/KOKKOS/fix_minimize_kokkos.cpp +++ b/src/KOKKOS/fix_minimize_kokkos.cpp @@ -224,13 +224,13 @@ void FixMinimizeKokkos::copy_arrays(int i, int j, int /*delflag*/) ------------------------------------------------------------------------- */ void FixMinimizeKokkos::sort_kokkos(Kokkos::BinSort &Sorter) -{ - // always sort on the device - +{ + // always sort on the device + k_vectors.sync_device(); - + Sorter.sort(LMPDeviceType(), k_vectors.d_view); - + k_vectors.modify_device(); } diff --git a/src/KOKKOS/fix_neigh_history_kokkos.cpp b/src/KOKKOS/fix_neigh_history_kokkos.cpp index ba189e38d9..b4a852ba70 100644 --- a/src/KOKKOS/fix_neigh_history_kokkos.cpp +++ b/src/KOKKOS/fix_neigh_history_kokkos.cpp @@ -332,7 +332,7 @@ void FixNeighHistoryKokkos::copy_arrays(int i, int j, int /*delflag* template void FixNeighHistoryKokkos::sort_kokkos(Kokkos::BinSort &Sorter) { - // always sort on the device + // always sort on the device k_npartner.sync_device(); k_partner.sync_device(); diff --git a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp index e003f4b4f9..6517036fa0 100644 --- a/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reaxff_kokkos.cpp @@ -1345,7 +1345,7 @@ void FixQEqReaxFFKokkos::copy_arrays(int i, int j, int /*delflag*/) template void FixQEqReaxFFKokkos::sort_kokkos(Kokkos::BinSort &Sorter) { - // always sort on the device + // always sort on the device k_s_hist.sync_device(); k_t_hist.sync_device(); diff --git a/src/KOKKOS/fix_shake_kokkos.cpp b/src/KOKKOS/fix_shake_kokkos.cpp index 465536d63f..1ea3ed1c5a 100644 --- a/src/KOKKOS/fix_shake_kokkos.cpp +++ b/src/KOKKOS/fix_shake_kokkos.cpp @@ -1491,7 +1491,7 @@ void FixShakeKokkos::copy_arrays(int i, int j, int delflag) template void FixShakeKokkos::sort_kokkos(Kokkos::BinSort &Sorter) { - // always sort on the device + // always sort on the device k_shake_flag.sync_device(); k_shake_atom.sync_device(); diff --git a/src/KOKKOS/fix_wall_gran_kokkos.cpp b/src/KOKKOS/fix_wall_gran_kokkos.cpp index 0499477649..f870b0f240 100644 --- a/src/KOKKOS/fix_wall_gran_kokkos.cpp +++ b/src/KOKKOS/fix_wall_gran_kokkos.cpp @@ -320,7 +320,7 @@ void FixWallGranKokkos::copy_arrays(int i, int j, int delflag) template void FixWallGranKokkos::sort_kokkos(Kokkos::BinSort &Sorter) { - // always sort on the device + // always sort on the device k_history_one.sync_device(); From 28d31dedc8fcb50902269f2a6593dc760ec7a567 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 19 Apr 2023 13:50:08 -0600 Subject: [PATCH 066/448] Add missing BinOp struct --- src/KOKKOS/atom_kokkos.cpp | 2 +- src/KOKKOS/atom_vec_kokkos.h | 2 +- src/KOKKOS/kokkos_base.h | 2 +- src/KOKKOS/kokkos_type.h | 58 ++++++++++++++++++++++++++++++++++++ 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index cb932a79ed..bda046c459 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -205,7 +205,7 @@ void AtomKokkos::sort_device() max_bins[2] = nbinz; using KeyViewType = DAT::t_x_array; - using BinOp = Kokkos::BinOp3DReverse; + using BinOp = BinOp3DLAMMPS; BinOp binner(max_bins, bboxlo, bboxhi); Kokkos::BinSort Sorter(d_x, 0, nlocal, binner, false); Sorter.create_permute_vector(LMPDeviceType()); diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index ef6a3fcbc8..310f1f4d48 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -41,7 +41,7 @@ class AtomVecKokkos : virtual public AtomVec { ~AtomVecKokkos() override; using KeyViewType = DAT::t_x_array; - using BinOp = Kokkos::BinOp3DReverse; + using BinOp = BinOp3DLAMMPS; virtual void sort_kokkos(Kokkos::BinSort &Sorter) = 0; diff --git a/src/KOKKOS/kokkos_base.h b/src/KOKKOS/kokkos_base.h index b78c88eacd..7d9ecb5d80 100644 --- a/src/KOKKOS/kokkos_base.h +++ b/src/KOKKOS/kokkos_base.h @@ -55,7 +55,7 @@ class KokkosBase { ExecutionSpace /*space*/) {} using KeyViewType = DAT::t_x_array; - using BinOp = Kokkos::BinOp3DReverse; + using BinOp = BinOp3DLAMMPS; virtual void sort_kokkos(Kokkos::BinSort & /*Sorter*/) {} }; diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index 69ebc91fec..555c7fa9ae 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -473,6 +473,64 @@ struct alignas(2*sizeof(F_FLOAT)) s_FLOAT2 { }; typedef struct s_FLOAT2 F_FLOAT2; +template +struct BinOp3DLAMMPS { + int max_bins_[3] = {}; + double mul_[3] = {}; + double min_[3] = {}; + + BinOp3DLAMMPS() = default; + + BinOp3DLAMMPS(int max_bins__[], typename KeyViewType::const_value_type min[], + typename KeyViewType::const_value_type max[]) { + max_bins_[0] = max_bins__[0]; + max_bins_[1] = max_bins__[1]; + max_bins_[2] = max_bins__[2]; + mul_[0] = static_cast(max_bins__[0]) / + (static_cast(max[0]) - static_cast(min[0])); + mul_[1] = static_cast(max_bins__[1]) / + (static_cast(max[1]) - static_cast(min[1])); + mul_[2] = static_cast(max_bins__[2]) / + (static_cast(max[2]) - static_cast(min[2])); + min_[0] = static_cast(min[0]); + min_[1] = static_cast(min[1]); + min_[2] = static_cast(min[2]); + } + + template + KOKKOS_INLINE_FUNCTION int bin(ViewType& keys, const int& i) const { + int ix = static_cast ((keys(i, 0) - min_[0]) * mul_[0]); + int iy = static_cast ((keys(i, 1) - min_[1]) * mul_[1]); + int iz = static_cast ((keys(i, 2) - min_[2]) * mul_[2]); + ix = MAX(ix,0); + iy = MAX(iy,0); + iz = MAX(iz,0); + ix = MIN(ix,max_bins_[0]-1); + iy = MIN(iy,max_bins_[1]-1); + iz = MIN(iz,max_bins_[2]-1); + const int ibin = iz*max_bins_[1]*max_bins_[0] + iy*max_bins_[0] + ix; + return ibin; + } + + KOKKOS_INLINE_FUNCTION + int max_bins() const { return max_bins_[0] * max_bins_[1] * max_bins_[2]; } + + template + KOKKOS_INLINE_FUNCTION bool operator()(ViewType& keys, iType1& i1, + iType2& i2) const { + if (keys(i1, 2) > keys(i2, 2)) + return true; + else if (keys(i1, 2) == keys(i2, 2)) { + if (keys(i1, 1) > keys(i2, 1)) + return true; + else if (keys(i1, 1) == keys(i2, 1)) { + if (keys(i1, 0) > keys(i2, 0)) return true; + } + } + return false; + } +}; + #ifndef PREC_POS #define PREC_POS PRECISION #endif From 313b3a69352f2786f2faa94ace4da39a8a3d0a94 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 19 Apr 2023 14:09:22 -0600 Subject: [PATCH 067/448] Fix typo --- src/KOKKOS/atom_vec_spin_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/atom_vec_spin_kokkos.cpp b/src/KOKKOS/atom_vec_spin_kokkos.cpp index ac1c5a9294..f5b8697352 100644 --- a/src/KOKKOS/atom_vec_spin_kokkos.cpp +++ b/src/KOKKOS/atom_vec_spin_kokkos.cpp @@ -143,7 +143,7 @@ void AtomVecSpinKokkos::sort_kokkos(Kokkos::BinSort &Sorter) Sorter.sort(LMPDeviceType(), d_image); Sorter.sort(LMPDeviceType(), d_x); Sorter.sort(LMPDeviceType(), d_v); - Sorter.sort(LMPDeviceType(), d_sp; + Sorter.sort(LMPDeviceType(), d_sp); atomKK->modified(Device, TAG_MASK|TYPE_MASK|MASK_MASK|IMAGE_MASK|X_MASK|V_MASK|SP_MASK); } From b511681c2b02e949ad3d36c6d20ac56868e2d043 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 20 Apr 2023 14:07:57 -0600 Subject: [PATCH 068/448] Revert binsize change --- src/atom.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/atom.cpp b/src/atom.cpp index 00dc0369b0..29e1bb6305 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -33,7 +33,6 @@ #include "tokenizer.h" #include "update.h" #include "variable.h" -#include "accelerator_kokkos.h" #include "library.h" @@ -2357,10 +2356,6 @@ void Atom::setup_sort_bins() return; } - if (userbinsize == 0 && lmp->kokkos && lmp->kokkos->ngpus > 0) { - binsize = neighbor->cutneighmax; - } - #ifdef LMP_GPU if (userbinsize == 0.0) { auto ifix = dynamic_cast(modify->get_fix_by_id("package_gpu")); From 7c7e62609760bbf133dad16e5c50aacf80761aa4 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 20 Apr 2023 14:34:00 -0600 Subject: [PATCH 069/448] Revert docs --- doc/src/atom_modify.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/doc/src/atom_modify.rst b/doc/src/atom_modify.rst index f845c15b24..9049a24fde 100644 --- a/doc/src/atom_modify.rst +++ b/doc/src/atom_modify.rst @@ -176,9 +176,7 @@ larger than 1 million, otherwise the default is hash. By default, a "first" group is not defined. By default, sorting is enabled with a frequency of 1000 and a binsize of 0.0, which means the neighbor cutoff will be used to set the bin size. If no neighbor cutoff is -defined, sorting will be turned off. When running with the KOKKOS -package on one or more GPUs, the default binsize for sorting is twice -the CPU default. +defined, sorting will be turned off. ---------- From 9b9b14e6141a2edea241121334a9365f322b0d93 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Apr 2023 14:49:57 -0400 Subject: [PATCH 070/448] add mechanism to record when Pair::ev_tally() was called and the corresponding callback functions --- src/TALLY/compute_force_tally.cpp | 16 ++++++++++++---- src/TALLY/compute_heat_flux_tally.cpp | 5 ++++- src/TALLY/compute_heat_flux_virial_tally.cpp | 10 ++++++++-- src/TALLY/compute_pe_mol_tally.cpp | 3 +++ src/TALLY/compute_pe_tally.cpp | 6 ++++++ src/TALLY/compute_stress_tally.cpp | 10 ++++++++-- src/pair.cpp | 5 +++++ src/pair.h | 3 ++- 8 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/TALLY/compute_force_tally.cpp b/src/TALLY/compute_force_tally.cpp index 8346edf928..e2243e02a7 100644 --- a/src/TALLY/compute_force_tally.cpp +++ b/src/TALLY/compute_force_tally.cpp @@ -21,6 +21,7 @@ #include "memory.h" #include "pair.h" #include "update.h" + #include using namespace LAMMPS_NS; @@ -29,10 +30,11 @@ using namespace LAMMPS_NS; ComputeForceTally::ComputeForceTally(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all(FLERR, "Illegal compute force/tally command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute force/tally", error); igroup2 = group->find(arg[3]); - if (igroup2 == -1) error->all(FLERR, "Could not find compute force/tally second group ID"); + if (igroup2 == -1) + error->all(FLERR, "Could not find compute force/tally second group ID {}", arg[3]); groupbit2 = group->bitmask[igroup2]; scalar_flag = 1; @@ -177,7 +179,10 @@ double ComputeForceTally::compute_scalar() { invoked_scalar = update->ntimestep; if ((did_setup != invoked_scalar) || (update->eflag_global != invoked_scalar)) - error->all(FLERR, "Energy was not tallied on needed timestep"); + error->all(FLERR, "Stress was not tallied on needed timestep"); + + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Stress was not tallied by pair style"); // sum accumulated forces across procs @@ -193,7 +198,10 @@ void ComputeForceTally::compute_peratom() { invoked_peratom = update->ntimestep; if ((did_setup != invoked_peratom) || (update->eflag_global != invoked_peratom)) - error->all(FLERR, "Energy was not tallied on needed timestep"); + error->all(FLERR, "Stress was not tallied on needed timestep"); + + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Stress was not tallied by pair style"); // collect contributions from ghost atoms diff --git a/src/TALLY/compute_heat_flux_tally.cpp b/src/TALLY/compute_heat_flux_tally.cpp index 2af809af22..9142f7859c 100644 --- a/src/TALLY/compute_heat_flux_tally.cpp +++ b/src/TALLY/compute_heat_flux_tally.cpp @@ -204,7 +204,10 @@ void ComputeHeatFluxTally::compute_vector() { invoked_vector = update->ntimestep; if ((did_setup != invoked_vector) || (update->eflag_global != invoked_vector)) - error->all(FLERR, "Energy was not tallied on needed timestep"); + error->all(FLERR, "Stress was not tallied on needed timestep"); + + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Stress was not tallied by pair style"); // collect contributions from ghost atoms diff --git a/src/TALLY/compute_heat_flux_virial_tally.cpp b/src/TALLY/compute_heat_flux_virial_tally.cpp index 29d409c660..ec7781b0aa 100644 --- a/src/TALLY/compute_heat_flux_virial_tally.cpp +++ b/src/TALLY/compute_heat_flux_virial_tally.cpp @@ -191,7 +191,10 @@ double ComputeHeatFluxVirialTally::compute_scalar() invoked_scalar = update->ntimestep; if ((did_setup != invoked_scalar) || (update->eflag_global != invoked_scalar)) - error->all(FLERR, "Energy was not tallied on needed timestep"); + error->all(FLERR, "Stress was not tallied on needed timestep"); + + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Stress was not tallied by pair style"); // sum heat flux across procs double hflux = 0.0; @@ -210,7 +213,10 @@ void ComputeHeatFluxVirialTally::compute_peratom() { invoked_peratom = update->ntimestep; if ((did_setup != invoked_peratom) || (update->eflag_global != invoked_peratom)) - error->all(FLERR, "Energy was not tallied on needed timestep"); + error->all(FLERR, "Stress was not tallied on needed timestep"); + + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Stress was not tallied by pair style"); // collect contributions from ghost atoms diff --git a/src/TALLY/compute_pe_mol_tally.cpp b/src/TALLY/compute_pe_mol_tally.cpp index b4f2ccd832..049563bc14 100644 --- a/src/TALLY/compute_pe_mol_tally.cpp +++ b/src/TALLY/compute_pe_mol_tally.cpp @@ -127,6 +127,9 @@ void ComputePEMolTally::compute_vector() if ((did_setup != invoked_vector) || (update->eflag_global != invoked_vector)) error->all(FLERR, "Energy was not tallied on needed timestep"); + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Energy was not tallied by pair style"); + // sum accumulated energies across procs MPI_Allreduce(etotal, vector, size_vector, MPI_DOUBLE, MPI_SUM, world); diff --git a/src/TALLY/compute_pe_tally.cpp b/src/TALLY/compute_pe_tally.cpp index d6af993afe..fc13a3b8da 100644 --- a/src/TALLY/compute_pe_tally.cpp +++ b/src/TALLY/compute_pe_tally.cpp @@ -169,6 +169,9 @@ double ComputePETally::compute_scalar() if ((did_setup != invoked_scalar) || (update->eflag_global != invoked_scalar)) error->all(FLERR, "Energy was not tallied on needed timestep"); + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Energy was not tallied by pair style"); + // sum accumulated energies across procs MPI_Allreduce(etotal, vector, size_peratom_cols, MPI_DOUBLE, MPI_SUM, world); @@ -185,6 +188,9 @@ void ComputePETally::compute_peratom() if ((did_setup != invoked_peratom) || (update->eflag_global != invoked_peratom)) error->all(FLERR, "Energy was not tallied on needed timestep"); + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Energy was not tallied by pair style"); + // collect contributions from ghost atoms if (force->newton_pair) { diff --git a/src/TALLY/compute_stress_tally.cpp b/src/TALLY/compute_stress_tally.cpp index f04640a2d2..32c3e83bb4 100644 --- a/src/TALLY/compute_stress_tally.cpp +++ b/src/TALLY/compute_stress_tally.cpp @@ -201,7 +201,10 @@ double ComputeStressTally::compute_scalar() { invoked_scalar = update->ntimestep; if ((did_setup != invoked_scalar) || (update->eflag_global != invoked_scalar)) - error->all(FLERR, "Energy was not tallied on needed timestep"); + error->all(FLERR, "Stress was not tallied on needed timestep"); + + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Stress was not tallied by pair style"); // sum accumulated forces across procs @@ -221,7 +224,10 @@ void ComputeStressTally::compute_peratom() { invoked_peratom = update->ntimestep; if ((did_setup != invoked_peratom) || (update->eflag_global != invoked_peratom)) - error->all(FLERR, "Energy was not tallied on needed timestep"); + error->all(FLERR, "Stress was not tallied on needed timestep"); + + if ((comm->me == 0) && !force->pair->did_tally_callback()) + error->warning(FLERR, "Stress was not tallied by pair style"); // collect contributions from ghost atoms diff --git a/src/pair.cpp b/src/pair.cpp index 32c7faaf90..9ae24e1e93 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -109,6 +109,7 @@ Pair::Pair(LAMMPS *lmp) : maxeatom = maxvatom = maxcvatom = 0; num_tally_compute = 0; + did_tally_flag = 0; nelements = nparams = maxparam = 0; @@ -295,6 +296,9 @@ void Pair::init() utils::logmesg(lmp,"Generated {} of {} mixed pair_coeff terms from {} mixing rule\n", mixed_count, num_mixed_pairs, mixing_rule_names[mix_flag]); } + + // for monitoring, if Pair::ev_tally() was called. + did_tally_flag = 0; } /* ---------------------------------------------------------------------- @@ -1095,6 +1099,7 @@ void Pair::ev_tally(int i, int j, int nlocal, int newton_pair, } if (num_tally_compute > 0) { + did_tally_flag = 1; for (int k=0; k < num_tally_compute; ++k) { Compute *c = list_tally_compute[k]; c->pair_tally_callback(i, j, nlocal, newton_pair, diff --git a/src/pair.h b/src/pair.h index 885a2c45ff..8c856660e9 100644 --- a/src/pair.h +++ b/src/pair.h @@ -230,12 +230,13 @@ class Pair : protected Pointers { // management of callbacks to be run from ev_tally() protected: - int num_tally_compute; + int num_tally_compute, did_tally_flag; class Compute **list_tally_compute; public: virtual void add_tally_callback(class Compute *); virtual void del_tally_callback(class Compute *); + bool did_tally_callback() const { return did_tally_flag != 0; } protected: int instance_me; // which Pair class instantiation I am From 367b0afb17f79281f1c1ff2b912b27db5413e80c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Apr 2023 14:57:50 -0400 Subject: [PATCH 071/448] document additional pair style restrictions for /tally computes --- doc/src/compute_tally.rst | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/doc/src/compute_tally.rst b/doc/src/compute_tally.rst index 6eff1e186e..fe2cbe7cca 100644 --- a/doc/src/compute_tally.rst +++ b/doc/src/compute_tally.rst @@ -187,16 +187,22 @@ Both the scalar and vector values calculated by this compute are Restrictions """""""""""" -This compute is part of the TALLY package. It is only enabled if -LAMMPS was built with that package. See the :doc:`Build package ` page for more info. +This compute is part of the TALLY package. It is only enabled if LAMMPS +was built with that package. See the :doc:`Build package +` page for more info. Not all pair styles can be evaluated in a pairwise mode as required by -this compute. For example, 3-body and other many-body potentials, -such as :doc:`Tersoff ` and -:doc:`Stillinger-Weber ` cannot be used. :doc:`EAM ` -potentials only include the pair potential portion of the EAM -interaction when used by this compute, not the embedding term. Also -bonded or Kspace interactions do not contribute to this compute. +this compute. For example, 3-body and other many-body potentials, such +as :doc:`Tersoff ` and :doc:`Stillinger-Weber ` +cannot be used. :doc:`EAM ` potentials only include the pair +potential portion of the EAM interaction when used by this compute, not +the embedding term. Also bonded or Kspace interactions do not +contribute to this compute. + +These computes are not compatible with accelerated pair styles from the +GPU, INTEL, KOKKOS, or OPENMP packages. They will either create an error +or print a warning when required data was not tallied in the required way +and thus the data acquisition functions from these computes not called. When used with dynamic groups, a :doc:`run 0 ` command needs to be inserted in order to initialize the dynamic groups before accessing From d4a3903ba348dc80e8cf3c19d67337e196ce75af Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Apr 2023 14:58:12 -0400 Subject: [PATCH 072/448] improve error messages --- src/TALLY/compute_heat_flux_tally.cpp | 5 +++-- src/TALLY/compute_heat_flux_virial_tally.cpp | 4 ++-- src/TALLY/compute_pe_mol_tally.cpp | 5 +++-- src/TALLY/compute_pe_tally.cpp | 4 ++-- src/TALLY/compute_stress_tally.cpp | 5 +++-- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/TALLY/compute_heat_flux_tally.cpp b/src/TALLY/compute_heat_flux_tally.cpp index 9142f7859c..47b9fb5681 100644 --- a/src/TALLY/compute_heat_flux_tally.cpp +++ b/src/TALLY/compute_heat_flux_tally.cpp @@ -29,10 +29,11 @@ using namespace LAMMPS_NS; ComputeHeatFluxTally::ComputeHeatFluxTally(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all(FLERR, "Illegal compute heat/flux/tally command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute heat/flux/tally", error); igroup2 = group->find(arg[3]); - if (igroup2 == -1) error->all(FLERR, "Could not find compute heat/flux/tally second group ID"); + if (igroup2 == -1) + error->all(FLERR, "Could not find compute heat/flux/tally second group ID {}", arg[3]); groupbit2 = group->bitmask[igroup2]; vector_flag = 1; diff --git a/src/TALLY/compute_heat_flux_virial_tally.cpp b/src/TALLY/compute_heat_flux_virial_tally.cpp index ec7781b0aa..7e4b27f361 100644 --- a/src/TALLY/compute_heat_flux_virial_tally.cpp +++ b/src/TALLY/compute_heat_flux_virial_tally.cpp @@ -29,11 +29,11 @@ using namespace LAMMPS_NS; ComputeHeatFluxVirialTally::ComputeHeatFluxVirialTally(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all(FLERR, "Illegal compute heat/flux/virial/tally command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute heat/flux/virial/tally", error); igroup2 = group->find(arg[3]); if (igroup2 == -1) - error->all(FLERR, "Could not find compute heat/flux/virial/tally second group ID"); + error->all(FLERR, "Could not find compute heat/flux/virial/tally second group ID {}", arg[3]); groupbit2 = group->bitmask[igroup2]; scalar_flag = 1; diff --git a/src/TALLY/compute_pe_mol_tally.cpp b/src/TALLY/compute_pe_mol_tally.cpp index 049563bc14..66e9972464 100644 --- a/src/TALLY/compute_pe_mol_tally.cpp +++ b/src/TALLY/compute_pe_mol_tally.cpp @@ -27,10 +27,11 @@ using namespace LAMMPS_NS; ComputePEMolTally::ComputePEMolTally(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all(FLERR, "Illegal compute pe/mol/tally command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute pe/mol/tally", error); igroup2 = group->find(arg[3]); - if (igroup2 == -1) error->all(FLERR, "Could not find compute pe/mol/tally second group ID"); + if (igroup2 == -1) + error->all(FLERR, "Could not find compute pe/mol/tally second group ID {}", arg[3]); groupbit2 = group->bitmask[igroup2]; vector_flag = 1; diff --git a/src/TALLY/compute_pe_tally.cpp b/src/TALLY/compute_pe_tally.cpp index fc13a3b8da..c2dd133016 100644 --- a/src/TALLY/compute_pe_tally.cpp +++ b/src/TALLY/compute_pe_tally.cpp @@ -28,10 +28,10 @@ using namespace LAMMPS_NS; ComputePETally::ComputePETally(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all(FLERR, "Illegal compute pe/tally command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute pe/tally", error); igroup2 = group->find(arg[3]); - if (igroup2 == -1) error->all(FLERR, "Could not find compute pe/tally second group ID"); + if (igroup2 == -1) error->all(FLERR, "Could not find compute pe/tally second group ID {}", arg[3]); groupbit2 = group->bitmask[igroup2]; scalar_flag = 1; diff --git a/src/TALLY/compute_stress_tally.cpp b/src/TALLY/compute_stress_tally.cpp index 32c3e83bb4..b5b54c495c 100644 --- a/src/TALLY/compute_stress_tally.cpp +++ b/src/TALLY/compute_stress_tally.cpp @@ -29,10 +29,11 @@ using namespace LAMMPS_NS; ComputeStressTally::ComputeStressTally(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 4) error->all(FLERR, "Illegal compute stress/tally command"); + if (narg < 4) utils::missing_cmd_args(FLERR, "compute stress/tally", error); igroup2 = group->find(arg[3]); - if (igroup2 == -1) error->all(FLERR, "Could not find compute stress/tally second group ID"); + if (igroup2 == -1) + error->all(FLERR, "Could not find compute stress/tally second group ID {}", arg[3]); groupbit2 = group->bitmask[igroup2]; scalar_flag = 1; From f68603703fe97df957face17a8f69ddb1c0a73e5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 26 Apr 2023 15:35:03 -0400 Subject: [PATCH 073/448] add false positive --- doc/utils/sphinx-config/false_positives.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index ab03ee3dff..ee3b582fd9 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1562,6 +1562,7 @@ invertibility ionicities ionizable ionocovalent +iOS iostreams iparam ipi From 449f5439ae9f1e8977d52706916be263ebd73770 Mon Sep 17 00:00:00 2001 From: "K.kawai" <31260712+kawai125@users.noreply.github.com> Date: Thu, 27 Apr 2023 18:52:04 +0900 Subject: [PATCH 074/448] fix grid index in read_electron_temperatures --- src/EXTRA-FIX/fix_ttm_mod.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index 65ccbda4c1..b142a369a9 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -614,8 +614,8 @@ void FixTTMMod::read_electron_temperatures(const std::string &filename) if (T_tmp < 0.0) throw TokenizerException("Fix ttm electron temperatures must be > 0.0",""); - T_electron[iz][iy][ix] = T_tmp; - T_initial_set[iz][iy][ix] = 1; + T_electron[ix][iy][iz] = T_tmp; + T_initial_set[ix][iy][iz] = 1; } } catch (std::exception &e) { error->one(FLERR, e.what()); @@ -626,7 +626,7 @@ void FixTTMMod::read_electron_temperatures(const std::string &filename) for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) for (int ix = 0; ix < nxgrid; ix++) - if (T_initial_set[iz][iy][ix] == 0) + if (T_initial_set[ix][iy][iz] == 0) error->all(FLERR,"Fix ttm/mod infile did not set all temperatures"); memory->destroy(T_initial_set); From 787399f5e399be0eda2aaabfd25b9487cd4a7404 Mon Sep 17 00:00:00 2001 From: Joel Thomas Clemmer Date: Thu, 27 Apr 2023 09:25:58 -0600 Subject: [PATCH 075/448] Reorganizing the programming manual and editing some text --- doc/src/Modify.rst | 15 +- doc/src/Modify_contribute.rst | 108 ++++--- doc/src/Modify_requirements.rst | 362 +++++++++++++++++++++++ doc/src/Modify_style.rst | 503 +++++--------------------------- 4 files changed, 497 insertions(+), 491 deletions(-) create mode 100644 doc/src/Modify_requirements.rst diff --git a/doc/src/Modify.rst b/doc/src/Modify.rst index 8ea7850fc5..31e67a66ca 100644 --- a/doc/src/Modify.rst +++ b/doc/src/Modify.rst @@ -3,21 +3,24 @@ Modifying & extending LAMMPS LAMMPS is designed in a modular fashion and to be easy to modify or extend with new functionality. In fact, about 95% of its source code -are optional. The following pages give basic instructions on what -is required when adding new styles of different kinds to LAMMPS. +is optional. The following pages give basic instructions on adding new +features to LAMMPS. If you add a new feature to LAMMPS and think it will be of general interest to other users, we encourage you to submit it for inclusion in -LAMMPS as a pull request on our `GitHub site -`_, after reading about :doc:`how to -prepare your code for submission ` and :doc:`the -style requirements and recommendations `. +LAMMPS. This process is explained in the following three pages: +:doc:`how to prepare and submit your code `, +:doc:`requirements for submissions `, and +:doc:`style guidelines `. A discussion of the various +types of styles in LAMMPS is then provided. + .. toctree:: :maxdepth: 1 Modify_overview Modify_contribute + Modify_requirements Modify_style .. toctree:: diff --git a/doc/src/Modify_contribute.rst b/doc/src/Modify_contribute.rst index d3d270fe3b..51692248a3 100644 --- a/doc/src/Modify_contribute.rst +++ b/doc/src/Modify_contribute.rst @@ -7,20 +7,25 @@ accessible to all LAMMPS users. The LAMMPS source code is managed with git and public development is hosted on `GitHub `_. You can monitor the repository to be notified of releases, follow the ongoing development, and comment on -topics of interest to you. +topics of interest to you. This section contains general information +regarding the preparation and submission of new features to LAMMPS. If +you are new to development in LAMMPS, we recommend you read one of the +tutorials on developing a new :doc:`pair style ` or +:doc:`fix style ` which provide a friendly +introduction to what LAMMPS development entails and common vocabulary +used in this chapter. + Communication with the LAMMPS developers ---------------------------------------- For any larger modifications or programming project, you are encouraged -to contact the LAMMPS developers ahead of time in order to discuss -implementation strategies and coding guidelines. That will make it -easier to integrate your contribution and results in less work for -everybody involved. You are also encouraged to search through the list -of `open issues on GitHub `_ -and submit a new issue for a planned feature, so you would not duplicate -the work of others (and possibly get scooped by them) or have your work -duplicated by others. +to contact the LAMMPS developers ahead of time to discuss implementation +strategies. That will make it easier to integrate your contribution and +results in less work for everybody involved. You are also encouraged to +search through the list of `open issues on GitHub +`_ and submit a new issue for a +planned feature, to avoid duplicating work (and possibly being scooped). For informal communication with the LAMMPS developers you may ask to join the `LAMMPS developers on Slack `_. This @@ -32,29 +37,6 @@ for help with compiling, installing, or using LAMMPS. Please post a message to the `LAMMPS forum `_ for those purposes. -Packages versus individual files --------------------------------- - -The remainder of this chapter describes how to add new "style" files of -various kinds to LAMMPS. Packages are simply collections of one or more -such new class files which are invoked as a new style within a LAMMPS -input script. In some cases collections of supporting functions or -classes are also included as separate files in a package, especially when -they can be shared between multiple styles. If designed correctly, these -additions typically do not require any changes to the core code of -LAMMPS; they are simply add-on files that are compiled with the rest of -LAMMPS. To make those styles work, you may need some trivial changes to -the core code; an example of a trivial change is making a parent-class -method "virtual" when you derive a new child class from it. - -If you think your new feature or package requires some non-trivial -changes in core LAMMPS files, you should communicate with the LAMMPS -developers `on Slack `_, `on GitHub -`_, or `via email -`_, since we may have -recommendations about what changes to do where, or may not want to -include certain changes for some reason and thus you would need to look -for alternatives. Time and effort required ------------------------ @@ -63,13 +45,11 @@ How quickly your contribution will be integrated can vary a lot. It depends largely on how much effort it will cause the LAMMPS developers to integrate and test it, how many and what kind of changes to the core code are required, how quickly you can address them and of how much -interest it is to the larger LAMMPS community. Please see the section -on :doc:`LAMMPS programming style and requirements ` for -instructions, recommendations, and formal requirements. A small, -modular, well written contribution may be integrated within hours, but a -complex change that will require a redesign of some core functionality -in LAMMPS for a clean integration can take many months until it is -considered ready for inclusion (though this is rare). +interest it is to the larger LAMMPS community. This process can be +streamlined by following the :doc:`requirements ` and :doc:`style guidelines`. A small, modular, well written +contribution may be integrated within hours, but a complex change that +requires a redesign of some core functionality in LAMMPS can take months +before inclusion (though this is rare). Submission procedure @@ -85,29 +65,16 @@ bug fixes from it. Once you have prepared everything, see the :doc:`LAMMPS GitHub Tutorial ` page for instructions on how to submit your changes or -new files through a GitHub pull request yourself. If you are unable or -unwilling to submit via GitHub yourself, you may also submit patch files +new files through a GitHub pull request. If you are unable or unwilling +to submit via GitHub yourself, you may also submit patch files or full files to the LAMMPS developers and ask them to submit a pull request on GitHub on your behalf. If this is the case, create a gzipped tar file of all new or changed files or a corresponding patch file using 'diff -u' or 'diff -c' format and compress it with gzip. Please only use gzip compression, as this works well and is available on all platforms. +This latter way of submission may delay the integration as it depends on +the LAMMPS developer having free time available. -If the new features/files are broadly useful we may add them as core -files to LAMMPS or as part of a :doc:`package `. All -packages are listed and described on the :doc:`Packages details -` doc page. - -Licensing ---------- - -Note that by providing us files to release, you agree to make them -open-source, i.e. we can release them under the terms of the GPL -(version 2) with the rest of LAMMPS. And similarly as part of a LGPL -(version 2.1) distribution of LAMMPS that we make available to -developers on request only and with files that are not authorized for -that kind of distribution removed (e.g. interface to FFTW). See the -:doc:`LAMMPS license ` page for details. External contributions ---------------------- @@ -123,3 +90,32 @@ package and we will post it there. We recommend to name external packages USER-\ so they can be easily distinguished from bundled packages that do not have the USER- prefix. + +Location of files: individual files and packages +-------------------------------- + +We rarely accept new styles in the core src folder. Thus please +review the list of :doc:`available Packages ` to see +if your contribution could be added to be added to one of them. It +should fit into the general purposed of that package. If it does not +fit well, it may be added to one of the EXTRA- packages or the MISC +package. + +However if your project includes many related features that are not covered +by one of the existing packages or is dependent on a library (bundled or +external), it is best to create a package with its own directory (labelled +with a name like FOO). In addition to your new files, the directory should +contain a README text file containing your name and contact information and +a brief description of what your new package does. + + +Changes to core LAMMPS files +-------------------------------- + +If designed correctly, many additions do not require any changes to the +core code of LAMMPS; they are simply add-on files that are compiled with +the rest of LAMMPS. To make those styles work, you may need some trivial +changes to the core code; an example of a trivial change is making a +parent-class method "virtual" when you derive a new child class from it. +If your features involve changes to the core LAMMPS files, it is particularly +encouraged that you communicate with the LAMMPS developers early in development. diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst new file mode 100644 index 0000000000..8c5869c929 --- /dev/null +++ b/doc/src/Modify_requirements.rst @@ -0,0 +1,362 @@ +Requirements for contributions to LAMMPS +=========================================================== + + +The following is a summary of the current requirements and +recommendations for including contributed source code or documentation +into the LAMMPS software distribution. + +Motivation +---------- + +The LAMMPS developers are committed to providing a software package that +is versatile, reliable, high-quality, efficient, portable, and easy to +maintain and modify. Achieving all of these goals is challenging since +a large part of LAMMPS consists of contributed code from many different +authors and not many of them are professionally trained programmers and +familiar with the idiosyncrasies of maintaining a large software +package. In addition, changes that interfere with the parallel +efficiency of the core code must be avoided. As LAMMPS continues to +grow and more features and functionality are added, it becomes a +necessity to be more discriminating with new contributions while also +working at the same time to improve the existing code. + +The following requirements and recommendations are provided to help +maintaining or improving that status. It is indicated which requirements are strict, and which represent a preference and thus are negotiable or optional. +Please feel free to contact the LAMMPS core developers in case you need +additional explanations or clarifications or in case you need assistance +in realizing the (strict) requirements for your contributions. Requirements +include: +* :ref:`Licensing requirements ` (strict) +* :ref:`Integration testing ` (strict) +* :ref:`Documentation ` (strict) +* :ref:`Programming language standards ` (strict) +* :ref:`Build system ` (strict) +* :ref:`Command or style names ` (strict) +* :ref:`Programming style requirements ` (varied) +* :ref:`Examples ` (preferred) +* :ref:`Error or warning messages and explanations ` (preferred) +* :ref:`Citation reminder ` (optional) +* :ref:`Testing ` (optional) + + +.. _License: +Licensing requirements (strict) +------------------------------- + +Contributing authors agree when submitting a pull request that their +contributions can be distributed under the LAMMPS license +conditions. This is the GNU public license in version 2 (not 3 or later) +for the publicly distributed versions, e.g. on the LAMMPS homepage or on +GitHub. On request we also make a version of LAMMPS available under +LGPL 2.1 terms; this will usually be the latest available or a previous +stable version with a few LGPL 2.1 incompatible files removed. More details +are found on the :doc:`LAMMPS open-source license page `. + +Your new source files should have the LAMMPS copyright, GPL notice, and +your name and email address at the top, like other user-contributed +LAMMPS source files. + +Contributions may be under a different license as long as that +license does not conflict with the aforementioned terms. Contributions +that use code with a conflicting license can be split into two parts: + +1. the core parts (i.e. parts that must be in the `src` tree) that are + licensed under compatible terms and bundled with the LAMMPS sources +2. an external library that must be downloaded and compiled (either + separately or as part of the LAMMPS compilation) + +Please note, that this split licensed mode may complicate including the +contribution in binary packages. + + +.. _IntegrationTesting +Integration testing (strict) +---------------------------- + +Where possible we utilize available continuous integration tools to +search for common programming mistakes, portability limitations, +incompatible formatting, and undesired side effects. Contributed code +must pass the automated tests on GitHub before it can be merged with +the LAMMPS distribution. These tests compile LAMMPS in a variety of +environments and settings and run the bundled unit tests. At the +discretion of the LAMMPS developer managing the pull request, +additional tests may be activated that test for "side effects" on +running a collection of input decks and create consistent results. +The translation of the documentation to HTML and PDF is also tested. + +This means that contributed source code **must** compile with the most +current version of LAMMPS with ``-DLAMMPS_BIGBIG`` in addition to the +default setting of ``-DLAMMPS_SMALLBIG``. The code needs to work +correctly in both cases and also in serial and parallel using MPI. + +Some "disruptive" changes may break tests and require updates to the +testing tools or scripts or tests themselves. This is rare. If in +doubt, contact the LAMMPS developer that is assigned to the pull request. + + +.. _Documentation +Documentation (strict) +---------------------- + +Contributions that add new styles or commands or augment existing ones +must include the corresponding new or modified documentation in +`ReStructuredText format `_ (.rst files in the ``doc/src/`` +folder). The documentation shall be written in American English and the +.rst file must use only ASCII characters so it can be cleanly translated +to PDF files (via `sphinx `_ and PDFLaTeX). +Special characters may be included via embedded math expression typeset +in a LaTeX subset. + +.. _rst: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html + +When adding new commands, they need to be integrated into the sphinx +documentation system, and the corresponding command tables and lists +updated. When translating the documentation into html files there should +be no warnings. When adding a new package also some lists describing +packages must be updated as well as a package specific description added +and, if necessary, some package specific build instructions included. + +As appropriate, the text files with the documentation can include inline +mathematical expression or figures (see ``doc/JPG`` for examples). +Additional PDF files with further details (see ``doc/PDF`` for examples) may +also be included. The page should also include literature citations as +appropriate; see the bottom of ``doc/fix_nh.rst`` for examples and the +earlier part of the same file for how to format the cite itself. +Citation labels must be unique across **all** .rst files. The +"Restrictions" section of the page should indicate if your command is +only available if LAMMPS is built with the appropriate FOO package. See +other package doc files for examples of how to do this. + +Please run at least "make html" and "make spelling" and carefully +inspect and proofread the resulting HTML format doc page before +submitting your code. Upon submission of a pull request, checks for +error free completion of the HTML and PDF build will be performed and +also a spell check, a check for correct anchors and labels, and a check +for completeness of references all styles in their corresponding tables +and lists is run. In case the spell check reports false positives they +can be added to the file ``doc/utils/sphinx-config/false_positives.txt`` + +Contributions that add or modify the library interface or "public" APIs +from the C++ code or the Fortran module must include suitable doxygen +comments in the source and corresponding changes to the documentation +sources for the "Programmer Guide" guide section of the LAMMPS manual. + +If your feature requires some more complex steps and explanations to be +used correctly or some external or bundled tools or scripts, we +recommend that you also contribute a :doc:`Howto document ` +providing some more background information and some tutorial material. +This can also be used to provide more in-depth explanations for bundled +examples. + +As a rule-of-thumb, the more clear and self-explanatory you make +your documentation, README files and examples, and the easier you make +it for people to get started, the more likely it is that users will try +out your new feature. + + +.. _ProgrammingStandards +Programming language standards (strict) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The core of LAMMPS is written in C++11 in a style that can be mostly +described as "C with classes". Advanced C++ features like operator +overloading or excessive use of templates are avoided with the intent to +keep the code readable to programmers that have limited C++ programming +experience. C++ constructs are acceptable when they help improve the +readability and reliability of the code, e.g. when using the +`std::string` class instead of manipulating pointers and calling the +string functions of the C library. In addition a collection of +convenient :doc:`utility functions and classes ` for +recurring tasks and a collection of +:doc:`platform neutral functions ` for improved +portability are provided. + +Included Fortran code has to be compatible with the Fortran 2003 +standard. Python code must be compatible with Python 3.5. Large parts +of LAMMPS (including the :ref:`PYTHON package `) are also +compatible with Python 2.7. Compatibility with Python 2.7 is +desirable, but compatibility with Python 3.5 is **required**. + +Compatibility with these older programming language standards is very +important to maintain portability and availability of LAMMPS on many +platforms. This applies especially to HPC cluster environments, which +tend to be running older software stacks and LAMMPS users may be +required to use those older tools for access to advanced hardware +features or not have the option to install newer compilers or libraries. + + +.. _BuildSystem +Build system (strict) +--------------------------------- + +LAMMPS currently supports two build systems: one that is based on +:doc:`traditional Makefiles ` and one that is based on +:doc:`CMake `. Thus your contribution must be compatible +with and support both. + +For a single pair of header and implementation files that are an +independent feature, it is usually only required to add them to +`src/.gitignore``. + +For traditional make, if your contributed files or package depend on +other LAMMPS style files or packages also being installed (e.g. because +your file is a derived class from the other LAMMPS class), then an +Install.sh file is also needed to check for those dependencies and +modifications to src/Depend.sh to trigger the checks. See other README +and Install.sh files in other directories as examples. + +Similarly for CMake support, changes may need to be made to +cmake/CMakeLists.txt, some of the files in cmake/presets, and possibly a +file with specific instructions needs to be added to +cmake/Modules/Packages/. Please check out how this is handled for +existing packages and ask the LAMMPS developers if you need assistance. + + +.. _Naming +Command or Style names, file names, and keywords (strict) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +All user-visible command or style names should be all lower case and +should only use letters, numbers, or forward slashes. They should be +descriptive and initialisms should be avoided unless they are well +established (e.g. lj for Lennard-Jones). For a compute style +"some/name" the source files must be called `compute_some_name.h` and +`compute_some_name.cpp`. The "include guard" would then be +`LMP_COMPUTE_SOME_NAME_H` and the class name `ComputeSomeName`. + + +.. _ProgrammingStyle +Programming style requirements (varied) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To maintain a consistency, there are various programming style +requirements for contributions to LAMMPS. Some of these requirements +are strict while some are only preferred. An indepth discussion of +the style guidelines are provided in the :doc:`programming style +doc page `. + + +.. _Examples +Examples (preferred) +-------------------- + +In most cases, it is preferred that example scripts (simple, small, fast +to complete on 1 CPU) are included that demonstrate the use of new or +extended functionality. These are typically under the examples or +examples/PACKAGES directory are are further described on the +:doc:`examples page `. Guidlines for input scripts include: + +- commands that generate output should be commented out (except when the + output is the sole purpose or the feature, e.g. for a new compute) + +- commands like :doc:`log `, :doc:`echo `, :doc:`package + `, :doc:`processors `, :doc:`suffix ` may + **not** be used in the input file (exception: "processors * * 1" or + similar is acceptable when used to avoid unwanted domain decomposition + of empty volumes) + +- outside of the log files, no generated output should be included + +- custom thermo_style settings may not include output measuring CPU or other + time as it complicates comparisons between different runs + +- input files should be named ``in.name``, data files should be named + ``data.name`` and log files should be named ``log.version.name..`` + +- the total file size of all the inputs and outputs should be small + +- where possible, potential files from the "potentials" folder or data + file from other folders should be re-used through symbolic links + + +.. _ErrorMessages +Error or warning messages and explanations (preferred) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. versionchanged:: 4May2022 + +Starting with LAMMPS version 4 May 2022 the LAMMPS developers have +agreed on a new policy for error and warning messages. + +Previously, all error and warning strings were supposed to be listed in +the class header files with an explanation. Those would then be +regularly "harvested" and transferred to alphabetically sorted lists in +the manual. To avoid excessively long lists and to reduce effort, this +came with a requirement to have rather generic error messages (e.g. +"Illegal ... command"). To identify the specific cause, the name of the +source file and the line number of the error location would be printed, +so that one could look up the cause by reading the source code. + +The new policy encourages more specific error messages that ideally +indicate the cause directly requiring no further lookup. This is aided +by the `{fmt} library `_ to convert the Error class +commands so that they take a variable number of arguments and error +text will be treated like a {fmt} syntax format string. Error messages +should still preferably be kept to a single line or two lines at most. + +For more complex explanations or errors that have multiple possible +reasons, a paragraph should be added to the `Error_details` page with an +error code reference (e.g. ``.. _err0001:``) then the utility function +:cpp:func:`utils::errorurl() ` can be used +to generate an URL that will directly lead to that paragraph. An error +for missing arguments can be easily generated using the +:cpp:func:`utils::missing_cmd_args() +` convenience function. +An example for this approach would be the +``src/read_data.cpp`` and ``src/atom.cpp`` files that implement the +:doc:`read_data ` and :doc:`atom_modify ` +commands and that may create :ref:`"Unknown identifier in data file" ` +errors that may have multiple possible reasons which complicates debugging, +and thus require some additional explanation. + +The transformation of existing LAMMPS code to this new scheme is ongoing +and - given the size of the LAMMPS source code - will take a significant +amount of time until completion. However, for new code following the +new approach is strongly preferred. The expectation is that the new +scheme will make it easier for LAMMPS users, developers, and +maintainers. + + +.. _Citation +Citation reminder (optional) +----------------------------- + +If there is a paper of yours describing your feature (either the +algorithm/science behind the feature itself, or its initial usage, or +its implementation in LAMMPS), you can add the citation to the \*.cpp +source file. See ``src/DIFFRACTION/compute_saed.cpp`` for an example. +A BibTeX format citation is stored in a string variable at the top +of the file and a single line of code registering this variable is +added to the constructor of the class. When your feature is used, +by default, LAMMPS will print the brief info and the DOI +in the first line to the screen and the full citation to the log file. + +If there is additional functionality (which may have been added later) +described in a different publication, additional citation descriptions +may be added for as long as they are only registered when the +corresponding keyword activating this functionality is used. With these +options it is possible to have LAMMPS output a specific citation +reminder whenever a user invokes your feature from their input script. +Please note that you should *only* use this for the *most* relevant +paper for a feature and a publication that you or your group authored. +E.g. adding a citation in the code for a paper by Nose and Hoover if you +write a fix that implements their integrator is not the intended usage. +That latter kind of citation should just be included in the +documentation page you provide describing your contribution. If you are +not sure what the best option would be, please contact the LAMMPS +developers for advice. + +.. _Testing +Testing (optional) +------------------ + +If your contribution contains new utility functions or a supporting class +(i.e. anything that does not depend on a LAMMPS object), new unit tests +should be added to a suitable folder in the ``unittest`` tree. +When adding a new LAMMPS style computing forces or selected fixes, +a ``.yaml`` file with a test configuration and reference data should be +added for the styles where a suitable tester program already exists +(e.g. pair styles, bond styles, etc.). Please see +:ref:`this section in the manual ` for more information on +how to enable, run, and expand testing. diff --git a/doc/src/Modify_style.rst b/doc/src/Modify_style.rst index 2feffe56c2..2603df8242 100644 --- a/doc/src/Modify_style.rst +++ b/doc/src/Modify_style.rst @@ -1,344 +1,25 @@ -LAMMPS programming style and requirements for contributions +LAMMPS programming style =========================================================== -The following is a summary of the current requirements and -recommendations for including contributed source code or documentation -into the LAMMPS software distribution. - -Motivation ----------- - -The LAMMPS developers are committed to providing a software package that -is versatile, reliable, high-quality, efficient, portable, and easy to -maintain and modify. Achieving all of these goals is challenging since -a large part of LAMMPS consists of contributed code from many different -authors and not many of them are professionally trained programmers and -familiar with the idiosyncrasies of maintaining a large software -package. In addition, changes that interfere with the parallel -efficiency of the core code must be avoided. As LAMMPS continues to -grow and more features and functionality are added, it becomes a -necessity to be more discriminating with new contributions while also -working at the same time to improve the existing code. - -The following requirements and recommendations are provided to help -maintaining or improving that status. Where possible we utilize -available continuous integration tools to search for common programming -mistakes, portability limitations, incompatible formatting, and -undesired side effects. It is indicated which requirements are strict, -and which represent a preference and thus are negotiable or optional. - -Please feel free to contact the LAMMPS core developers in case you need -additional explanations or clarifications or in case you need assistance -in realizing the (strict) requirements for your contributions. - -Licensing requirements (strict) -------------------------------- - -Contributing authors agree when submitting a pull request that their -contributions can be distributed under the LAMMPS license -conditions. This is the GNU public license in version 2 (not 3 or later) -for the publicly distributed versions, e.g. on the LAMMPS homepage or on -GitHub. On request we also make a version of LAMMPS available under -LGPL 2.1 terms; this will usually be the latest available or a previous -stable version with a few LGPL 2.1 incompatible files removed. More details -are found on the :doc:`LAMMPS open-source license page `. - -Your new source files should have the LAMMPS copyright, GPL notice, and -your name and email address at the top, like other user-contributed -LAMMPS source files. - -Contributions may be under a different license as long as that -license does not conflict with the aforementioned terms. Contributions -that use code with a conflicting license can be split into two parts: - -1. the core parts (i.e. parts that must be in the `src` tree) that are - licensed under compatible terms and bundled with the LAMMPS sources -2. an external library that must be downloaded and compiled (either - separately or as part of the LAMMPS compilation) - -Please note, that this split licensed mode may complicate including the -contribution in binary packages. - -Using pull requests on GitHub (preferred) ------------------------------------------ - -All contributions to LAMMPS are processed as pull requests on GitHub -(this also applies to the work of the core LAMMPS developers). A -:doc:`tutorial for submitting pull requests on GitHub ` is -provided. If this is still problematic, contributors may contact any of -the core LAMMPS developers for help or to create a pull request on their -behalf. This latter way of submission may delay the integration as it -depends on the amount of time required to prepare the pull request and -free time available by the LAMMPS developer in question to spend on this -task. - -Integration testing (strict) ----------------------------- - -Contributed code, like all pull requests, must pass the automated -tests on GitHub before it can be merged with the LAMMPS distribution. -These tests compile LAMMPS in a variety of environments and settings and -run the bundled unit tests. At the discretion of the LAMMPS developer -managing the pull request, additional tests may be activated that test -for "side effects" on running a collection of input decks and create -consistent results. Also, the translation of the documentation to HTML -and PDF is tested for. - -More specifically, this means that contributed source code **must** -compile with the most current version of LAMMPS with ``-DLAMMPS_BIGBIG`` -in addition to the default setting of ``-DLAMMPS_SMALLBIG``. The code -needs to work correctly in both cases and also in serial and parallel -using MPI. - -Some "disruptive" changes may break tests and require updates to the -testing tools or scripts or tests themselves. This is rare. If in -doubt, contact the LAMMPS developer that is assigned to the pull request -for further details and explanations and suggestions of what needs to be -done. - -Documentation (strict) ----------------------- - -Contributions that add new styles or commands or augment existing ones -must include the corresponding new or modified documentation in -`ReStructuredText format `_ (.rst files in the ``doc/src/`` -folder). The documentation shall be written in American English and the -.rst file must use only ASCII characters so it can be cleanly translated -to PDF files (via `sphinx `_ and PDFLaTeX). -Special characters may be included via embedded math expression typeset -in a LaTeX subset. - -.. _rst: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html - -When adding new commands, they need to be integrated into the sphinx -documentation system, and the corresponding command tables and lists -updated. When translating the documentation into html files there should -be no warnings. When adding a new package also some lists describing -packages must be updated as well as a package specific description added -and, if necessary, some package specific build instructions included. - -As appropriate, the text files with the documentation can include inline -mathematical expression or figures (see ``doc/JPG`` for examples). -Additional PDF files with further details (see ``doc/PDF`` for examples) may -also be included. The page should also include literature citations as -appropriate; see the bottom of ``doc/fix_nh.rst`` for examples and the -earlier part of the same file for how to format the cite itself. -Citation labels must be unique across **all** .rst files. The -"Restrictions" section of the page should indicate if your command is -only available if LAMMPS is built with the appropriate FOO package. See -other package doc files for examples of how to do this. - -Please run at least "make html" and "make spelling" and carefully -inspect and proofread the resulting HTML format doc page before -submitting your code. Upon submission of a pull request, checks for -error free completion of the HTML and PDF build will be performed and -also a spell check, a check for correct anchors and labels, and a check -for completeness of references all styles in their corresponding tables -and lists is run. In case the spell check reports false positives they -can be added to the file ``doc/utils/sphinx-config/false_positives.txt`` - -Contributions that add or modify the library interface or "public" APIs -from the C++ code or the Fortran module must include suitable doxygen -comments in the source and corresponding changes to the documentation -sources for the "Programmer Guide" guide section of the LAMMPS manual. - -Examples (preferred) --------------------- - -In most cases, it is preferred that example scripts (simple, small, fast -to complete on 1 CPU) are included that demonstrate the use of new or -extended functionality. These are typically under the examples or -examples/PACKAGES directory. A few guidelines for such example input -decks. - -- commands that generate output should be commented out (except when the - output is the sole purpose or the feature, e.g. for a new compute). - -- commands like :doc:`log `, :doc:`echo `, :doc:`package - `, :doc:`processors `, :doc:`suffix ` may - **not** be used in the input file (exception: "processors * * 1" or - similar is acceptable when used to avoid unwanted domain decomposition - of empty volumes). - -- outside of the log files, no generated output should be included - -- custom thermo_style settings may not include output measuring CPU or other time - as that makes comparing the thermo output between different runs more complicated. - -- input files should be named ``in.name``, data files should be named - ``data.name`` and log files should be named ``log.version.name..`` - -- the total file size of all the inputs and outputs should be small - -- where possible, potential files from the "potentials" folder or data - file from other folders should be re-used through symbolic links - -Howto document (optional) -------------------------- - -If your feature requires some more complex steps and explanations to be -used correctly or some external or bundled tools or scripts, we -recommend that you also contribute a :doc:`Howto document ` -providing some more background information and some tutorial material. -This can also be used to provide more in-depth explanations for bundled -examples. - -As a general rule-of-thumb, the more clear and self-explanatory you make -your documentation, README files and examples, and the easier you make -it for people to get started, the more likely it is that users will try -out your new feature. - -Programming style requirements (varied) ---------------------------------------- The LAMMPS developers aim to employ a consistent programming style and naming conventions across the entire code base, as this helps with maintenance, debugging, and understanding the code, both for developers -and users. +and users. This page provides a list of standard style choices used in +LAMMPS. Some of these standards are required while others are just +preferred. Following these conventions will make it much easier to +integrate your contribution. If you are uncertain, please ask. The files `pair_lj_cut.h`, `pair_lj_cut.cpp`, `utils.h`, and `utils.cpp` may serve as representative examples. -Command or Style names, file names, and keywords (mostly strict) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -All user-visible command or style names should be all lower case and -should only use letters, numbers, or forward slashes. They should be -descriptive and initialisms should be avoided unless they are well -established (e.g. lj for Lennard-Jones). For a compute style -"some/name" the source files must be called `compute_some_name.h` and -`compute_some_name.cpp`. The "include guard" would then be -`LMP_COMPUTE_SOME_NAME_H` and the class name `ComputeSomeName`. - -Whitespace and permissions (preferred) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Source files should not contain TAB characters unless required by the -syntax (e.g. in makefiles) and no trailing whitespace. Text files -should be added with Unix-style line endings (LF-only). Git will -automatically convert those in both directions when running on Windows; -use dos2unix on Linux machines to convert files. Text files should have -a line ending on the last line. - -All files should have 0644 permissions, i.e writable to the user only -and readable by all and no executable permissions. Executable -permissions (0755) should only be on shell scripts or python or similar -scripts for interpreted script languages. - -You can check for these issues with the python scripts in the -:ref:`"tools/coding_standard" ` folder. When run -normally with a source file or a source folder as argument, they will -list all non-conforming lines. By adding the `-f` flag to the command -line, they will modify the flagged files to try removing the detected -issues. - -Indentation and placement of braces (strongly preferred) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -LAMMPS uses 2 characters per indentation level and lines should be -kept within 100 characters wide. - -For new files added to the "src" tree, a `clang-format -`_ configuration file is -provided under the name `.clang-format`. This file is compatible with -clang-format version 8 and later. With that file present, files can be -reformatted according to the configuration with a command like: -`clang-format -i new-file.cpp`. Ideally, this is done while writing the -code or before a pull request is submitted. Blocks of code where the -reformatting from clang-format yields undesirable output may be -protected with placing a pair `// clang-format off` and `// clang-format -on` comments around that block. - -Error or warning messages and explanations (preferred) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. versionchanged:: 4May2022 - -Starting with LAMMPS version 4 May 2022 the LAMMPS developers have -agreed on a new policy for error and warning messages. - -Previously, all error and warning strings were supposed to be listed in -the class header files with an explanation. Those would then be -regularly "harvested" and transferred to alphabetically sorted lists in -the manual. To avoid excessively long lists and to reduce effort, this -came with a requirement to have rather generic error messages (e.g. -"Illegal ... command"). To identify the specific cause, the name of the -source file and the line number of the error location would be printed, -so that one could look up the cause by reading the source code. - -The new policy encourages more specific error messages that ideally -indicate the cause directly and no further lookup would be needed. -This is aided by using the `{fmt} library `_ to convert -the Error class commands so that they take a variable number of arguments -and error text will be treated like a {fmt} syntax format string. -Error messages should still kept to a single line or two lines at the most. - -For more complex explanations or errors that have multiple possible -reasons, a paragraph should be added to the `Error_details` page with an -error code reference (e.g. ``.. _err0001:``) then the utility function -:cpp:func:`utils::errorurl() ` can be used -to generate an URL that will directly lead to that paragraph. An error -for missing arguments can be easily generated using the -:cpp:func:`utils::missing_cmd_args() -` convenience function. - -The transformation of existing LAMMPS code to this new scheme is ongoing -and - given the size of the LAMMPS source code - will take a significant -amount of time until completion. However, for new code following the -new approach is strongly preferred. The expectation is that the new -scheme will make it easier for LAMMPS users, developers, and -maintainers. - -An example for this approach would be the -``src/read_data.cpp`` and ``src/atom.cpp`` files that implement the -:doc:`read_data ` and :doc:`atom_modify ` -commands and that may create :ref:`"Unknown identifier in data file" ` -errors that seem difficult to debug for users because they may have -one of multiple possible reasons, and thus require some additional explanations. - -Programming language standards (required) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The core of LAMMPS is written in C++11 in a style that can be mostly -described as "C with classes". Advanced C++ features like operator -overloading or excessive use of templates are avoided with the intent to -keep the code readable to programmers that have limited C++ programming -experience. C++ constructs are acceptable when they help improve the -readability and reliability of the code, e.g. when using the -`std::string` class instead of manipulating pointers and calling the -string functions of the C library. In addition a collection of -convenient :doc:`utility functions and classes ` for -recurring tasks and a collection of -:doc:`platform neutral functions ` for improved -portability are provided. - -Included Fortran code has to be compatible with the Fortran 2003 -standard. Python code must be compatible with Python 3.5. Large parts -of LAMMPS (including the :ref:`PYTHON package `) are also -compatible with Python 2.7. Compatibility with Python 2.7 is -desirable, but compatibility with Python 3.5 is **required**. - -Compatibility with these older programming language standards is very -important to maintain portability and availability of LAMMPS on many -platforms. This applies especially to HPC cluster environments, which -tend to be running older software stacks and LAMMPS users may be -required to use those older tools for access to advanced hardware -features or not have the option to install newer compilers or libraries. - -Programming conventions (varied) +Include files (varied) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following is a collection of conventions that should be applied when -writing code for LAMMPS. Following these steps will make it much easier -to integrate your contribution. Please have a look at the existing files -in packages in the src directory for examples. As a demonstration for -how can be adapted to these conventions you may compare the REAXFF -package with the what it looked like when it was called USER-REAXC. If -you are uncertain, please ask. - - system headers or from installed libraries are include with angular brackets (example: ``#include ``), while local include file - use double quotes (example: ``#include "atom.h"``). + use double quotes (example: ``#include "atom.h"``) - when including system header files from the C library use the C++-style names (```` or ````) instead of the @@ -358,6 +39,36 @@ you are uncertain, please ask. - ``using namespace LAMMPS_NS`` or other namespace imports. +- Header files, especially those defining a "style", should only use + the absolute minimum number of include files and **must not** contain + any ``using`` statements. Typically that would be only the header for + the base class. Instead any include statements should be put into the + corresponding implementation files and forward declarations be used. + For implementation files, the "include what you use" principle should + be employed. However, there is the notable exception that when the + ``pointers.h`` header is included (or one of the base classes derived + from it) certain headers will always be included and thus do not need + to be explicitly specified. + These are: `mpi.h`, `cstddef`, `cstdio`, `cstdlib`, `string`, `utils.h`, + `vector`, `fmt/format.h`, `climits`, `cinttypes`. + This also means any such file can assume that `FILE`, `NULL`, and + `INT_MAX` are defined. + +- Header files that define a new LAMMPS style (i.e. that have a + ``SomeStyle(some/name,SomeName);`` macro in them) should only use the + include file for the base class and otherwise use forward declarations + and pointers; when interfacing to a library use the PIMPL (pointer + to implementation) approach where you have a pointer to a struct + that contains all library specific data (and thus requires the library + header) but use a forward declaration and define the struct only in + the implementation file. This is a **strict** requirement since this + is where type clashes between packages and hard to find bugs have + regularly manifested in the past. + + +Miscellaneous standards (varied) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + - I/O is done via the C-style stdio library and **not** iostreams. - Do not use so-called "alternative tokens" like ``and``, ``or``, @@ -404,32 +115,6 @@ you are uncertain, please ask. B(); }; -- Header files, especially those defining a "style", should only use - the absolute minimum number of include files and **must not** contain - any ``using`` statements. Typically that would be only the header for - the base class. Instead any include statements should be put into the - corresponding implementation files and forward declarations be used. - For implementation files, the "include what you use" principle should - be employed. However, there is the notable exception that when the - ``pointers.h`` header is included (or one of the base classes derived - from it) certain headers will always be included and thus do not need - to be explicitly specified. - These are: `mpi.h`, `cstddef`, `cstdio`, `cstdlib`, `string`, `utils.h`, - `vector`, `fmt/format.h`, `climits`, `cinttypes`. - This also means any such file can assume that `FILE`, `NULL`, and - `INT_MAX` are defined. - -- Header files that define a new LAMMPS style (i.e. that have a - ``SomeStyle(some/name,SomeName);`` macro in them) should only use the - include file for the base class and otherwise use forward declarations - and pointers; when interfacing to a library use the PIMPL (pointer - to implementation) approach where you have a pointer to a struct - that contains all library specific data (and thus requires the library - header) but use a forward declaration and define the struct only in - the implementation file. This is a **strict** requirement since this - is where type clashes between packages and hard to find bugs have - regularly manifested in the past. - - Please use clang-format only to reformat files that you have contributed. For header files containing a ``SomeStyle(keyword, ClassName)`` macros it is required to have this macro embedded with a @@ -450,89 +135,49 @@ you are uncertain, please ask. You may also use ``// clang-format on/off`` throughout your files to protect individual sections from being reformatted. -- We rarely accept new styles in the core src folder. Thus please - review the list of :doc:`available Packages ` to see - if your contribution could be added to be added to one of them. It - should fit into the general purposed of that package. If it does not - fit well, it may be added to one of the EXTRA- packages or the MISC - package. +- All files should have 0644 permissions, i.e writable to the user only + and readable by all and no executable permissions. Executable + permissions (0755) should only be on shell scripts or python or similar + scripts for interpreted script languages. + +Whitespace (preferred) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Contributing a package ----------------------- +LAMMPS uses 2 characters per indentation level and lines should be +kept within 100 characters wide. -If your contribution has several related features that are not covered -by one of the existing packages or is dependent on a library (bundled or -external), it is best to make it a package directory with a name like -FOO. In addition to your new files, the directory should contain a -README text file. The README should contain your name and contact -information and a brief description of what your new package does. +Spacing before brackets, after commas, etc. + +Source files should not contain TAB characters unless required by the +syntax (e.g. in makefiles) and no trailing whitespace. Text files +should be added with Unix-style line endings (LF-only). Git will +automatically convert those in both directions when running on Windows; +use dos2unix on Linux machines to convert files. Text files should have +a line ending on the last line. + +You can check for these issues with the python scripts in the +:ref:`"tools/coding_standard" ` folder. When run +normally with a source file or a source folder as argument, they will +list all non-conforming lines. By adding the `-f` flag to the command +line, they will modify the flagged files to try removing the detected +issues. -Build system (strongly preferred) ---------------------------------- +Placement of braces (strongly preferred) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -LAMMPS currently supports two build systems: one that is based on -:doc:`traditional Makefiles ` and one that is based on -:doc:`CMake `. Thus your contribution must be compatible -with and support both. +On new lines for methods, when to use, etc. -For a single pair of header and implementation files that are an -independent feature, it is usually only required to add them to -`src/.gitignore``. - -For traditional make, if your contributed files or package depend on -other LAMMPS style files or packages also being installed (e.g. because -your file is a derived class from the other LAMMPS class), then an -Install.sh file is also needed to check for those dependencies and -modifications to src/Depend.sh to trigger the checks. See other README -and Install.sh files in other directories as examples. - -Similarly for CMake support, changes may need to be made to -cmake/CMakeLists.txt, some of the files in cmake/presets, and possibly a -file with specific instructions needs to be added to -cmake/Modules/Packages/. Please check out how this is handled for -existing packages and ask the LAMMPS developers if you need assistance. +For new files added to the "src" tree, a `clang-format +`_ configuration file is +provided under the name `.clang-format`. This file is compatible with +clang-format version 8 and later. With that file present, files can be +reformatted according to the configuration with a command like: +`clang-format -i new-file.cpp`. Ideally, this is done while writing the +code or before a pull request is submitted. Blocks of code where the +reformatting from clang-format yields undesirable output may be +protected with placing a pair `// clang-format off` and `// clang-format +on` comments around that block. -Citation reminder (suggested) ------------------------------ - -If there is a paper of yours describing your feature (either the -algorithm/science behind the feature itself, or its initial usage, or -its implementation in LAMMPS), you can add the citation to the \*.cpp -source file. See ``src/DIFFRACTION/compute_saed.cpp`` for an example. -A BibTeX format citation is stored in a string variable at the top -of the file and a single line of code registering this variable is -added to the constructor of the class. When your feature is used, -by default, LAMMPS will print the brief info and the DOI -in the first line to the screen and the full citation to the log file. - -If there is additional functionality (which may have been added later) -described in a different publication, additional citation descriptions -may be added for as long as they are only registered when the -corresponding keyword activating this functionality is used. With these -options it is possible to have LAMMPS output a specific citation -reminder whenever a user invokes your feature from their input script. -Please note that you should *only* use this for the *most* relevant -paper for a feature and a publication that you or your group authored. -E.g. adding a citation in the code for a paper by Nose and Hoover if you -write a fix that implements their integrator is not the intended usage. -That latter kind of citation should just be included in the -documentation page you provide describing your contribution. If you are -not sure what the best option would be, please contact the LAMMPS -developers for advice. - - -Testing (optional) ------------------- - -If your contribution contains new utility functions or a supporting class -(i.e. anything that does not depend on a LAMMPS object), new unit tests -should be added to a suitable folder in the ``unittest`` tree. -When adding a new LAMMPS style computing forces or selected fixes, -a ``.yaml`` file with a test configuration and reference data should be -added for the styles where a suitable tester program already exists -(e.g. pair styles, bond styles, etc.). Please see -:ref:`this section in the manual ` for more information on -how to enable, run, and expand testing. From a4d56b56abf695fae64d36cc9a8ab76fb66b66f4 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 27 Apr 2023 10:27:38 -0600 Subject: [PATCH 076/448] Fix bug in atom sorting with triclinic boxes --- src/atom.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/atom.cpp b/src/atom.cpp index 87be0fa4b0..3f2f4550e9 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2271,6 +2271,10 @@ void Atom::sort() for (i = 0; i < nbins; i++) binhead[i] = -1; + // for triclinic, atoms must be in box coords (not lamda) to match bbox + + if (domain->triclinic) domain->lamda2x(nlocal); + for (i = nlocal-1; i >= 0; i--) { ix = static_cast ((x[i][0]-bboxlo[0])*bininvx); iy = static_cast ((x[i][1]-bboxlo[1])*bininvy); @@ -2286,6 +2290,10 @@ void Atom::sort() binhead[ibin] = i; } + // convert back to lamda coords + + if (domain->triclinic) domain->x2lamda(nlocal); + // permute = desired permutation of atoms // permute[I] = J means Ith new atom will be Jth old atom From 1f54dc3ac4f6a774a35c7bd9dad2b7874475b23b Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 27 Apr 2023 11:04:39 -0600 Subject: [PATCH 077/448] Port changes to Kokkos --- src/KOKKOS/atom_kokkos.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 938d9709e9..ac76a87938 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -165,6 +165,10 @@ void AtomKokkos::sort() if (nlocal == nmax) avec->grow(0); + // for triclinic, atoms must be in box coords (not lamda) to match bbox + + if (domain->triclinic) domain->lamda2x(nlocal); + sync(Host, ALL_MASK); modified(Host, ALL_MASK); @@ -188,6 +192,10 @@ void AtomKokkos::sort() binhead[ibin] = i; } + // convert back to lamda coords + + if (domain->triclinic) domain->x2lamda(nlocal); + // permute = desired permutation of atoms // permute[I] = J means Ith new atom will be Jth old atom From c95a349faea0e56b4d4f178af33391205081f386 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 27 Apr 2023 11:07:04 -0600 Subject: [PATCH 078/448] Small tweak --- src/KOKKOS/atom_kokkos.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index ac76a87938..5c1451d0cc 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -170,7 +170,6 @@ void AtomKokkos::sort() if (domain->triclinic) domain->lamda2x(nlocal); sync(Host, ALL_MASK); - modified(Host, ALL_MASK); // bin atoms in reverse order so linked list will be in forward order @@ -192,10 +191,6 @@ void AtomKokkos::sort() binhead[ibin] = i; } - // convert back to lamda coords - - if (domain->triclinic) domain->x2lamda(nlocal); - // permute = desired permutation of atoms // permute[I] = J means Ith new atom will be Jth old atom @@ -241,6 +236,12 @@ void AtomKokkos::sort() //int flagall; //MPI_Allreduce(&flag,&flagall,1,MPI_INT,MPI_SUM,world); //if (flagall) errorX->all(FLERR,"Atom sort did not operate correctly"); + + modified(Host, ALL_MASK); + + // convert back to lamda coords + + if (domain->triclinic) domain->x2lamda(nlocal); } /* ---------------------------------------------------------------------- From 7c3deba4a65b138df703ccb53ea09d2082e457e1 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 27 Apr 2023 11:21:31 -0600 Subject: [PATCH 079/448] whitespace --- src/KOKKOS/atom_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 5c1451d0cc..0cc682eda9 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -240,7 +240,7 @@ void AtomKokkos::sort() modified(Host, ALL_MASK); // convert back to lamda coords - + if (domain->triclinic) domain->x2lamda(nlocal); } From 7791ab728fe40ba5c329c1973116893bb0bb3e05 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 27 Apr 2023 11:25:34 -0600 Subject: [PATCH 080/448] Fix small issue --- src/KOKKOS/atom_kokkos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index 12db89d117..f9fa31bf2a 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -223,9 +223,10 @@ void AtomKokkos::sort_device() kkbase->sort_kokkos(Sorter); } + } // convert back to lamda coords - + if (domain->triclinic) domain->x2lamda(nlocal); } From 50adf2b340de20dfd94c61235a112971e44c4548 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 27 Apr 2023 15:17:54 -0600 Subject: [PATCH 081/448] Add a couple notes to the docs --- doc/src/Speed_kokkos.rst | 10 ++++++++++ doc/src/atom_modify.rst | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/doc/src/Speed_kokkos.rst b/doc/src/Speed_kokkos.rst index 569a24f1c2..dd417d7c79 100644 --- a/doc/src/Speed_kokkos.rst +++ b/doc/src/Speed_kokkos.rst @@ -285,6 +285,16 @@ one or more nodes, each with two GPUs: settings. Experimenting with its options can provide a speed-up for specific calculations. For example: +.. note:: + + The default binsize for :doc:`atom sorting ` on GPUs + is equal to the default CPU neighbor binsize (i.e. 2x smaller than the + default neighbor binsize on GPUs). When running simple pair-wise + potentials like Lennard Jones on GPUs, using a 2x larger binsize for + atom sorting (equal to the default binsize for building the neighbor + list on GPUs) and a more frequent sorting than default (e.g. sorting + every 100 time steps instead of 1000) may improve performance. + .. code-block:: bash mpirun -np 2 lmp_kokkos_cuda_openmpi -k on g 2 -sf kk -pk kokkos newton on neigh half binsize 2.8 -in in.lj # Newton on, half neighbor list, set binsize = neighbor ghost cutoff diff --git a/doc/src/atom_modify.rst b/doc/src/atom_modify.rst index 9049a24fde..1e5a3d49ff 100644 --- a/doc/src/atom_modify.rst +++ b/doc/src/atom_modify.rst @@ -153,6 +153,13 @@ cache locality will be undermined. order of atoms in a :doc:`dump ` file will also typically change if sorting is enabled. +.. note:: + + When running simple pair-wise potentials like Lennard Jones on GPUs + with the KOKKOS package, using a larger binsize (e.g. 2x larger than + default) and a more frequent reordering than default (e.g. every 100 + time steps) may improve performance. + Restrictions """""""""""" From b17f9ac10e6efecbc4110a0aa5d8896046932c7f Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 27 Apr 2023 15:21:30 -0600 Subject: [PATCH 082/448] Small tweak to docs --- doc/src/Speed_kokkos.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/Speed_kokkos.rst b/doc/src/Speed_kokkos.rst index dd417d7c79..8161e69a1c 100644 --- a/doc/src/Speed_kokkos.rst +++ b/doc/src/Speed_kokkos.rst @@ -289,11 +289,11 @@ one or more nodes, each with two GPUs: The default binsize for :doc:`atom sorting ` on GPUs is equal to the default CPU neighbor binsize (i.e. 2x smaller than the - default neighbor binsize on GPUs). When running simple pair-wise + default GPU neighbor binsize). When running simple pair-wise potentials like Lennard Jones on GPUs, using a 2x larger binsize for - atom sorting (equal to the default binsize for building the neighbor - list on GPUs) and a more frequent sorting than default (e.g. sorting - every 100 time steps instead of 1000) may improve performance. + atom sorting (equal to the default GPU neighbor binsize) and a more + frequent sorting than default (e.g. sorting every 100 time steps + instead of 1000) may improve performance. .. code-block:: bash From 8d6c3a7536bfaef5070d0699455d6e115be10121 Mon Sep 17 00:00:00 2001 From: Shern Tee Date: Fri, 28 Apr 2023 14:50:09 +1000 Subject: [PATCH 083/448] Fix Markdown table in tools/tabulate/README.md --- tools/tabulate/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/tabulate/README.md b/tools/tabulate/README.md index 0430c39111..d3b4df0738 100644 --- a/tools/tabulate/README.md +++ b/tools/tabulate/README.md @@ -17,7 +17,6 @@ numerical differentiation. Please see the individual tabulation scripts in this folder for examples: -| ------------------------------|-------------------------------------------------------------------------------| | File | Description | | ------------------------------|-------------------------------------------------------------------------------| | pair_lj_tabulate.py | creates two Lennard-Jones pair potential tables with different parameters | @@ -28,7 +27,6 @@ Please see the individual tabulation scripts in this folder for examples: | wall_harmonic_tabulate.py | creates a table for fix wall/table with a simple repulsive harmonic potential | | wall_multi_tabulate.py | creates a table for fix wall/table with multiple tables | | pair_bi_tabulate.py | creates a table from radial distribution file using Boltzmann Inversion | -| ------------------------------|-------------------------------------------------------------------------------| Common command line flags: From 235372d6e811a229d45d1913b77e413ec3d58827 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 28 Apr 2023 14:40:59 -0600 Subject: [PATCH 084/448] Fuse some Kokkos kernels to reduce launch latency for small systems --- src/KOKKOS/fix_nve_kokkos.cpp | 30 ++++++++++++++++++++++++ src/KOKKOS/fix_nve_kokkos.h | 20 ++++++++++++++++ src/KOKKOS/modify_kokkos.cpp | 19 +++++++++++++++ src/KOKKOS/modify_kokkos.h | 1 + src/KOKKOS/pair_kokkos.h | 26 +++++++++++++++++++++ src/KOKKOS/verlet_kokkos.cpp | 44 ++++++++++++++++++++++++++++++++--- src/KOKKOS/verlet_kokkos.h | 3 +++ src/fix.cpp | 6 ++--- src/fix.h | 4 +++- src/modify.cpp | 30 ++++++++++++++++++++++++ src/modify.h | 3 +++ src/pair.cpp | 7 +++--- src/pair.h | 3 ++- src/timer.h | 1 + 14 files changed, 185 insertions(+), 12 deletions(-) diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index 5dcb611d41..f812c575bc 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -29,6 +29,7 @@ FixNVEKokkos::FixNVEKokkos(LAMMPS *lmp, int narg, char **arg) : FixNVE(lmp, narg, arg) { kokkosable = 1; + fuse_integrate_flag = 1; atomKK = (AtomKokkos *) atom; execution_space = ExecutionSpaceFromDevice::space; @@ -168,6 +169,35 @@ void FixNVEKokkos::cleanup_copy() vatom = nullptr; } +/* ---------------------------------------------------------------------- + allow for both per-type and per-atom mass +------------------------------------------------------------------------- */ + +template +void FixNVEKokkos::fused_integrate() +{ + atomKK->sync(execution_space,datamask_read); + atomKK->modified(execution_space,datamask_modify); + + x = atomKK->k_x.view(); + v = atomKK->k_v.view(); + f = atomKK->k_f.view(); + rmass = atomKK->k_rmass.view(); + mass = atomKK->k_mass.view(); + type = atomKK->k_type.view(); + mask = atomKK->k_mask.view(); + int nlocal = atomKK->nlocal; + if (igroup == atomKK->firstgroup) nlocal = atomKK->nfirst; + + if (rmass.data()) { + FixNVEKokkosFusedIntegrateFunctor functor(this); + Kokkos::parallel_for(nlocal,functor); + } else { + FixNVEKokkosFusedIntegrateFunctor functor(this); + Kokkos::parallel_for(nlocal,functor); + } +} + namespace LAMMPS_NS { template class FixNVEKokkos; #ifdef LMP_KOKKOS_GPU diff --git a/src/KOKKOS/fix_nve_kokkos.h b/src/KOKKOS/fix_nve_kokkos.h index 215aacb4a0..a10f846cba 100644 --- a/src/KOKKOS/fix_nve_kokkos.h +++ b/src/KOKKOS/fix_nve_kokkos.h @@ -46,6 +46,7 @@ class FixNVEKokkos : public FixNVE { void init() override; void initial_integrate(int) override; void final_integrate() override; + void fused_integrate() override; KOKKOS_INLINE_FUNCTION void initial_integrate_item(int) const; @@ -96,6 +97,25 @@ struct FixNVEKokkosFinalIntegrateFunctor { } }; +template +struct FixNVEKokkosFusedIntegrateFunctor { + typedef DeviceType device_type ; + FixNVEKokkos c; + + FixNVEKokkosFusedIntegrateFunctor(FixNVEKokkos* c_ptr): + c(*c_ptr) {c.cleanup_copy();}; + KOKKOS_INLINE_FUNCTION + void operator()(const int i) const { + if (RMass) { + c.final_integrate_rmass_item(i); + c.initial_integrate_rmass_item(i); + } else { + c.final_integrate_item(i); + c.initial_integrate_item(i); + } + } +}; + } #endif diff --git a/src/KOKKOS/modify_kokkos.cpp b/src/KOKKOS/modify_kokkos.cpp index 9d8c16603e..581f6598f1 100644 --- a/src/KOKKOS/modify_kokkos.cpp +++ b/src/KOKKOS/modify_kokkos.cpp @@ -392,6 +392,25 @@ void ModifyKokkos::final_integrate() } } + +/* ---------------------------------------------------------------------- + 2nd half of integrate call, only for relevant fixes +------------------------------------------------------------------------- */ + +void ModifyKokkos::fused_integrate() +{ + for (int i = 0; i < n_final_integrate; i++) { + atomKK->sync(fix[list_final_integrate[i]]->execution_space, + fix[list_final_integrate[i]]->datamask_read); + int prev_auto_sync = lmp->kokkos->auto_sync; + if (!fix[list_final_integrate[i]]->kokkosable) lmp->kokkos->auto_sync = 1; + fix[list_final_integrate[i]]->fused_integrate(); + lmp->kokkos->auto_sync = prev_auto_sync; + atomKK->modified(fix[list_final_integrate[i]]->execution_space, + fix[list_final_integrate[i]]->datamask_modify); + } +} + /* ---------------------------------------------------------------------- end-of-timestep call, only for relevant fixes only call fix->end_of_step() on timesteps that are multiples of nevery diff --git a/src/KOKKOS/modify_kokkos.h b/src/KOKKOS/modify_kokkos.h index 5edf5cd662..e440693fbb 100644 --- a/src/KOKKOS/modify_kokkos.h +++ b/src/KOKKOS/modify_kokkos.h @@ -39,6 +39,7 @@ class ModifyKokkos : public Modify { void pre_reverse(int,int) override; void post_force(int) override; void final_integrate() override; + void fused_integrate() override; void end_of_step() override; double energy_couple() override; double energy_global() override; diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index 0ff244f67d..7551d03f89 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -280,6 +280,12 @@ struct PairComputeFunctor { const X_FLOAT ztmp = c.x(i,2); const int itype = c.type(i); + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) = 0.0; + f(i,1) = 0.0; + f(i,2) = 0.0; + }); + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; @@ -337,6 +343,12 @@ struct PairComputeFunctor { const int itype = c.type(i); const F_FLOAT qtmp = c.q(i); + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) = 0.0; + f(i,1) = 0.0; + f(i,2) = 0.0; + }); + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; @@ -399,6 +411,12 @@ struct PairComputeFunctor { const X_FLOAT ztmp = c.x(i,2); const int itype = c.type(i); + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) = 0.0; + f(i,1) = 0.0; + f(i,2) = 0.0; + }); + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; @@ -495,6 +513,12 @@ struct PairComputeFunctor { const int itype = c.type(i); const F_FLOAT qtmp = c.q(i); + Kokkos::single(Kokkos::PerThread(team), [&] (){ + f(i,0) = 0.0; + f(i,1) = 0.0; + f(i,2) = 0.0; + }); + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; @@ -743,6 +767,8 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename std::enable_if<(NEIG fpair->lmp->kokkos->neigh_thread = 1; if (fpair->lmp->kokkos->neigh_thread) { + fpair->fuse_force_clear_flag = 1; + int vector_length = 8; int atoms_per_team = 32; diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index 01401542cd..0339df663b 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -296,7 +296,9 @@ void VerletKokkos::run(int n) // initial time integration timer->stamp(); - modify->initial_integrate(vflag); + fuse_check(i,n); + if (!fuse_integrate) + modify->initial_integrate(vflag); if (n_post_integrate) modify->post_integrate(); timer->stamp(Timer::MODIFY); @@ -362,7 +364,8 @@ void VerletKokkos::run(int n) // since some bonded potentials tally pairwise energy/virial // and Pair:ev_tally() needs to be called before any tallying - force_clear(); + if (!fuse_force_clear) + force_clear(); timer->stamp(); @@ -494,7 +497,10 @@ void VerletKokkos::run(int n) // force modifications, final time integration, diagnostics if (n_post_force) modify->post_force(vflag); - modify->final_integrate(); + + if (fuse_integrate) modify->fused_integrate(); + else modify->final_integrate(); + if (n_end_of_step) modify->end_of_step(); timer->stamp(Timer::MODIFY); @@ -593,3 +599,35 @@ void VerletKokkos::force_clear() } } } + +/* ---------------------------------------------------------------------- + check if can fuse force_clear() with pair compute() + Requirements: + - no pre_force fixes + - no torques, SPIN forces, or includegroup set + - pair compute() must be called + - pair_style must support fusing + + check if can fuse initial_integrate() with final_integrate() + Requirements: + - no end_of_step fixes + - not on first, last, or output step + - no timers to break out of loop + - integrate fix style must support fusing +------------------------------------------------------------------------- */ + +void VerletKokkos::fuse_check(int i, int n) +{ + fuse_force_clear = 0; + if (modify->n_pre_force) fuse_force_clear = 0; + if (torqueflag || extraflag || neighbor->includegroup) fuse_force_clear = 0; + if (!pair_compute_flag) fuse_force_clear = 0; + if (!force->pair->fuse_force_clear_flag) fuse_force_clear = 0; + + fuse_integrate = 0; + if (modify->n_end_of_step) fuse_integrate = 0; + if (i == 0 || i == n-1) fuse_integrate = 0; + if (update->ntimestep == output->next) fuse_integrate = 0; + if (timer->has_timeout()) fuse_integrate = 0; + if (!modify->check_fuse_integrate()) fuse_integrate = 0; +} diff --git a/src/KOKKOS/verlet_kokkos.h b/src/KOKKOS/verlet_kokkos.h index 067df54f4f..c71211c542 100644 --- a/src/KOKKOS/verlet_kokkos.h +++ b/src/KOKKOS/verlet_kokkos.h @@ -46,6 +46,9 @@ class VerletKokkos : public Verlet { protected: DAT::t_f_array f_merge_copy,f; + int fuse_force_clear,fuse_integrate; + + void fuse_check(int, int); }; } diff --git a/src/fix.cpp b/src/fix.cpp index 1d41ad3943..02adcbd016 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -102,15 +102,15 @@ Fix::Fix(LAMMPS *lmp, int /*narg*/, char **arg) : vflag_atom = cvflag_atom = 0; centroidstressflag = CENTROID_SAME; - // KOKKOS per-fix data masks + // KOKKOS package execution_space = Host; datamask_read = ALL_MASK; datamask_modify = ALL_MASK; - kokkosable = 0; + kokkosable = copymode = 0; forward_comm_device = exchange_comm_device = 0; - copymode = 0; + fuse_integrate_flag = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/fix.h b/src/fix.h index b47cfb2f4a..23b120d989 100644 --- a/src/fix.h +++ b/src/fix.h @@ -127,11 +127,12 @@ class Fix : protected Pointers { int restart_reset; // 1 if restart just re-initialized fix - // KOKKOS host/device flag and data masks + // KOKKOS flags and variables int kokkosable; // 1 if Kokkos fix int forward_comm_device; // 1 if forward comm on Device int exchange_comm_device; // 1 if exchange comm on Device + int fuse_integrate_flag; // 1 if can fuse initial integrate with final integrate ExecutionSpace execution_space; unsigned int datamask_read, datamask_modify; @@ -152,6 +153,7 @@ class Fix : protected Pointers { virtual void setup_pre_reverse(int, int) {} virtual void min_setup(int) {} virtual void initial_integrate(int) {} + virtual void fused_integrate() {} virtual void post_integrate() {} virtual void pre_exchange() {} virtual void pre_neighbor() {} diff --git a/src/modify.cpp b/src/modify.cpp index d0656d3895..71f7cb8889 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -475,6 +475,17 @@ void Modify::final_integrate() for (int i = 0; i < n_final_integrate; i++) fix[list_final_integrate[i]]->final_integrate(); } + +/* ---------------------------------------------------------------------- + 2nd half of integrate call, only for relevant fixes +------------------------------------------------------------------------- */ + +void Modify::fused_integrate() +{ + for (int i = 0; i < n_final_integrate; i++) + fix[list_final_integrate[i]]->fused_integrate(); +} + /* ---------------------------------------------------------------------- end-of-timestep call, only for relevant fixes only call fix->end_of_step() on timesteps that are multiples of nevery @@ -1799,3 +1810,22 @@ double Modify::memory_usage() for (int i = 0; i < ncompute; i++) bytes += compute[i]->memory_usage(); return bytes; } + +/* ---------------------------------------------------------------------- + check if initial and final integrate can be fused +------------------------------------------------------------------------- */ + +int Modify::check_fuse_integrate() +{ + int fuse_integrate_flag = 1; + + for (int i = 0; i < n_initial_integrate; i++) + if (!fix[list_initial_integrate[i]]->fuse_integrate_flag) + fuse_integrate_flag = 0; + + for (int i = 0; i < n_final_integrate; i++) + if (!fix[list_final_integrate[i]]->fuse_integrate_flag) + fuse_integrate_flag = 0; + + return fuse_integrate_flag; +} diff --git a/src/modify.h b/src/modify.h index 7a3f54c277..da3cab55d2 100644 --- a/src/modify.h +++ b/src/modify.h @@ -61,6 +61,7 @@ class Modify : protected Pointers { virtual void setup_pre_force(int); virtual void setup_pre_reverse(int, int); virtual void initial_integrate(int); + virtual void fused_integrate(); virtual void post_integrate(); virtual void pre_exchange(); virtual void pre_neighbor(); @@ -150,6 +151,8 @@ class Modify : protected Pointers { double memory_usage(); + int check_fuse_integrate(); + protected: // internal fix counts diff --git a/src/pair.cpp b/src/pair.cpp index 9ae24e1e93..34c8e4978e 100644 --- a/src/pair.cpp +++ b/src/pair.cpp @@ -116,15 +116,14 @@ Pair::Pair(LAMMPS *lmp) : nondefault_history_transfer = 0; beyond_contact = 0; - // KOKKOS per-fix data masks + // KOKKOS package execution_space = Host; datamask_read = ALL_MASK; datamask_modify = ALL_MASK; - kokkosable = 0; - reverse_comm_device = 0; - copymode = 0; + kokkosable = copymode = 0; + reverse_comm_device = fuse_force_clear_flag = 0; } /* ---------------------------------------------------------------------- */ diff --git a/src/pair.h b/src/pair.h index 8c856660e9..d36b48f340 100644 --- a/src/pair.h +++ b/src/pair.h @@ -119,12 +119,13 @@ class Pair : protected Pointers { int beyond_contact, nondefault_history_transfer; // for granular styles - // KOKKOS host/device flag and data masks + // KOKKOS flags and variables ExecutionSpace execution_space; unsigned int datamask_read, datamask_modify; int kokkosable; // 1 if Kokkos pair int reverse_comm_device; // 1 if reverse comm on Device + int fuse_force_clear_flag; // 1 if can fuse force clear with force compute Pair(class LAMMPS *); ~Pair() override; diff --git a/src/timer.h b/src/timer.h index 5c100db1c0..f7efa5ac64 100644 --- a/src/timer.h +++ b/src/timer.h @@ -63,6 +63,7 @@ class Timer : protected Pointers { bool has_normal() const { return (_level >= NORMAL); } bool has_full() const { return (_level >= FULL); } bool has_sync() const { return (_sync != OFF); } + bool has_timeout() const { return (_timeout >= 0.0); } // flag if wallclock time is expired bool is_timeout() const { return (_timeout == 0.0); } From 29a2b58ab625b9ea6361a0e82a14369ec91fbc68 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 28 Apr 2023 14:57:19 -0600 Subject: [PATCH 085/448] Small cleanup --- src/KOKKOS/modify_kokkos.cpp | 21 ++++++++++++++++++++- src/KOKKOS/modify_kokkos.h | 2 ++ src/KOKKOS/verlet_kokkos.cpp | 4 ++-- src/modify.cpp | 30 ------------------------------ src/modify.h | 4 +--- 5 files changed, 25 insertions(+), 36 deletions(-) diff --git a/src/KOKKOS/modify_kokkos.cpp b/src/KOKKOS/modify_kokkos.cpp index 581f6598f1..d0f57df8dc 100644 --- a/src/KOKKOS/modify_kokkos.cpp +++ b/src/KOKKOS/modify_kokkos.cpp @@ -394,7 +394,7 @@ void ModifyKokkos::final_integrate() /* ---------------------------------------------------------------------- - 2nd half of integrate call, only for relevant fixes + fused initial and final integrate call, only for relevant fixes ------------------------------------------------------------------------- */ void ModifyKokkos::fused_integrate() @@ -900,3 +900,22 @@ int ModifyKokkos::min_reset_ref() } return itmpall; } + +/* ---------------------------------------------------------------------- + check if initial and final integrate can be fused +------------------------------------------------------------------------- */ + +int ModifyKokkos::check_fuse_integrate() +{ + int fuse_integrate_flag = 1; + + for (int i = 0; i < n_initial_integrate; i++) + if (!fix[list_initial_integrate[i]]->fuse_integrate_flag) + fuse_integrate_flag = 0; + + for (int i = 0; i < n_final_integrate; i++) + if (!fix[list_final_integrate[i]]->fuse_integrate_flag) + fuse_integrate_flag = 0; + + return fuse_integrate_flag; +} diff --git a/src/KOKKOS/modify_kokkos.h b/src/KOKKOS/modify_kokkos.h index e440693fbb..8dd9e6d9df 100644 --- a/src/KOKKOS/modify_kokkos.h +++ b/src/KOKKOS/modify_kokkos.h @@ -70,6 +70,8 @@ class ModifyKokkos : public Modify { int min_dof() override; int min_reset_ref() override; + int check_fuse_integrate(); + protected: }; diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index 0339df663b..2b70f3db61 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -27,7 +27,7 @@ #include "kspace.h" #include "output.h" #include "update.h" -#include "modify.h" +#include "modify_kokkos.h" #include "timer.h" #include "memory_kokkos.h" #include "kokkos.h" @@ -629,5 +629,5 @@ void VerletKokkos::fuse_check(int i, int n) if (i == 0 || i == n-1) fuse_integrate = 0; if (update->ntimestep == output->next) fuse_integrate = 0; if (timer->has_timeout()) fuse_integrate = 0; - if (!modify->check_fuse_integrate()) fuse_integrate = 0; + if (!((ModifyKokkos*)modify)->check_fuse_integrate()) fuse_integrate = 0; } diff --git a/src/modify.cpp b/src/modify.cpp index 71f7cb8889..d0656d3895 100644 --- a/src/modify.cpp +++ b/src/modify.cpp @@ -475,17 +475,6 @@ void Modify::final_integrate() for (int i = 0; i < n_final_integrate; i++) fix[list_final_integrate[i]]->final_integrate(); } - -/* ---------------------------------------------------------------------- - 2nd half of integrate call, only for relevant fixes -------------------------------------------------------------------------- */ - -void Modify::fused_integrate() -{ - for (int i = 0; i < n_final_integrate; i++) - fix[list_final_integrate[i]]->fused_integrate(); -} - /* ---------------------------------------------------------------------- end-of-timestep call, only for relevant fixes only call fix->end_of_step() on timesteps that are multiples of nevery @@ -1810,22 +1799,3 @@ double Modify::memory_usage() for (int i = 0; i < ncompute; i++) bytes += compute[i]->memory_usage(); return bytes; } - -/* ---------------------------------------------------------------------- - check if initial and final integrate can be fused -------------------------------------------------------------------------- */ - -int Modify::check_fuse_integrate() -{ - int fuse_integrate_flag = 1; - - for (int i = 0; i < n_initial_integrate; i++) - if (!fix[list_initial_integrate[i]]->fuse_integrate_flag) - fuse_integrate_flag = 0; - - for (int i = 0; i < n_final_integrate; i++) - if (!fix[list_final_integrate[i]]->fuse_integrate_flag) - fuse_integrate_flag = 0; - - return fuse_integrate_flag; -} diff --git a/src/modify.h b/src/modify.h index da3cab55d2..9686a9a7ec 100644 --- a/src/modify.h +++ b/src/modify.h @@ -61,7 +61,7 @@ class Modify : protected Pointers { virtual void setup_pre_force(int); virtual void setup_pre_reverse(int, int); virtual void initial_integrate(int); - virtual void fused_integrate(); + virtual void fused_integrate() {} virtual void post_integrate(); virtual void pre_exchange(); virtual void pre_neighbor(); @@ -151,8 +151,6 @@ class Modify : protected Pointers { double memory_usage(); - int check_fuse_integrate(); - protected: // internal fix counts From 24e7204b51c7392e1dc556394028b76d163354a5 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 28 Apr 2023 15:00:50 -0600 Subject: [PATCH 086/448] whitespace --- src/KOKKOS/modify_kokkos.cpp | 1 - src/KOKKOS/pair_kokkos.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/KOKKOS/modify_kokkos.cpp b/src/KOKKOS/modify_kokkos.cpp index d0f57df8dc..44fcb48727 100644 --- a/src/KOKKOS/modify_kokkos.cpp +++ b/src/KOKKOS/modify_kokkos.cpp @@ -392,7 +392,6 @@ void ModifyKokkos::final_integrate() } } - /* ---------------------------------------------------------------------- fused initial and final integrate call, only for relevant fixes ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index 7551d03f89..dd274ca8c2 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -416,7 +416,7 @@ struct PairComputeFunctor { f(i,1) = 0.0; f(i,2) = 0.0; }); - + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; From f66cf7c9e8a8a02d552e7a7dd489d1acc1f3a334 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 28 Apr 2023 16:15:55 -0600 Subject: [PATCH 087/448] Revert testing change --- src/KOKKOS/verlet_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index 2b70f3db61..4e564a6ef2 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -618,13 +618,13 @@ void VerletKokkos::force_clear() void VerletKokkos::fuse_check(int i, int n) { - fuse_force_clear = 0; + fuse_force_clear = 1; if (modify->n_pre_force) fuse_force_clear = 0; if (torqueflag || extraflag || neighbor->includegroup) fuse_force_clear = 0; if (!pair_compute_flag) fuse_force_clear = 0; if (!force->pair->fuse_force_clear_flag) fuse_force_clear = 0; - fuse_integrate = 0; + fuse_integrate = 1; if (modify->n_end_of_step) fuse_integrate = 0; if (i == 0 || i == n-1) fuse_integrate = 0; if (update->ntimestep == output->next) fuse_integrate = 0; From 2c8a49bb2600d4ebcf54c8a991a72d2845d36d8a Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Sat, 29 Apr 2023 18:14:24 -0600 Subject: [PATCH 088/448] new compute count_type --- src/compute_count_type.cpp | 165 +++++++++++++++++++++++++++++++++++++ src/compute_count_type.h | 46 +++++++++++ src/lmptype.h | 5 +- 3 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 src/compute_count_type.cpp create mode 100644 src/compute_count_type.h diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp new file mode 100644 index 0000000000..707a4bb943 --- /dev/null +++ b/src/compute_count_type.cpp @@ -0,0 +1,165 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#include "compute_count_type.h" + +#include "atom.h" +#include "atom_vec.h" +#include "domain.h" +#include "error.h" +#include "force.h" +#include "group.h" +#include "update.h" + +using namespace LAMMPS_NS; + +enum{ATOM,BOND}; + +/* ---------------------------------------------------------------------- */ + +ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) +{ + if (narg != 4) error->all(FLERR, "Illegal compute count/type command"); + + // process args + + if (strcmp(arg[3],"atom") == 0) mode = ATOM; + else if (strcmp(arg[3],"bond") == 0) mode = BOND; + else error->all(FLERR, "Invalid compute count/type keyword {}",arg[3]); + + if (mode == ATOM) { + vector_flag = 1; + size_vector = atom->ntypes; + extvector = 1; + } else if (mode == BOND) { + scalar_flag = vector_flag = 1; + size_vector = atom->nbondtypes; + extscalar = 1; + extvector = 1; + } + + if (mode == BOND && !atom->avec->bonds_allow) + error->all(FLERR,"Cannot use compute count/type bond command with no bonds allowed"); + + vector = new double[size_vector]; + + // work vectors + + count = new int[size_vector]; + bcount_me = new bigint[size_vector]; + bcount = new bigint[size_vector]; +} + +/* ---------------------------------------------------------------------- */ + +ComputeCountType::~ComputeCountType() +{ + delete[] vector; +} + +/* ---------------------------------------------------------------------- + only invoked for mode = BOND to count broken bonds + broken bonds have bond_type = 0 +---------------------------------------------------------------------- */ + +double ComputeCountType::compute_scalar() +{ + invoked_scalar = update->ntimestep; + + int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; + int nlocal = atom->nlocal; + + int nbond; + int count = 0; + + for (int i = 0; i < nlocal; i++) { + nbond = num_bond[i]; + for (int m = 0; m < nbond; m++) + if (bond_type[i][m] == 0) count++; + } + + // sum across procs as bigint, then convert to double + // correct for double counting if newton_bond off + + bigint bcount_me = count; + bigint bcount; + MPI_Allreduce(&bcount_me, &bcount, 1, MPI_LMP_BIGINT, MPI_SUM, world); + if (force->newton_bond == 0) bcount /= 2; + + if (bcount > MAXDOUBLEINT) + error->all(FLERR,"Compute count/type overflow"); + double scalar = bcount; + return scalar; +} + +/* ---------------------------------------------------------------------- */ + +void ComputeCountType::compute_vector() +{ + invoked_vector = update->ntimestep; + + int n; + + // count atoms by type + + if (mode == ATOM) { + int *type = atom->type; + int nlocal = atom->nlocal; + int ntypes = atom->ntypes; + + for (int m = 0; m < ntypes; m++) count[m] = 0; + for (int i = 0; i < nlocal; i++) count[type[i]-1]++; + + n = ntypes; + } + + // count bonds by type + // skip type = 0 bonds, they are counted by compute_scalar + // bond types can be negative for SHAKE + + else if (mode == BOND) { + int *num_bond = atom->num_bond; + int **bond_type = atom->bond_type; + int nlocal = atom->nlocal; + int nbondtypes = atom->nbondtypes; + + int nbond,itype; + for (int m = 0; m < nbondtypes; m++) count[m] = 0; + + for (int i = 0; i < nlocal; i++) { + nbond = num_bond[i]; + for (int m = 0; m < nbond; m++) { + itype = bond_type[i][m]; + if (itype == 0) continue; + if (itype > 0) count[itype-1]++; + else count[-itype-1]++; + } + } + + n = nbondtypes; + } + + // sum across procs as bigint, then convert to double + // correct for double counting if newton_bond off + + for (int m = 0; m < n; m++) bcount_me[m] = count[m]; + MPI_Allreduce(&bcount_me, &bcount, 1, MPI_LMP_BIGINT, MPI_SUM, world); + if (force->newton_bond == 0) + for (int m = 0; m < n; m++) bcount[m] /= 2; + + for (int m = 0; m < n; m++) + if (bcount[m] > MAXDOUBLEINT) + error->all(FLERR,"Compute count/type overflow"); + for (int m = 0; m < n; m++) vector[m] *= bcount[m]; +} diff --git a/src/compute_count_type.h b/src/compute_count_type.h new file mode 100644 index 0000000000..0ed7a22467 --- /dev/null +++ b/src/compute_count_type.h @@ -0,0 +1,46 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef COMPUTE_CLASS +// clang-format off +ComputeStyle(count/type,ComputeCountType); +// clang-format on +#else + +#ifndef LMP_COMPUTE_COMPUTE_TYPE_H +#define LMP_COMPUTE_COMPUTE_TYPE_H + +#include "compute.h" + +namespace LAMMPS_NS { + +class ComputeCountType : public Compute { + public: + ComputeCountType(class LAMMPS *, int, char **); + ~ComputeCountType() override; + void init() override {} + double compute_scalar() override; + void compute_vector() override; + + protected: + int mode; + + int *count; + bigint *bcount_me; + bigint *bcount; +}; + +} // namespace LAMMPS_NS + +#endif +#endif diff --git a/src/lmptype.h b/src/lmptype.h index bf56d07d77..891d5bdf89 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -95,7 +95,8 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT_MAX #define MAXBIGINT INT64_MAX - +#define MAXDOUBLEINT 9007199254740992 // 2^53 + #define MPI_LMP_TAGINT MPI_INT #define MPI_LMP_IMAGEINT MPI_INT #define MPI_LMP_BIGINT MPI_LL @@ -132,6 +133,7 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT64_MAX #define MAXBIGINT INT64_MAX +#define MAXDOUBLEINT 9007199254740992 // 2^53 #define MPI_LMP_TAGINT MPI_LL #define MPI_LMP_IMAGEINT MPI_LL @@ -168,6 +170,7 @@ typedef int bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT_MAX #define MAXBIGINT INT_MAX +#define MAXDOUBLEINT INT_MAX #define MPI_LMP_TAGINT MPI_INT #define MPI_LMP_IMAGEINT MPI_INT From f644f7078cb782702df393dafce4248c36c84ff9 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Sat, 29 Apr 2023 18:50:15 -0600 Subject: [PATCH 089/448] doc page for new command --- doc/src/Commands_compute.rst | 1 + doc/src/bond_style.rst | 14 +++--- doc/src/compute.rst | 1 + doc/src/compute_count_type.rst | 89 ++++++++++++++++++++++++++++++++++ src/compute_count_type.cpp | 8 ++- 5 files changed, 105 insertions(+), 8 deletions(-) create mode 100644 doc/src/compute_count_type.rst diff --git a/doc/src/Commands_compute.rst b/doc/src/Commands_compute.rst index 2f9c8b03fb..755000c976 100644 --- a/doc/src/Commands_compute.rst +++ b/doc/src/Commands_compute.rst @@ -46,6 +46,7 @@ KOKKOS, o = OPENMP, t = OPT. * :doc:`com/chunk ` * :doc:`contact/atom ` * :doc:`coord/atom (k) ` + * :doc:`count/type ` * :doc:`damage/atom ` * :doc:`dihedral ` * :doc:`dihedral/local ` diff --git a/doc/src/bond_style.rst b/doc/src/bond_style.rst index b33d0a9e9a..95f463e695 100644 --- a/doc/src/bond_style.rst +++ b/doc/src/bond_style.rst @@ -32,13 +32,13 @@ Set the formula(s) LAMMPS uses to compute bond interactions between pairs of atoms. In LAMMPS, a bond differs from a pairwise interaction, which are set via the :doc:`pair_style ` command. Bonds are defined between specified pairs of atoms and -remain in force for the duration of the simulation (unless the bond -breaks which is possible in some bond potentials). The list of bonded -atoms is read in by a :doc:`read_data ` or -:doc:`read_restart ` command from a data or restart file. -By contrast, pair potentials are typically defined between all pairs -of atoms within a cutoff distance and the set of active interactions -changes over time. +remain in force for the duration of the simulation (unless new bonds +are created or existing bonds break, which is possible in some fixes +and bond potentials). The list of bonded atoms is read in by a +:doc:`read_data ` or :doc:`read_restart ` +command from a data or restart file. By contrast, pair potentials are +typically defined between all pairs of atoms within a cutoff distance +and the set of active interactions changes over time. Hybrid models where bonds are computed using different bond potentials can be setup using the *hybrid* bond style. diff --git a/doc/src/compute.rst b/doc/src/compute.rst index 880f60a8a6..950487cb72 100644 --- a/doc/src/compute.rst +++ b/doc/src/compute.rst @@ -200,6 +200,7 @@ The individual style names on the :doc:`Commands compute ` pag * :doc:`com/chunk ` - center of mass for each chunk * :doc:`contact/atom ` - contact count for each spherical particle * :doc:`coord/atom ` - coordination number for each atom +* :doc:`count/type ` - count of atoms or bonds by type * :doc:`damage/atom ` - Peridynamic damage for each atom * :doc:`dihedral ` - energy of each dihedral sub-style * :doc:`dihedral/local ` - angle of each dihedral diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst new file mode 100644 index 0000000000..17fd9ed784 --- /dev/null +++ b/doc/src/compute_count_type.rst @@ -0,0 +1,89 @@ +.. index:: compute count/type + +compute count/type command +==================== + +Syntax +"""""" + +.. code-block:: LAMMPS + + compute ID group-ID count/type mode + +* ID, group-ID are documented in :doc:`compute ` command +* count/type = style name of this compute command +* mode = {atom} or {bond} + +Examples +"""""""" + +.. code-block:: LAMMPS + + compute 1 all count/type atom + compute 1 flowmols count/type bond + +Description +""""""""""" + +Define a computation that counts the current number of atoms by atom +type or the number of bonds by bond type. The latter can be useful in +reactive simulations where bonds are broken or created. + +Note that for this command, bonds are the topological kind enumerated +in a data file, initially read by the :doc:`read_data ` +command. They do not refer to bonds defined on-the-fly by bond-order +or reactive pair styles. + +These commands can create and break toplogical bonds: + +* :doc:`fix bond/react ` +* :doc:`fix bond/create ` +* :doc:`fix bond/break ` +* :doc:`bond_style quartic ` +* :doc:`BPM package ` bond styles + +If the {mode} setting is {atom} then the count of atoms for each atom +type is tallied. Only atoms in the specified group are counted. + +If the {mode} setting is {bond} then the count of bonds for each bond +type is tallied. Only bonds with both atoms in the specified group +are counted. + +For {mode} = {bond}, broken bonds with a bond type or zero are also +counted. Some commands flag broken bonds by setting their bond type +to zero. See the :doc:`Howto broken bonds ` doc +page for details. Note that the group setting is ignored for broken +bonds; all broken bonds in the system are counted. + +---------- + +Output info +""""""""""" + +This compute calculates a global vector of counts. If the mode is +{atom}, the vector length is the number of atom types. If the mode is +{bond}, the vector length is the number of bond types. + +If the mode is {bond} this compute also calculates a global scalar which +counts the number of broken bonds. + +These values can be used by any command that uses global scalar or +vector values from a compute as input. See the :doc:`Howto output +` page for an overview of LAMMPS output options. + +The scalar and vector values calculated by this compute are "extensive". + +Restrictions +"""""""""""" + +none + +Related commands +"""""""""""""""" + +none + +Default +""""""" + +none diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 707a4bb943..c3014394d8 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -82,6 +82,8 @@ double ComputeCountType::compute_scalar() int nbond; int count = 0; + + // NOTE: respect group setting for (int i = 0; i < nlocal; i++) { nbond = num_bond[i]; @@ -113,6 +115,8 @@ void ComputeCountType::compute_vector() // count atoms by type + // NOTE: respect group setting + if (mode == ATOM) { int *type = atom->type; int nlocal = atom->nlocal; @@ -127,7 +131,9 @@ void ComputeCountType::compute_vector() // count bonds by type // skip type = 0 bonds, they are counted by compute_scalar // bond types can be negative for SHAKE - + + // NOTE: respect group setting + else if (mode == BOND) { int *num_bond = atom->num_bond; int **bond_type = atom->bond_type; From c282d8d5d0eb80c9050f8b141639ef1e31617e06 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 1 May 2023 09:01:03 -0600 Subject: [PATCH 090/448] add group support to new command --- doc/src/compute_count_type.rst | 11 ++++----- src/compute_count_type.cpp | 45 ++++++++++++++++++++++++---------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index 17fd9ed784..ca56648297 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -29,7 +29,7 @@ Define a computation that counts the current number of atoms by atom type or the number of bonds by bond type. The latter can be useful in reactive simulations where bonds are broken or created. -Note that for this command, bonds are the topological kind enumerated +Note that for this command, bonds are the topological ones enumerated in a data file, initially read by the :doc:`read_data ` command. They do not refer to bonds defined on-the-fly by bond-order or reactive pair styles. @@ -49,9 +49,8 @@ If the {mode} setting is {bond} then the count of bonds for each bond type is tallied. Only bonds with both atoms in the specified group are counted. -For {mode} = {bond}, broken bonds with a bond type or zero are also -counted. Some commands flag broken bonds by setting their bond type -to zero. See the :doc:`Howto broken bonds ` doc +For {mode} = {bond}, broken bonds with a bond type of zero are also +counted. See the :doc:`Howto broken bonds ` doc page for details. Note that the group setting is ignored for broken bonds; all broken bonds in the system are counted. @@ -64,8 +63,8 @@ This compute calculates a global vector of counts. If the mode is {atom}, the vector length is the number of atom types. If the mode is {bond}, the vector length is the number of bond types. -If the mode is {bond} this compute also calculates a global scalar which -counts the number of broken bonds. +If the mode is {bond} this compute also calculates a global scalar +which is the number of broken bonds. These values can be used by any command that uses global scalar or vector values from a compute as input. See the :doc:`Howto output diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index c3014394d8..9de5f39cab 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -80,14 +80,16 @@ double ComputeCountType::compute_scalar() int **bond_type = atom->bond_type; int nlocal = atom->nlocal; - int nbond; + int m,nbond; int count = 0; - // NOTE: respect group setting + // count broken bonds with bond_type = 0 + // ignore group setting since 2 atoms in a broken bond + // can be arbitrarily far apart for (int i = 0; i < nlocal; i++) { nbond = num_bond[i]; - for (int m = 0; m < nbond; m++) + for (m = 0; m < nbond; m++) if (bond_type[i][m] == 0) count++; } @@ -114,45 +116,62 @@ void ComputeCountType::compute_vector() int n; // count atoms by type - - // NOTE: respect group setting + // atom must be in group to be counted if (mode == ATOM) { int *type = atom->type; + int *mask = atom->mask; int nlocal = atom->nlocal; int ntypes = atom->ntypes; for (int m = 0; m < ntypes; m++) count[m] = 0; - for (int i = 0; i < nlocal; i++) count[type[i]-1]++; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + count[type[i]-1]++; n = ntypes; } // count bonds by type + // both atoms in bond must be in group to be counted // skip type = 0 bonds, they are counted by compute_scalar // bond types can be negative for SHAKE - // NOTE: respect group setting - else if (mode == BOND) { - int *num_bond = atom->num_bond; + int **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; + int *num_bond = atom->num_bond; + int *mask = atom->mask; int nlocal = atom->nlocal; int nbondtypes = atom->nbondtypes; - int nbond,itype; + int j,m,nbond,itype; + int flag = 0; for (int m = 0; m < nbondtypes; m++) count[m] = 0; for (int i = 0; i < nlocal; i++) { nbond = num_bond[i]; - for (int m = 0; m < nbond; m++) { + for (m = 0; m < nbond; m++) { itype = bond_type[i][m]; if (itype == 0) continue; - if (itype > 0) count[itype-1]++; - else count[-itype-1]++; + + j = atom->map(bond_atom[i][m]); + if (j < 0) { + flag = 1; + continue; + } + + if ((mask[i] & groupbit) && (mask[j] & groupbit)) { + if (itype > 0) count[itype-1]++; + else count[-itype-1]++; + } } } + int flagany; + MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); + if (flagany) error->all(FLERR,"Missing bond atom in compute count/type"); + n = nbondtypes; } From 2fe423cc70a104514b8f2c396e3b732a86c74d0d Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 1 May 2023 09:20:20 -0600 Subject: [PATCH 091/448] bug fix --- src/compute_count_type.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 9de5f39cab..feadcb04ba 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -51,6 +51,8 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute( if (mode == BOND && !atom->avec->bonds_allow) error->all(FLERR,"Cannot use compute count/type bond command with no bonds allowed"); + // output vector + vector = new double[size_vector]; // work vectors @@ -65,6 +67,10 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute( ComputeCountType::~ComputeCountType() { delete[] vector; + + delete[] count; + delete[] bcount_me; + delete[] bcount; } /* ---------------------------------------------------------------------- @@ -103,7 +109,7 @@ double ComputeCountType::compute_scalar() if (bcount > MAXDOUBLEINT) error->all(FLERR,"Compute count/type overflow"); - double scalar = bcount; + scalar = bcount; return scalar; } @@ -113,7 +119,7 @@ void ComputeCountType::compute_vector() { invoked_vector = update->ntimestep; - int n; + int nvec; // count atoms by type // atom must be in group to be counted @@ -129,7 +135,7 @@ void ComputeCountType::compute_vector() if (mask[i] & groupbit) count[type[i]-1]++; - n = ntypes; + nvec = ntypes; } // count bonds by type @@ -172,19 +178,19 @@ void ComputeCountType::compute_vector() MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); if (flagany) error->all(FLERR,"Missing bond atom in compute count/type"); - n = nbondtypes; + nvec = nbondtypes; } // sum across procs as bigint, then convert to double // correct for double counting if newton_bond off - for (int m = 0; m < n; m++) bcount_me[m] = count[m]; - MPI_Allreduce(&bcount_me, &bcount, 1, MPI_LMP_BIGINT, MPI_SUM, world); + for (int m = 0; m < nvec; m++) bcount_me[m] = count[m]; + MPI_Allreduce(bcount_me, bcount, nvec, MPI_LMP_BIGINT, MPI_SUM, world); if (force->newton_bond == 0) - for (int m = 0; m < n; m++) bcount[m] /= 2; + for (int m = 0; m < nvec; m++) bcount[m] /= 2; - for (int m = 0; m < n; m++) + for (int m = 0; m < nvec; m++) if (bcount[m] > MAXDOUBLEINT) error->all(FLERR,"Compute count/type overflow"); - for (int m = 0; m < n; m++) vector[m] *= bcount[m]; + for (int m = 0; m < nvec; m++) vector[m] = bcount[m]; } From 370ec562072ca886df77f8978dea407809d5fa7f Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 1 May 2023 10:20:45 -0600 Subject: [PATCH 092/448] Whitespace --- src/KOKKOS/pair_kokkos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index dd274ca8c2..c244d6a8f9 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -416,7 +416,7 @@ struct PairComputeFunctor { f(i,1) = 0.0; f(i,2) = 0.0; }); - + const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); const int jnum = list.d_numneigh[i]; From 059601734f8fee570af87fff1d961212be1d3299 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 1 May 2023 12:38:16 -0600 Subject: [PATCH 093/448] Fix issues --- src/KOKKOS/fix_nve_kokkos.cpp | 3 ++- src/KOKKOS/verlet_kokkos.cpp | 18 +++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index f812c575bc..c26e26a02c 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -177,7 +177,6 @@ template void FixNVEKokkos::fused_integrate() { atomKK->sync(execution_space,datamask_read); - atomKK->modified(execution_space,datamask_modify); x = atomKK->k_x.view(); v = atomKK->k_v.view(); @@ -196,6 +195,8 @@ void FixNVEKokkos::fused_integrate() FixNVEKokkosFusedIntegrateFunctor functor(this); Kokkos::parallel_for(nlocal,functor); } + + atomKK->modified(execution_space,datamask_modify); } namespace LAMMPS_NS { diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index 4e564a6ef2..bd15859644 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -296,7 +296,6 @@ void VerletKokkos::run(int n) // initial time integration timer->stamp(); - fuse_check(i,n); if (!fuse_integrate) modify->initial_integrate(vflag); if (n_post_integrate) modify->post_integrate(); @@ -364,6 +363,7 @@ void VerletKokkos::run(int n) // since some bonded potentials tally pairwise energy/virial // and Pair:ev_tally() needs to be called before any tallying + fuse_check(i,n); if (!fuse_force_clear) force_clear(); @@ -611,7 +611,7 @@ void VerletKokkos::force_clear() check if can fuse initial_integrate() with final_integrate() Requirements: - no end_of_step fixes - - not on first, last, or output step + - not on last or output step - no timers to break out of loop - integrate fix style must support fusing ------------------------------------------------------------------------- */ @@ -620,14 +620,14 @@ void VerletKokkos::fuse_check(int i, int n) { fuse_force_clear = 1; if (modify->n_pre_force) fuse_force_clear = 0; - if (torqueflag || extraflag || neighbor->includegroup) fuse_force_clear = 0; - if (!pair_compute_flag) fuse_force_clear = 0; - if (!force->pair->fuse_force_clear_flag) fuse_force_clear = 0; + else if (torqueflag || extraflag || neighbor->includegroup) fuse_force_clear = 0; + else if (!force->pair || !pair_compute_flag) fuse_force_clear = 0; + else if (!force->pair->fuse_force_clear_flag) fuse_force_clear = 0; fuse_integrate = 1; if (modify->n_end_of_step) fuse_integrate = 0; - if (i == 0 || i == n-1) fuse_integrate = 0; - if (update->ntimestep == output->next) fuse_integrate = 0; - if (timer->has_timeout()) fuse_integrate = 0; - if (!((ModifyKokkos*)modify)->check_fuse_integrate()) fuse_integrate = 0; + else if (i == n-1) fuse_integrate = 0; + else if (update->ntimestep == output->next) fuse_integrate = 0; + else if (timer->has_timeout()) fuse_integrate = 0; + else if (!((ModifyKokkos*)modify)->check_fuse_integrate()) fuse_integrate = 0; } From fd65000afc950d7cee2a4a190d415a3664d893ad Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 1 May 2023 13:08:01 -0600 Subject: [PATCH 094/448] Small refactor --- src/KOKKOS/fix_langevin_kokkos.cpp | 9 ++++++ src/KOKKOS/fix_langevin_kokkos.h | 1 + src/KOKKOS/fix_nve_kokkos.cpp | 52 ++++++++++++++++++++++++------ src/KOKKOS/fix_nve_kokkos.h | 17 +++++----- src/KOKKOS/modify_kokkos.cpp | 4 +-- src/KOKKOS/modify_kokkos.h | 2 +- src/KOKKOS/verlet_kokkos.cpp | 2 +- src/fix.h | 2 +- src/modify.h | 2 +- 9 files changed, 67 insertions(+), 24 deletions(-) diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index b7305644c9..14eb0f1ab7 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -44,6 +44,7 @@ FixLangevinKokkos::FixLangevinKokkos(LAMMPS *lmp, int narg, char **a FixLangevin(lmp, narg, arg),rand_pool(seed + comm->me) { kokkosable = 1; + fuse_integrate_flag = 1; atomKK = (AtomKokkos *) atom; int ntypes = atomKK->ntypes; @@ -169,6 +170,14 @@ void FixLangevinKokkos::initial_integrate_item(int i) const /* ---------------------------------------------------------------------- */ +template +void FixLangevinKokkos::fused_integrate(int vflag) +{ + initial_integrate(vflag); +} + +/* ---------------------------------------------------------------------- */ + template void FixLangevinKokkos::post_force(int /*vflag*/) { diff --git a/src/KOKKOS/fix_langevin_kokkos.h b/src/KOKKOS/fix_langevin_kokkos.h index f7142e6286..0bd628270e 100644 --- a/src/KOKKOS/fix_langevin_kokkos.h +++ b/src/KOKKOS/fix_langevin_kokkos.h @@ -69,6 +69,7 @@ namespace LAMMPS_NS { void cleanup_copy(); void init() override; void initial_integrate(int) override; + void fused_integrate(int) override; void post_force(int) override; void reset_dt() override; void grow_arrays(int) override; diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index c26e26a02c..b8236c2657 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -160,21 +160,12 @@ void FixNVEKokkos::final_integrate_rmass_item(int i) const } } -/* ---------------------------------------------------------------------- */ - -template -void FixNVEKokkos::cleanup_copy() -{ - id = style = nullptr; - vatom = nullptr; -} - /* ---------------------------------------------------------------------- allow for both per-type and per-atom mass ------------------------------------------------------------------------- */ template -void FixNVEKokkos::fused_integrate() +void FixNVEKokkos::fused_integrate(int /*vflag*/) { atomKK->sync(execution_space,datamask_read); @@ -199,6 +190,47 @@ void FixNVEKokkos::fused_integrate() atomKK->modified(execution_space,datamask_modify); } +template +KOKKOS_INLINE_FUNCTION +void FixNVEKokkos::fused_integrate_item(int i) const +{ + if (mask[i] & groupbit) { + const double dtfm = 2.0 * dtf / mass[type[i]]; + v(i,0) += dtfm * f(i,0); + v(i,1) += dtfm * f(i,1); + v(i,2) += dtfm * f(i,2); + x(i,0) += dtv * v(i,0); + x(i,1) += dtv * v(i,1); + x(i,2) += dtv * v(i,2); + } +} + +template +KOKKOS_INLINE_FUNCTION +void FixNVEKokkos::fused_integrate_rmass_item(int i) const +{ + if (mask[i] & groupbit) { + const double dtfm = 2.0 * dtf / rmass[i]; + v(i,0) += dtfm * f(i,0); + v(i,1) += dtfm * f(i,1); + v(i,2) += dtfm * f(i,2); + x(i,0) += dtv * v(i,0); + x(i,1) += dtv * v(i,1); + x(i,2) += dtv * v(i,2); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void FixNVEKokkos::cleanup_copy() +{ + id = style = nullptr; + vatom = nullptr; +} + +/* ---------------------------------------------------------------------- */ + namespace LAMMPS_NS { template class FixNVEKokkos; #ifdef LMP_KOKKOS_GPU diff --git a/src/KOKKOS/fix_nve_kokkos.h b/src/KOKKOS/fix_nve_kokkos.h index a10f846cba..a1e8e1398c 100644 --- a/src/KOKKOS/fix_nve_kokkos.h +++ b/src/KOKKOS/fix_nve_kokkos.h @@ -46,7 +46,7 @@ class FixNVEKokkos : public FixNVE { void init() override; void initial_integrate(int) override; void final_integrate() override; - void fused_integrate() override; + void fused_integrate(int) override; KOKKOS_INLINE_FUNCTION void initial_integrate_item(int) const; @@ -56,6 +56,10 @@ class FixNVEKokkos : public FixNVE { void final_integrate_item(int) const; KOKKOS_INLINE_FUNCTION void final_integrate_rmass_item(int) const; + KOKKOS_INLINE_FUNCTION + void fused_integrate_item(int) const; + KOKKOS_INLINE_FUNCTION + void fused_integrate_rmass_item(int) const; private: @@ -106,13 +110,10 @@ struct FixNVEKokkosFusedIntegrateFunctor { c(*c_ptr) {c.cleanup_copy();}; KOKKOS_INLINE_FUNCTION void operator()(const int i) const { - if (RMass) { - c.final_integrate_rmass_item(i); - c.initial_integrate_rmass_item(i); - } else { - c.final_integrate_item(i); - c.initial_integrate_item(i); - } + if (RMass) + c.fused_integrate_rmass_item(i); + else + c.fused_integrate_item(i); } }; diff --git a/src/KOKKOS/modify_kokkos.cpp b/src/KOKKOS/modify_kokkos.cpp index 44fcb48727..0b81a1cabb 100644 --- a/src/KOKKOS/modify_kokkos.cpp +++ b/src/KOKKOS/modify_kokkos.cpp @@ -396,14 +396,14 @@ void ModifyKokkos::final_integrate() fused initial and final integrate call, only for relevant fixes ------------------------------------------------------------------------- */ -void ModifyKokkos::fused_integrate() +void ModifyKokkos::fused_integrate(int vflag) { for (int i = 0; i < n_final_integrate; i++) { atomKK->sync(fix[list_final_integrate[i]]->execution_space, fix[list_final_integrate[i]]->datamask_read); int prev_auto_sync = lmp->kokkos->auto_sync; if (!fix[list_final_integrate[i]]->kokkosable) lmp->kokkos->auto_sync = 1; - fix[list_final_integrate[i]]->fused_integrate(); + fix[list_final_integrate[i]]->fused_integrate(vflag); lmp->kokkos->auto_sync = prev_auto_sync; atomKK->modified(fix[list_final_integrate[i]]->execution_space, fix[list_final_integrate[i]]->datamask_modify); diff --git a/src/KOKKOS/modify_kokkos.h b/src/KOKKOS/modify_kokkos.h index 8dd9e6d9df..527518219c 100644 --- a/src/KOKKOS/modify_kokkos.h +++ b/src/KOKKOS/modify_kokkos.h @@ -39,7 +39,7 @@ class ModifyKokkos : public Modify { void pre_reverse(int,int) override; void post_force(int) override; void final_integrate() override; - void fused_integrate() override; + void fused_integrate(int) override; void end_of_step() override; double energy_couple() override; double energy_global() override; diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index bd15859644..3b88b34b38 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -498,7 +498,7 @@ void VerletKokkos::run(int n) if (n_post_force) modify->post_force(vflag); - if (fuse_integrate) modify->fused_integrate(); + if (fuse_integrate) modify->fused_integrate(vflag); else modify->final_integrate(); if (n_end_of_step) modify->end_of_step(); diff --git a/src/fix.h b/src/fix.h index 23b120d989..9676651afb 100644 --- a/src/fix.h +++ b/src/fix.h @@ -153,7 +153,6 @@ class Fix : protected Pointers { virtual void setup_pre_reverse(int, int) {} virtual void min_setup(int) {} virtual void initial_integrate(int) {} - virtual void fused_integrate() {} virtual void post_integrate() {} virtual void pre_exchange() {} virtual void pre_neighbor() {} @@ -162,6 +161,7 @@ class Fix : protected Pointers { virtual void pre_reverse(int, int) {} virtual void post_force(int) {} virtual void final_integrate() {} + virtual void fused_integrate(int) {} virtual void end_of_step() {} virtual void post_run() {} virtual void write_restart(FILE *) {} diff --git a/src/modify.h b/src/modify.h index 9686a9a7ec..6ca4b4ad26 100644 --- a/src/modify.h +++ b/src/modify.h @@ -61,7 +61,6 @@ class Modify : protected Pointers { virtual void setup_pre_force(int); virtual void setup_pre_reverse(int, int); virtual void initial_integrate(int); - virtual void fused_integrate() {} virtual void post_integrate(); virtual void pre_exchange(); virtual void pre_neighbor(); @@ -70,6 +69,7 @@ class Modify : protected Pointers { virtual void pre_reverse(int, int); virtual void post_force(int); virtual void final_integrate(); + virtual void fused_integrate(int) {} virtual void end_of_step(); virtual double energy_couple(); virtual double energy_global(); From 757130f9d049561b0a756c0b0b41216afbfbb572 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 1 May 2023 13:09:46 -0600 Subject: [PATCH 095/448] whitespace --- src/KOKKOS/fix_nve_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index b8236c2657..fba8911f31 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -224,7 +224,7 @@ void FixNVEKokkos::fused_integrate_rmass_item(int i) const template void FixNVEKokkos::cleanup_copy() -{ +{ id = style = nullptr; vatom = nullptr; } From cd972884ff979e83daf1a8af494070db99246ced Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 1 May 2023 13:13:23 -0600 Subject: [PATCH 096/448] Clarify with comment --- src/KOKKOS/verlet_kokkos.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index 3b88b34b38..becdf67c9c 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -358,12 +358,15 @@ void VerletKokkos::run(int n) } } + // check if kernels can be fused, must come after initial_integrate + + fuse_check(i,n); + // force computations // important for pair to come before bonded contributions // since some bonded potentials tally pairwise energy/virial // and Pair:ev_tally() needs to be called before any tallying - fuse_check(i,n); if (!fuse_force_clear) force_clear(); From 76f9336de41939f459e5a597fdf9756a9574c0e9 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 1 May 2023 13:16:16 -0600 Subject: [PATCH 097/448] whitespace --- src/KOKKOS/fix_nve_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/fix_nve_kokkos.cpp b/src/KOKKOS/fix_nve_kokkos.cpp index fba8911f31..59cc90c088 100644 --- a/src/KOKKOS/fix_nve_kokkos.cpp +++ b/src/KOKKOS/fix_nve_kokkos.cpp @@ -193,8 +193,8 @@ void FixNVEKokkos::fused_integrate(int /*vflag*/) template KOKKOS_INLINE_FUNCTION void FixNVEKokkos::fused_integrate_item(int i) const -{ - if (mask[i] & groupbit) { +{ + if (mask[i] & groupbit) { const double dtfm = 2.0 * dtf / mass[type[i]]; v(i,0) += dtfm * f(i,0); v(i,1) += dtfm * f(i,1); From f1b29941fdf1aa7a6da41c4899d07e933640e60d Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 1 May 2023 13:34:58 -0600 Subject: [PATCH 098/448] Port changes to nve/sphere --- src/KOKKOS/fix_nve_sphere_kokkos.cpp | 67 ++++++++++++++++++++++++++++ src/KOKKOS/fix_nve_sphere_kokkos.h | 14 ++++++ 2 files changed, 81 insertions(+) diff --git a/src/KOKKOS/fix_nve_sphere_kokkos.cpp b/src/KOKKOS/fix_nve_sphere_kokkos.cpp index 51e57b839e..ecea4f31d1 100644 --- a/src/KOKKOS/fix_nve_sphere_kokkos.cpp +++ b/src/KOKKOS/fix_nve_sphere_kokkos.cpp @@ -28,6 +28,7 @@ FixNVESphereKokkos::FixNVESphereKokkos(LAMMPS *lmp, int narg, char * FixNVESphere(lmp, narg, arg) { kokkosable = 1; + fuse_integrate_flag = 1; atomKK = (AtomKokkos *)atom; execution_space = ExecutionSpaceFromDevice::space; @@ -164,6 +165,72 @@ void FixNVESphereKokkos::final_integrate_item(const int i) const } } +/* ---------------------------------------------------------------------- */ + +template +void FixNVESphereKokkos::fused_integrate(int /*vflag*/) +{ + if (extra == DIPOLE) + atomKK->sync(execution_space, X_MASK | V_MASK | OMEGA_MASK| F_MASK | TORQUE_MASK | RMASS_MASK | RADIUS_MASK | MASK_MASK | MU_MASK); + else + atomKK->sync(execution_space, X_MASK | V_MASK | OMEGA_MASK| F_MASK | TORQUE_MASK | RMASS_MASK | RADIUS_MASK | MASK_MASK); + + v = atomKK->k_v.view(); + omega = atomKK->k_omega.view(); + f = atomKK->k_f.view(); + torque = atomKK->k_torque.view(); + mask = atomKK->k_mask.view(); + rmass = atomKK->k_rmass.view(); + radius = atomKK->k_radius.view(); + mu = atomKK->k_mu.view(); + + int nlocal = atom->nlocal; + if (igroup == atom->firstgroup) nlocal = atom->nfirst; + + FixNVESphereKokkosFusedIntegrateFunctor f(this); + Kokkos::parallel_for(nlocal,f); + + if (extra == DIPOLE) + atomKK->modified(execution_space, X_MASK | V_MASK | OMEGA_MASK | MU_MASK); + else + atomKK->modified(execution_space, X_MASK | V_MASK | OMEGA_MASK); +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void FixNVESphereKokkos::fused_integrate_item(const int i) const +{ + const double dtfrotate = dtf / inertia; + + if (mask(i) & groupbit) { + const double dtfm = 2.0 * dtf / rmass(i); + v(i,0) += dtfm * f(i,0); + v(i,1) += dtfm * f(i,1); + v(i,2) += dtfm * f(i,2); + x(i,0) += dtv * v(i,0); + x(i,1) += dtv * v(i,1); + x(i,2) += dtv * v(i,2); + + const double dtirotate = 2.0 * dtfrotate / (radius(i)*radius(i)*rmass(i)); + omega(i,0) += dtirotate * torque(i,0); + omega(i,1) += dtirotate * torque(i,1); + omega(i,2) += dtirotate * torque(i,2); + + if (extra == DIPOLE) { + const double g0 = mu(i,0) + dtv * (omega(i,1) * mu(i,2) - omega(i,2) * mu(i,1)); + const double g1 = mu(i,1) + dtv * (omega(i,2) * mu(i,0) - omega(i,0) * mu(i,2)); + const double g2 = mu(i,2) + dtv * (omega(i,0) * mu(i,1) - omega(i,1) * mu(i,0)); + const double msq = g0*g0 + g1*g1 + g2*g2; + const double scale = mu(i,3)/sqrt(msq); + mu(i,0) = g0*scale; + mu(i,1) = g1*scale; + mu(i,2) = g2*scale; + } + } +} + namespace LAMMPS_NS { template class FixNVESphereKokkos; #ifdef LMP_KOKKOS_GPU diff --git a/src/KOKKOS/fix_nve_sphere_kokkos.h b/src/KOKKOS/fix_nve_sphere_kokkos.h index 268b4ea9ce..02acb466f2 100644 --- a/src/KOKKOS/fix_nve_sphere_kokkos.h +++ b/src/KOKKOS/fix_nve_sphere_kokkos.h @@ -37,11 +37,14 @@ class FixNVESphereKokkos : public FixNVESphere { void init() override; void initial_integrate(int) override; void final_integrate() override; + void fused_integrate(int) override; KOKKOS_INLINE_FUNCTION void initial_integrate_item(const int i) const; KOKKOS_INLINE_FUNCTION void final_integrate_item(const int i) const; + KOKKOS_INLINE_FUNCTION + void fused_integrate_item(int) const; private: typename ArrayTypes::t_x_array x; @@ -77,6 +80,17 @@ struct FixNVESphereKokkosFinalIntegrateFunctor { } }; +template +struct FixNVESphereKokkosFusedIntegrateFunctor { + typedef DeviceType device_type; + FixNVESphereKokkos c; + FixNVESphereKokkosFusedIntegrateFunctor(FixNVESphereKokkos *c_ptr): c(*c_ptr) { c.cleanup_copy(); } + KOKKOS_INLINE_FUNCTION + void operator()(const int i) const { + c.fused_integrate_item(i); + } +}; + } // namespace LAMMPS_NS #endif // LMP_FIX_NVE_SPHERE_KOKKOS_H From ef9ce62aa8f89b9ce067cda9a1b8fc6f6bb78cd4 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 1 May 2023 15:17:19 -0600 Subject: [PATCH 099/448] update broken bond doc page --- doc/src/Howto_broken_bonds.rst | 75 ++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 35 deletions(-) diff --git a/doc/src/Howto_broken_bonds.rst b/doc/src/Howto_broken_bonds.rst index 88c8acb87f..4fd0bcc30f 100644 --- a/doc/src/Howto_broken_bonds.rst +++ b/doc/src/Howto_broken_bonds.rst @@ -1,48 +1,53 @@ Broken Bonds ============ -Typically, bond interactions persist for the duration of a simulation in -LAMMPS. However, there are some exceptions that allow for bonds to -break, including the :doc:`quartic bond style ` and the -bond styles in the :doc:`BPM package ` which contains the -:doc:`bpm/spring ` and :doc:`bpm/rotational -` bond styles. In these cases, a bond can be broken -if it is stretched beyond a user-defined threshold. LAMMPS accomplishes -this by setting the bond type to 0, such that the bond force is no -longer computed. +Typically, bond interactions persist for the duration of a simulation +in LAMMPS. However, some commands allow bonds to break, including the +following: -Users are normally able to weight the contribution of pair forces to atoms -that are bonded using the :doc:`special_bonds command `. -When bonds break, this is not always the case. For the quartic bond style, -pair forces are always turned off between bonded particles. LAMMPS does -this via a computational sleight-of-hand. It subtracts the pairwise -interaction as part of the bond computation. When the bond breaks, the -subtraction stops. For this to work, the pairwise interaction must always -be computed by the :doc:`pair_style ` command, whether the bond -is broken or not. This means that :doc:`special_bonds ` must -be set to 1,1,1. After the bond breaks, the pairwise interaction between the -two atoms is turned on, since they are no longer bonded. +* :doc:`bond_style quartic ` +* :doc:`fix bond/break ` +* :doc:`fix bond/react ` +* :doc:`BPM package ` bond styles -In the BPM package, one can either turn off all pair interactions between -bonded particles or leave them on, overlaying pair forces on top of bond -forces. To remove pair forces, the special bond list is dynamically -updated. More details can be found on the :doc:`Howto BPM ` -page. +A bond can break if it is stretched beyond a user-defined threshold or +more generally if other criteria are met. -Bonds can also be broken by fixes which change bond topology, including -:doc:`fix bond/break ` and -:doc:`fix bond/react `. These fixes will automatically -trigger a rebuild of the neighbor list and update special bond data structures -when bonds are broken. +For the quartic bond style, when a bond is broken its bond type is set +to 0 and pairwise forces between the two atoms in the broken bond are +"turned on". Angles, dihedrals, etc cannot be defined for the system +when :doc:`bond_style quartic ` is used. -Note that when bonds are dumped to a file via the :doc:`dump local ` command, bonds with type 0 are not included. The -:doc:`delete_bonds ` command can also be used to query the -status of broken bonds or permanently delete them, e.g.: +The :doc:`fix bond/break ` and :doc:`fix bond/react +` commands allow breaking of bonds within a molecular +topology with also defines angles, dihedrals, etc. These fixes will +update internal topology data structures when bonds are broken, so +that the appropriate angle, dihederal, etc interactions are also +turned off. They will also trigger a rebuild of the neighbor list +when this occurs, to turn on the appropriate pairwise forces. + +In the BPM package, one can either turn off all pair interactions +between bonded particles or leave them on, overlaying pair forces on +top of bond forces. To remove pair forces, the special bond list is +dynamically updated. More details can be found on the :doc:`Howto BPM +` page. + +Note that when bonds are dumped to a file via the :doc:`dump local +` command, bonds with type 0 are not included. + +The :doc:`delete_bonds ` command can also be used to +query the status of broken bonds (type = 0) or permanently delete +them, e.g.: .. code-block:: LAMMPS delete_bonds all stats delete_bonds all bond 0 remove -The compute :doc:`nbond/atom ` can also be used -to tally the current number of bonds per atom, excluding broken bonds. +The compute :doc:`count/type bond ` command +tallies the current number of bonds for each bond type. It also +tallies broken bonds with type = 0. + +The compute :doc:`nbond/atom ` command tallies the +current number of bonds each atom is part of, excluding broken bonds +with type = 0. From fae0ef6cdea8a531bb9a5c77bb8e32c8ab8284da Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 1 May 2023 15:21:56 -0600 Subject: [PATCH 100/448] update count/type doc page --- doc/src/compute_count_type.rst | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index ca56648297..9ab0b1009f 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -25,16 +25,22 @@ Examples Description """"""""""" -Define a computation that counts the current number of atoms by atom -type or the number of bonds by bond type. The latter can be useful in -reactive simulations where bonds are broken or created. +Define a computation that counts the current number of atoms for each +atom type or the number of bonds for each bond type. The former can +be useful if atoms are added to or deleted from the system in random +ways, e.g. via the :doc:`fix deposit `, :doc:`fix pour +`, or :doc:`fix evaporate ` commands. The +latter can be useful in reactive simulations where molecular bonds are +broken or created. -Note that for this command, bonds are the topological ones enumerated -in a data file, initially read by the :doc:`read_data ` -command. They do not refer to bonds defined on-the-fly by bond-order -or reactive pair styles. +Note that for this command, bonds are defined as the topological kind +enumerated in a data file, initially read by the :doc:`read_data +` command or defined by the :doc:`molecule ` +command. They do not refer to implicit bonds defined on-the-fly by +bond-order or reactive pair styles based on the current conformation +of small clusters of atoms. -These commands can create and break toplogical bonds: +These commands can create and/or break topological bonds: * :doc:`fix bond/react ` * :doc:`fix bond/create ` @@ -50,9 +56,11 @@ type is tallied. Only bonds with both atoms in the specified group are counted. For {mode} = {bond}, broken bonds with a bond type of zero are also -counted. See the :doc:`Howto broken bonds ` doc -page for details. Note that the group setting is ignored for broken -bonds; all broken bonds in the system are counted. +counted. Some of the commands listed above which break bonds, do this +by setting their types to zero. See the :doc:`Howto broken bonds +` doc page for details. Note that the group +setting is ignored for broken bonds; all broken bonds in the system +are counted. ---------- From f8058f039fe77e30974d2fb172cebed33e68f38b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 1 May 2023 15:26:07 -0600 Subject: [PATCH 101/448] Fix bug --- src/KOKKOS/fix_nve_sphere_kokkos.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KOKKOS/fix_nve_sphere_kokkos.cpp b/src/KOKKOS/fix_nve_sphere_kokkos.cpp index ecea4f31d1..38f6a40792 100644 --- a/src/KOKKOS/fix_nve_sphere_kokkos.cpp +++ b/src/KOKKOS/fix_nve_sphere_kokkos.cpp @@ -175,6 +175,7 @@ void FixNVESphereKokkos::fused_integrate(int /*vflag*/) else atomKK->sync(execution_space, X_MASK | V_MASK | OMEGA_MASK| F_MASK | TORQUE_MASK | RMASS_MASK | RADIUS_MASK | MASK_MASK); + x = atomKK->k_x.view(); v = atomKK->k_v.view(); omega = atomKK->k_omega.view(); f = atomKK->k_f.view(); From dbcc19aef4ab0386f6e1ba7e011926ca2e190cc7 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 1 May 2023 15:42:17 -0600 Subject: [PATCH 102/448] Fix uninitialized variables --- src/KOKKOS/verlet_kokkos.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/KOKKOS/verlet_kokkos.cpp b/src/KOKKOS/verlet_kokkos.cpp index becdf67c9c..7570f1d8fa 100644 --- a/src/KOKKOS/verlet_kokkos.cpp +++ b/src/KOKKOS/verlet_kokkos.cpp @@ -276,6 +276,9 @@ void VerletKokkos::run(int n) lmp->kokkos->auto_sync = 0; + fuse_integrate = 0; + fuse_force_clear = 0; + if (atomKK->sortfreq > 0) sortflag = 1; else sortflag = 0; From 53848be081c2fa9319a378e50a963c18ee3ea986 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 28 Apr 2023 11:49:11 -0400 Subject: [PATCH 103/448] improve error messages --- src/fix.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/fix.cpp b/src/fix.cpp index f0cc8a20ea..78fdf1ce65 100644 --- a/src/fix.cpp +++ b/src/fix.cpp @@ -145,13 +145,13 @@ void Fix::modify_params(int narg, char **arg) if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); thermo_energy = utils::logical(FLERR,arg[iarg+1],false,lmp); if (thermo_energy && !energy_global_flag && !energy_peratom_flag) - error->all(FLERR,"Illegal fix_modify command"); + error->all(FLERR,"Fix {} {} does not support fix_modify energy command", id, style); iarg += 2; } else if (strcmp(arg[iarg],"virial") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); thermo_virial = utils::logical(FLERR,arg[iarg+1],false,lmp); if (thermo_virial && !virial_global_flag && !virial_peratom_flag) - error->all(FLERR,"Illegal fix_modify command"); + error->all(FLERR,"Fix {} {} does not support fix_modify virial command", id, style); iarg += 2; } else if (strcmp(arg[iarg],"respa") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix_modify command"); From d1f64c02d8e18a4d0426289a64210502840ca580 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 20:13:37 -0400 Subject: [PATCH 104/448] show/explain alternate LJ potential using the minimum energy distance --- doc/src/pair_lj.rst | 21 ++++++++++++++++----- doc/utils/requirements.txt | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/doc/src/pair_lj.rst b/doc/src/pair_lj.rst index 62cdd98cef..1a099e009b 100644 --- a/doc/src/pair_lj.rst +++ b/doc/src/pair_lj.rst @@ -43,8 +43,7 @@ given by .. math:: E = 4 \epsilon \left[ \left(\frac{\sigma}{r}\right)^{12} - - \left(\frac{\sigma}{r}\right)^6 \right] - \qquad r < r_c + \left(\frac{\sigma}{r}\right)^6 \right] \qquad r < r_c :math:`r_c` is the cutoff. @@ -64,12 +63,24 @@ file or restart files read by the :doc:`read_data ` or * :math:`\sigma` (distance units) * LJ cutoff (distance units) -Note that :math:`\sigma` is defined in the LJ formula as the zero-crossing -distance for the potential, not as the energy minimum at :math:`2^{\frac{1}{6}} \sigma`. - The last coefficient is optional. If not specified, the global LJ cutoff specified in the pair_style command is used. +Note that :math:`\sigma` is defined in the LJ formula as the +zero-crossing distance for the potential, *not* as the energy minimum at +:math:`r_0 = 2^{\frac{1}{6}} \sigma`. The _same_ potential function becomes: + +.. math:: + + E = \epsilon \left[ \left(\frac{r_0}{r}\right)^{12} - + 2 \left(\frac{r_0}{r}\right)^6 \right] \qquad r < r_c + +When using the minimum as reference width. In the literature both +formulations are used, but the describe the same potential, only the +:math:`\sigma` value must be computed by :math:`\sigma = r_0 / +2^{\frac{1}{6}}` for use with LAMMPS, if this latter formulation is +used. + ---------- A version of these styles with a soft core, *lj/cut/soft*, suitable diff --git a/doc/utils/requirements.txt b/doc/utils/requirements.txt index ac4e010147..aa71e9c5f9 100644 --- a/doc/utils/requirements.txt +++ b/doc/utils/requirements.txt @@ -1,4 +1,4 @@ -Sphinx >= 5.0.0, <7.0.0 +Sphinx >= 5.3.0, <7.1.0 sphinxcontrib-spelling sphinxcontrib-jquery git+https://github.com/akohlmey/sphinx-fortran@parallel-read From 478058119b051ea256a519f843abecc8c9a7bb43 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 29 Apr 2023 02:59:04 -0400 Subject: [PATCH 105/448] integrate CMake build procedure for tools/phonon --- cmake/CMakeLists.txt | 2 +- cmake/Modules/Tools.cmake | 2 + tools/phonon/CMakeLists.spglib | 54 +++++ tools/phonon/CMakeLists.txt | 99 ++++++++ tools/phonon/Makefile | 67 ------ tools/phonon/README | 56 +++-- tools/phonon/disp.cpp | 43 ++-- tools/phonon/dynmat.cpp | 72 ++++-- tools/phonon/dynmat.h | 20 +- tools/phonon/global.h | 2 +- tools/phonon/green.cpp | 13 +- tools/phonon/green.h | 5 +- tools/phonon/input.cpp | 35 +++ tools/phonon/input.h | 17 ++ tools/phonon/interpolate.cpp | 21 +- tools/phonon/interpolate.h | 15 +- tools/phonon/kpath.cpp | 39 ++- tools/phonon/kpath.h | 17 +- tools/phonon/main.cpp | 4 - tools/phonon/memory.cpp | 6 +- tools/phonon/memory.h | 308 +++++------------------- tools/phonon/phonon.cpp | 176 +++++++++----- tools/phonon/phonon.h | 16 +- tools/phonon/phonopy.cpp | 141 ++++++----- tools/phonon/phonopy.h | 16 +- tools/phonon/timer.cpp | 3 + tools/phonon/timer.h | 4 +- tools/phonon/tricubic/CMakeLists.txt | 18 ++ tools/phonon/tricubic/LICENSE | 340 +++++++++++++++++++++++++++ tools/phonon/tricubic/README.md | 28 +++ tools/phonon/tricubic/tricubic.cpp | 185 +++++++++++++++ tools/phonon/tricubic/tricubic.h | 10 + tools/phonon/version.h | 1 - tools/phonon/zheevd.h | 16 ++ 34 files changed, 1260 insertions(+), 591 deletions(-) create mode 100644 tools/phonon/CMakeLists.spglib create mode 100644 tools/phonon/CMakeLists.txt delete mode 100644 tools/phonon/Makefile create mode 100644 tools/phonon/input.cpp create mode 100644 tools/phonon/input.h create mode 100644 tools/phonon/tricubic/CMakeLists.txt create mode 100644 tools/phonon/tricubic/LICENSE create mode 100644 tools/phonon/tricubic/README.md create mode 100644 tools/phonon/tricubic/tricubic.cpp create mode 100644 tools/phonon/tricubic/tricubic.h delete mode 100644 tools/phonon/version.h create mode 100644 tools/phonon/zheevd.h diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index a71347c2c4..88b7ec422e 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -440,7 +440,7 @@ if(BUILD_OMP) target_link_libraries(lmp PRIVATE OpenMP::OpenMP_CXX) endif() -if(PKG_MSCG OR PKG_ATC OR PKG_AWPMD OR PKG_ML-QUIP OR PKG_ML-POD OR PKG_ELECTRODE) +if(PKG_MSCG OR PKG_ATC OR PKG_AWPMD OR PKG_ML-QUIP OR PKG_ML-POD OR PKG_ELECTRODE OR BUILD_TOOLS) enable_language(C) if (NOT USE_INTERNAL_LINALG) find_package(LAPACK) diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index c4c33cc40c..ba91a557bc 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -63,6 +63,8 @@ if(BUILD_LAMMPS_SHELL) install(TARGETS lammps-shell EXPORT LAMMPS_Targets DESTINATION ${CMAKE_INSTALL_BINDIR}) install(DIRECTORY ${LAMMPS_TOOLS_DIR}/lammps-shell/icons DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/) install(FILES ${LAMMPS_TOOLS_DIR}/lammps-shell/lammps-shell.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/) + + add_subdirectory(${LAMMPS_TOOLS_DIR}/phonon ${CMAKE_BINARY_DIR}/phana_build) endif() diff --git a/tools/phonon/CMakeLists.spglib b/tools/phonon/CMakeLists.spglib new file mode 100644 index 0000000000..9e22445b80 --- /dev/null +++ b/tools/phonon/CMakeLists.spglib @@ -0,0 +1,54 @@ +cmake_minimum_required(VERSION 3.10) +project(spglib C) +set(CMAKE_MACOSX_RPATH 1) +set(CMAKE_C_FLAGS_RELEASE "-Wall -O2") +set(CMAKE_C_FLAGS_DEBUG "-g -DSPGDEBUG -DSPGWARNING") +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif(NOT CMAKE_BUILD_TYPE) +message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") + +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + + +# Version numbers +file(READ ${PROJECT_SOURCE_DIR}/src/version.h version_file) +string(REGEX MATCH "SPGLIB_MAJOR_VERSION ([0-9]+)" spglib_major_version ${version_file}) +set(spglib_major_version ${CMAKE_MATCH_1}) +string(REGEX MATCH "SPGLIB_MINOR_VERSION ([0-9]+)" spglib_minor_version ${version_file}) +set(spglib_minor_version ${CMAKE_MATCH_1}) +string(REGEX MATCH "SPGLIB_MICRO_VERSION ([0-9]+)" spglib_micro_version ${version_file}) +set(spglib_micro_version ${CMAKE_MATCH_1}) +set(serial "${spglib_major_version}.${spglib_minor_version}.${spglib_micro_version}") +set(soserial "1") + +# Source code +include_directories("${PROJECT_SOURCE_DIR}/src") +set(SOURCES ${PROJECT_SOURCE_DIR}/src/arithmetic.c + ${PROJECT_SOURCE_DIR}/src/cell.c + ${PROJECT_SOURCE_DIR}/src/debug.c + ${PROJECT_SOURCE_DIR}/src/delaunay.c + ${PROJECT_SOURCE_DIR}/src/determination.c + ${PROJECT_SOURCE_DIR}/src/hall_symbol.c + ${PROJECT_SOURCE_DIR}/src/kgrid.c + ${PROJECT_SOURCE_DIR}/src/kpoint.c + ${PROJECT_SOURCE_DIR}/src/mathfunc.c + ${PROJECT_SOURCE_DIR}/src/niggli.c + ${PROJECT_SOURCE_DIR}/src/overlap.c + ${PROJECT_SOURCE_DIR}/src/pointgroup.c + ${PROJECT_SOURCE_DIR}/src/primitive.c + ${PROJECT_SOURCE_DIR}/src/refinement.c + ${PROJECT_SOURCE_DIR}/src/site_symmetry.c + ${PROJECT_SOURCE_DIR}/src/sitesym_database.c + ${PROJECT_SOURCE_DIR}/src/spacegroup.c + ${PROJECT_SOURCE_DIR}/src/spg_database.c + ${PROJECT_SOURCE_DIR}/src/spglib.c + ${PROJECT_SOURCE_DIR}/src/spin.c + ${PROJECT_SOURCE_DIR}/src/symmetry.c) + +add_library(symspg STATIC ${SOURCES}) +install(TARGETS symspg LIBRARY) + +# Header file +install(FILES ${PROJECT_SOURCE_DIR}/src/spglib.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) + diff --git a/tools/phonon/CMakeLists.txt b/tools/phonon/CMakeLists.txt new file mode 100644 index 0000000000..283b995590 --- /dev/null +++ b/tools/phonon/CMakeLists.txt @@ -0,0 +1,99 @@ + +# Support Linux from Ubuntu 20.04LTS onward, CentOS 7.x (with EPEL), +# macOS, MSVC 2019 (=Version 16) +cmake_minimum_required(VERSION 3.16) + +# set timestamp of downloaded files to that of archive +if(POLICY CMP0135) + cmake_policy(SET CMP0135 NEW) +endif() + +# set up project +set(PHANA_MINOR_VERSION 48) +project(phonon VERSION ${PHANA_MINOR_VERSION} + DESCRIPTION "Fix phonon post-processor" + LANGUAGES CXX C) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE RelWithDebInfo) +endif() + +# hacks for MSVC to prevent lots of pointless warnings about "unsafe" functions, +# padding and Spectre mitigation +if(MSVC) + add_compile_options(/wd4244) + add_compile_options(/wd4267) + add_compile_options(/wd4711) + add_compile_options(/wd4820) + add_compile_options(/wd5045) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +endif() + +set(CMAKE_PROJECT_VERSION ${PHANA_MINOR_VERSION}) +configure_file(version.h.in version.h @ONLY) +add_executable(phana + main.cpp + disp.cpp + dynmat.cpp + green.cpp + input.cpp + interpolate.cpp + kpath.cpp + memory.cpp + phonon.cpp + phonopy.cpp + qnodes.cpp + timer.cpp +) +target_include_directories(phana PUBLIC $) + +find_package(FFTW3) +if(FFTW3_FOUND) + target_compile_definitions(phana PRIVATE FFTW3) + target_link_libraries(phana PRIVATE FFTW3::FFTW3) +endif() + +# build bundeled libraries +add_subdirectory(tricubic) + +option(USE_SPGLIB "Download and use spglib for phonon DOS and other optional properties" ON) +if(USE_SPGLIB) + set(SPGLIB_URL "https://github.com/spglib/spglib/archive/refs/tags/v1.11.2.1.tar.gz" CACHE STRING "URL for spglib v1.x tarball") + set(SPGLIB_MD5 "3089782bc85b5034dd4765a18ee70bc7" CACHE STRING "MD5 checksum for spglib tarball") + mark_as_advanced(SPGLIB_URL) + mark_as_advanced(SPGLIB_MD5) + GetFallbackURL(SPGLIB_URL SPGLIB_FALLBACK) + + include(ExternalProject) + ExternalProject_Add(spglib_build + URL ${SPGLIB_URL} ${SPGLIB_FALLBACK} + URL_MD5 ${SPGLIB_MD5} + PREFIX ${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext + CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext + -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} + -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -DCMAKE_MAKE_PROGRAM=${CMAKE_MAKE_PROGRAM} + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} + -DCMAKE_POSITION_INDEPENDENT_CODE=ON + UPDATE_COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.spglib ${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext/src/spglib_build/CMakeLists.txt + INSTALL_COMMAND ${CMAKE_COMMAND} --build ${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext/src/spglib_build-build --target install + BUILD_BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext/lib/${CMAKE_STATIC_LIBRARY_PREFIX}symspg${CMAKE_STATIC_LIBRARY_SUFFIX}" + ) + + # workaround for older CMake versions + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext/lib) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext/include) + + add_library(SPGLIB::SYMSPG UNKNOWN IMPORTED) + add_dependencies(SPGLIB::SYMSPG spglib_build) + set_target_properties(SPGLIB::SYMSPG PROPERTIES + IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext/lib/${CMAKE_STATIC_LIBRARY_PREFIX}symspg${CMAKE_STATIC_LIBRARY_SUFFIX}" + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}/spglib_build_ext/include + ) + + target_compile_definitions(phana PRIVATE UseSPG) + target_link_libraries(phana PRIVATE SPGLIB::SYMSPG) +endif() + +target_link_libraries(phana PRIVATE tricubic ${LAPACK_LIBRARIES}) +install(TARGETS phana EXPORT LAMMPS_Targets DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/tools/phonon/Makefile b/tools/phonon/Makefile deleted file mode 100644 index 6afae5f312..0000000000 --- a/tools/phonon/Makefile +++ /dev/null @@ -1,67 +0,0 @@ -.SUFFIXES : .o .cpp -# compiler and flags -CC = g++ -Wno-unused-result -LINK = $(CC) -static -CFLAGS = -O3 $(DEBUG) $(UFLAG) - -OFLAGS = -O3 $(DEBUG) -INC = $(LPKINC) $(TCINC) $(SPGINC) $(FFTINC) -LIB = $(LPKLIB) $(TCLIB) $(SPGLIB) $(FFTLIB) - -# cLapack library needed -LPKINC = -I/opt/clapack/3.2.1/include -LPKLIB = -L/opt/clapack/3.2.1/lib -lclapack -lblas -lf2c -lm - -# Tricubic library needed -TCINC = -I/opt/tricubic/1.0/include -TCLIB = -L/opt/tricubic/1.0/lib -ltricubic - -# spglib, used to get the irreducible q-points -# if SFLAG is not set, spglib won't be used. -SFLAG = -DUseSPG -SPGINC = -I/opt/spglib/1.9.7/include/spglib -SPGLIB = -L/opt/spglib/1.9.7/lib -lsymspg - -# FFTW 3, used to deduce the force constants in real space -# if FFLAG is not set, fftw won't be used. -FFLAG = -DFFTW3 -FFTINC = -I/opt/fftw/3.3.7/include -FFTLIB = -L/opt/fftw/3.3.7/lib -lfftw3 - -# Debug flags -# DEBUG = -g -DDEBUG -UFLAG = $(SFLAG) $(FFLAG) - -#==================================================================== -ROOT = phana -# executable name -EXE = $(ROOT) -#==================================================================== -# source and rules -SRC = $(wildcard *.cpp) -OBJ = $(SRC:.cpp=.o) - -#==================================================================== -all: ${EXE} - -${EXE}: $(OBJ) - $(LINK) $(OFLAGS) $(OBJ) $(LIB) -o $@ - -clean: - rm -f *.o *~ *.mod ${EXE} - -tar: - rm -f ${ROOT}.tar.gz; tar -czvf ${ROOT}.tar.gz *.cpp *.h Makefile README - -ver: - @echo "#define VERSION `git log|grep '^commit'|wc -l`" > version.h - -#==================================================================== -.f.o: - $(FC) $(FFLAGS) $(FREE) $(MPI) ${INC} -c $< -.f90.o: - $(FC) $(FFLAGS) $(FREE) $(MPI) ${INC} -c $< -.c.o: - $(CC) $(CFLAGS) -c $< -.cpp.o: - $(CC) $(CFLAGS) $(INC) -c $< diff --git a/tools/phonon/README b/tools/phonon/README index db69ac50c8..c1430f5940 100644 --- a/tools/phonon/README +++ b/tools/phonon/README @@ -5,34 +5,38 @@ analyse the phonon related information. #------------------------------------------------------------------------------- 1. Dependencies - The clapack library is needed to solve the eigen problems, - which could be downloaded from: - http://www.netlib.org/clapack/ - - The tricubic library is also needed to do tricubic interpolations, - which could now be obtained from: - https://github.com/nbigaouette/libtricubic/ - + The ZHEEVD LAPACK function is needed to solve the eigen problems. + A C++ compilable version based on CLAPACK is included in the linalg folder + and will be automatically built. + + The tricubic library is also needed to do tricubic interpolations. + A copy is included and will be automatically built. + The spglib is optionally needed, enabling one to evaluate the phonon density of states or vibrational thermal properties using only the irreducible q-points in the first Brillouin zone, as well as to evaluate the phonon dispersion curvers with the - automatic mode. Currently, the 1.8.3 version of spglib is used. - It can be obtained from: - http://spglib.sourceforge.net/ + automatic mode. Currently, version 1.11.2.1 of spglib is used. + It is automatically downloaded and compiled unless the -DUSE_SPGLIB=off + variable is set during CMake configuration. FFTW 3 might also be needed if you would like to interface with phonopy: necessary input files for phonopy will be prepared so that you can make use of the functions provided by phonopy. - FFTW 3 can be downloaded from: - http://www.fftw.org - + It is autodetected and used if available. + + FFTW 3 can be downloaded from: http://www.fftw.org + 2. Compilation - To compile the code, one needs therefore to install the above - libraries and set the paths correctly in the Makefile. - Once this is done, by typing - make - will yield the executable "phana". + To compile the code, one needs to have CMake version 3.16 + or later installed. + + The CMake configuration is done with: + cmake -S . -B build + And compilation then performed with: + cmake --build build + The phana (or phana.exe) executable is then available in + the "build" folder 3. Unit system The units of the output frequencies by this code is THz for @@ -46,6 +50,18 @@ 5. Bug report If any bug found, please drop a line to: konglt(at)sjtu.edu.cn +6. Precompiled executable + The "precompiled" folder contains a precompiled and statically + linked Linux executable for x86_64 CPUs. It should work on *any* + Linux machine with using the x86_64 architecture. It includes + spglib support but not fftw3. + +7. Portability + Build and use of phana has been successfully tested on: + - Fedora Linux 38 using GCC, Clang, and MinGW Linux2Windows cross-compiler + - macOS 12 (Monterey) using Xcode + - Windows 11 using Visual Studio 2022 with MSVC and Clang + #------------------------------------------------------------------------------- Author: Ling-Ti Kong, konglt(at)sjtu.edu.cn -May 2020 +Aug 2021 diff --git a/tools/phonon/disp.cpp b/tools/phonon/disp.cpp index 8a53873383..79a22aeee4 100644 --- a/tools/phonon/disp.cpp +++ b/tools/phonon/disp.cpp @@ -1,10 +1,18 @@ -#include "string.h" -#include "qnodes.h" -#include "global.h" + #include "phonon.h" -#include "green.h" -#include "timer.h" + +#include "dynmat.h" +#include "global.h" +#include "input.h" #include "kpath.h" +#include "qnodes.h" + +#include +#include +#include +#include +#include +#include /*------------------------------------------------------------------------------ * Private method to evaluate the phonon dispersion curves @@ -13,19 +21,22 @@ void Phonon::pdisp() { // ask the output file name and write the header. char str[MAXLINE]; - for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n"); + puts("================================================================================"); + #ifdef UseSPG // ask method to generate q-lines int method = 2; printf("Please select your method to generate the phonon dispersion:\n"); printf(" 1. Manual, should always work;\n"); printf(" 2. Automatic, works only for 3D crystals (CMS49-299).\nYour choice [2]: "); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) method = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) method = atoi(strtok(str," \t\n\r\f")); method = 2 - method%2; printf("Your selection: %d\n", method); #endif printf("\nPlease input the filename to output the dispersion data [pdisp.dat]:"); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) strcpy(str, "pdisp.dat"); + input->read_stdin(str); + if (count_words(str) < 1) strcpy(str, "pdisp.dat"); char *ptr = strtok(str," \t\n\r\f"); char *fname = new char[strlen(ptr)+1]; strcpy(fname,ptr); @@ -45,9 +56,9 @@ void Phonon::pdisp() while (1){ for (int i = 0; i < 3; ++i) qstr[i] = qend[i]; - int quit = 0; printf("\nPlease input the start q-point in unit of B1->B3, q to exit [%g %g %g]: ", qstr[0], qstr[1], qstr[2]); - int n = count_words(fgets(str, MAXLINE, stdin)); + input->read_stdin(str); + int n = count_words(str); ptr = strtok(str, " \t\n\r\f"); if ((n == 1) && (strcmp(ptr,"q") == 0)) break; else if (n >= 3){ @@ -56,14 +67,18 @@ void Phonon::pdisp() qstr[2] = atof(strtok(NULL, " \t\n\r\f")); } - do printf("Please input the end q-point in unit of B1->B3: "); - while (count_words(fgets(str, MAXLINE, stdin)) < 3); + while ( 1 ){ + printf("Please input the end q-point in unit of B1->B3: "); + input->read_stdin(str); + if (count_words(str) >= 3) break; + } qend[0] = atof(strtok(str, " \t\n\r\f")); qend[1] = atof(strtok(NULL, " \t\n\r\f")); qend[2] = atof(strtok(NULL, " \t\n\r\f")); printf("Please input the # of points along the line [%d]: ", nq); - if (count_words(fgets(str, MAXLINE, stdin)) > 0) nq = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) nq = atoi(strtok(str," \t\n\r\f")); nq = MAX(nq,2); double *qtmp = new double [3]; @@ -147,7 +162,7 @@ void Phonon::pdisp() printf("\nPhonon dispersion data are written to: %s, you can visualize the results\n", fname); printf("by invoking: `gnuplot pdisp.gnuplot; gv pdisp.eps`\n"); } - for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n"); + puts("================================================================================"); delete []fname; delete qnodes; diff --git a/tools/phonon/dynmat.cpp b/tools/phonon/dynmat.cpp index a6c4105547..aeb8fe6430 100644 --- a/tools/phonon/dynmat.cpp +++ b/tools/phonon/dynmat.cpp @@ -1,7 +1,16 @@ + #include "dynmat.h" -#include "math.h" -#include "version.h" + #include "global.h" +#include "input.h" +#include "interpolate.h" +#include "memory.h" +#include "version.h" +#include "zheevd.h" + +#include +#include +#include /* ---------------------------------------------------------------------------- * Class DynMat stores the Dynamic Matrix read from the binary file from @@ -9,6 +18,7 @@ * ---------------------------------------------------------------------------- */ DynMat::DynMat(int narg, char **arg) { + input = NULL; attyp = NULL; memory = NULL; M_inv_sqrt = NULL; @@ -19,6 +29,8 @@ DynMat::DynMat(int narg, char **arg) attyp = NULL; basis = NULL; flag_reset_gamma = flag_skip = 0; + symprec = -1.; + int flag_save = 0; // analyze the command line options int iarg = 1; @@ -29,9 +41,16 @@ DynMat::DynMat(int narg, char **arg) } else if (strcmp(arg[iarg], "-r") == 0){ flag_reset_gamma = 1; + } else if (strcmp(arg[iarg], "-p") == 0){ + if (++iarg >= narg) help(); + else symprec = fabs(atof(arg[iarg])); + } else if (strcmp(arg[iarg], "-h") == 0){ help(); + } else if (strcmp(arg[iarg], "-save") == 0){ + flag_save = 1; + } else { if (binfile) delete []binfile; int n = strlen(arg[iarg]) + 1; @@ -43,6 +62,8 @@ DynMat::DynMat(int narg, char **arg) } ShowVersion(); + input = new UserInput(flag_save); + // get the binary file name from user input if not found in command line char str[MAXLINE]; if (binfile == NULL) { @@ -50,7 +71,7 @@ DynMat::DynMat(int narg, char **arg) printf("\n"); do { printf("Please input the binary file name from fix_phonon: "); - fgets(str,MAXLINE,stdin); + input->read_stdin(str); ptr = strtok(str, " \n\t\r\f"); } while (ptr == NULL); @@ -137,17 +158,17 @@ DynMat::DynMat(int narg, char **arg) fclose(fp); exit(3); } - if (fread(basis[0], sizeof(double), fftdim, fp) != fftdim){ + if (fread(basis[0], sizeof(double), fftdim, fp) != (size_t)fftdim){ printf("\nError while reading basis info from file: %s\n", binfile); fclose(fp); exit(3); } - if (fread(&attyp[0], sizeof(int), nucell, fp) != nucell){ + if (fread(&attyp[0], sizeof(int), nucell, fp) != (size_t)nucell){ printf("\nError while reading atom types from file: %s\n", binfile); fclose(fp); exit(3); } - if (fread(&M_inv_sqrt[0], sizeof(double), nucell, fp) != nucell){ + if (fread(&M_inv_sqrt[0], sizeof(double), nucell, fp) != (size_t)nucell){ printf("\nError while reading atomic masses from file: %s\n", binfile); fclose(fp); exit(3); @@ -159,6 +180,7 @@ DynMat::DynMat(int narg, char **arg) // initialize interpolation interpolate = new Interpolate(nx,ny,nz,fftdim2,DM_all); + interpolate->input = input; if (flag_reset_gamma) interpolate->reset_gamma(); // Enforcing Austic Sum Rule @@ -217,7 +239,7 @@ void DynMat::writeDMq(double *q) printf("\n"); while ( 1 ){ printf("Please input the filename to output the DM at selected q: "); - fgets(str,MAXLINE,stdin); + input->read_stdin(str); ptr = strtok(str, " \r\t\n\f"); if (ptr) break; } @@ -264,9 +286,9 @@ void DynMat::writeDMq(double *q, const double qr, FILE *fp) int DynMat::geteigen(double *egv, int flag) { char jobz, uplo; - integer n, lda, lwork, lrwork, *iwork, liwork, info; + int n, lda, lwork, lrwork, *iwork, liwork, info; doublecomplex *work; - doublereal *w = &egv[0], *rwork; + double *w = &egv[0], *rwork; n = fftdim; if (flag) jobz = 'V'; @@ -348,7 +370,7 @@ void DynMat::EnforceASR() char str[MAXLINE]; int nasr = 20; if (nucell <= 1) nasr = 1; - printf("\n"); for (int i = 0; i < 80; ++i) printf("="); + printf("\n================================================================================"); // compute and display eigenvalues of Phi at gamma before ASR if (nucell > 100){ @@ -356,7 +378,7 @@ void DynMat::EnforceASR() fflush(stdout); } - double egvs[fftdim]; + double *egvs = new double[fftdim]; for (int i = 0; i < fftdim; ++i) for (int j = 0; j < fftdim; ++j) DM_q[i][j] = DM_all[0][i*fftdim+j]; geteigen(egvs, 0); @@ -370,11 +392,11 @@ void DynMat::EnforceASR() // ask for iterations to enforce ASR printf("Please input the # of iterations to enforce ASR [%d]: ", nasr); - fgets(str,MAXLINE,stdin); + input->read_stdin(str); char *ptr = strtok(str," \t\n\r\f"); if (ptr) nasr = atoi(ptr); if (nasr < 1){ - for (int i=0; i<80; i++) printf("="); printf("\n"); + puts("================================================================================"); return; } @@ -439,9 +461,8 @@ void DynMat::EnforceASR() if (i%10 == 9) printf("\n"); if (i == 99){ printf("...... (%d more skiped)", fftdim-100); break;} } - printf("\n"); - for (int i = 0; i < 80; ++i) printf("="); printf("\n\n"); - + delete[] egvs; + puts("\n================================================================================\n"); return; } @@ -468,7 +489,7 @@ void DynMat::real2rec() for (int i = 0; i < 9; ++i) ibasevec[i] *= vol; - printf("\n"); for (int i = 0; i < 80; ++i) printf("="); + printf("\n================================================================================"); printf("\nBasis vectors of the unit cell in real space:"); for (int i = 0; i < sysdim; ++i){ printf("\n A%d: ", i+1); @@ -479,8 +500,7 @@ void DynMat::real2rec() printf("\n B%d: ", i+1); for (int j = 0; j < sysdim; ++j) printf("%8.4f ", ibasevec[i*3+j]); } - printf("\n"); for (int i = 0; i < 80; ++i) printf("="); printf("\n"); - + puts("\n================================================================================"); return; } @@ -500,16 +520,17 @@ void DynMat::GaussJordan(int n, double *Mat) indxc = new int[n]; indxr = new int[n]; ipiv = new int[n]; - + + irow = icol = -1; for (i = 0; i < n; ++i) ipiv[i] = 0; for (i = 0; i < n; ++i){ - big = 0.; + big = 0.0; for (j = 0; j < n; ++j){ if (ipiv[j] != 1){ for (k = 0; k < n; ++k){ if (ipiv[k] == 0){ idr = j * n + k; - nmjk = abs(Mat[idr]); + nmjk = fabs(Mat[idr]); if (nmjk >= big){ big = nmjk; irow = j; @@ -602,6 +623,9 @@ void DynMat::help() printf(" will also inform the code to skip all q-points that is in the vicinity\n"); printf(" of the gamma point when evaluating phonon DOS and/or phonon dispersion.\n\n"); printf(" By default, this is not set; and not expected for uncharged systems.\n\n"); + printf(" -p prec To define the precision for symmetry identification with spglib.\n"); + printf(" By default, 1.e-3.\n\n"); + printf(" -save To record user input in `script.inp`, facilitating scripting.\n\n"); printf(" -h To print out this help info.\n\n"); printf(" file To define the filename that carries the binary dynamical matrice generated\n"); printf(" by fix-phonon. If not provided, the code will ask for it.\n"); @@ -680,13 +704,13 @@ void DynMat::Define_Conversion_Factor() * ---------------------------------------------------------------------------- */ void DynMat::ShowInfo() { - printf("\n"); for (int i = 0; i < 80; ++i) printf("="); printf("\n"); + puts("\n================================================================================"); printf("Dynamical matrix is read from file: %s\n", binfile); printf("The system size in three dimension: %d x %d x %d\n", nx, ny, nz); printf("Number of atoms per unit cell : %d\n", nucell); printf("System dimension : %d\n", sysdim); printf("Boltzmann constant in used units : %g\n", boltz); - for (int i = 0; i < 80; ++i) printf("="); printf("\n"); + puts("================================================================================"); return; } /* --------------------------------------------------------------------*/ diff --git a/tools/phonon/dynmat.h b/tools/phonon/dynmat.h index 10caa1ce2a..e11badfde6 100644 --- a/tools/phonon/dynmat.h +++ b/tools/phonon/dynmat.h @@ -1,11 +1,9 @@ #ifndef DYNMAT_H #define DYNMAT_H -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "memory.h" -#include "interpolate.h" +#include "zheevd.h" + +#include class DynMat { public: @@ -15,7 +13,7 @@ public: int nx, ny, nz, nucell; int sysdim, fftdim; - double eml2f, eml2fc; + double eml2f, eml2fc, symprec; char *funit; void getDMq(double *); @@ -34,18 +32,18 @@ public: double **basis; int *attyp; + class UserInput *input; + private: int flag_skip, flag_reset_gamma; - Interpolate *interpolate; - - Memory *memory; + class Interpolate *interpolate; + class Memory *memory; - int nasr; void EnforceASR(); char *binfile, *dmfile; - double boltz, q[3]; + double boltz; doublecomplex **DM_all; diff --git a/tools/phonon/global.h b/tools/phonon/global.h index c20a91f317..bd1608ee07 100644 --- a/tools/phonon/global.h +++ b/tools/phonon/global.h @@ -1,7 +1,7 @@ #ifndef GLOBAL_H #define GLOBAL_H -#define ZERO 1.e-8 +#define ZERO 1.0e-8 #define MAXLINE 512 #define MIN(a,b) ((a)>(b)?(b):(a)) diff --git a/tools/phonon/green.cpp b/tools/phonon/green.cpp index 41f5b14886..0f687fd834 100644 --- a/tools/phonon/green.cpp +++ b/tools/phonon/green.cpp @@ -1,10 +1,10 @@ -#include -#include -#include -#include #include "green.h" + +#include "memory.h" + #include -#include "global.h" +#include +#include /******************************************************************************* * The class of Green is designed to evaluate the LDOS via the Green's Function @@ -59,7 +59,6 @@ Green::Green(const int ntm, const int sdim, const int niter, const double min, c dw = (wmax - wmin)/double(nw-1); memory->create(alpha, sysdim,nit, "Green_Green:alpha"); memory->create(beta, sysdim,nit+1,"Green_Green:beta"); - //memory->create(ldos, nw,sysdim, "Green_Green:ldos"); // use Lanczos algorithm to diagonalize the Hessian Lanczos(); @@ -224,8 +223,6 @@ void Green::recursion() { // local variables std::complex Z, rec_x, rec_x_inv; - std::complex cunit = std::complex(0.,1.); - double w = wmin; for (int i = 0; i < nw; ++i){ diff --git a/tools/phonon/green.h b/tools/phonon/green.h index 1a137e53ba..21e3b091dc 100644 --- a/tools/phonon/green.h +++ b/tools/phonon/green.h @@ -1,8 +1,6 @@ #ifndef GREEN_H #define GREEN_H -#include "memory.h" - class Green{ public: Green(const int, const int, const int, const double, const double, @@ -14,12 +12,11 @@ private: void Recursion(); void recursion(); - int ndos; double **ldos; int natom, iatom, sysdim, nit, nw, ndim; double dw, wmin, wmax, epson; double **alpha, **beta, **H; - Memory *memory; + class Memory *memory; }; #endif diff --git a/tools/phonon/input.cpp b/tools/phonon/input.cpp new file mode 100644 index 0000000000..c2059043c7 --- /dev/null +++ b/tools/phonon/input.cpp @@ -0,0 +1,35 @@ +#include "input.h" + +#include "global.h" + +/* ------------------------------------------------------------------- + * Constructor. If flag = 1, output user inputs as script.inp + * ---------------------------------------------------------------- */ +UserInput::UserInput(int flag) +{ + fp = NULL; + if (flag) fp = fopen("script.inp", "w"); + + return; +} + +/* ------------------------------------------------------------------- + * Deconstructor. Output user inputs as required and clear workspace. + * ---------------------------------------------------------------- */ +UserInput::~UserInput() +{ + if (fp) fclose(fp); + fp = NULL; +} + +/* ------------------------------------------------------------------- + * Read stdin and keep a record of it. + * ---------------------------------------------------------------- */ +void UserInput::read_stdin(char *str) +{ + fgets(str, MAXLINE, stdin); + if (fp) fprintf(fp, "%s", str); + + return; +} +/* ---------------------------------------------------------------- */ diff --git a/tools/phonon/input.h b/tools/phonon/input.h new file mode 100644 index 0000000000..c931895c4d --- /dev/null +++ b/tools/phonon/input.h @@ -0,0 +1,17 @@ +#ifndef INPUT_H +#define INPUT_H + +#include + +class UserInput { +public: + UserInput(int); + ~UserInput(); + + void read_stdin(char *); + +private: + FILE *fp; + +}; +#endif diff --git a/tools/phonon/interpolate.cpp b/tools/phonon/interpolate.cpp index 09e261c763..8ea551d1a8 100644 --- a/tools/phonon/interpolate.cpp +++ b/tools/phonon/interpolate.cpp @@ -1,6 +1,14 @@ + #include "interpolate.h" -#include "math.h" + #include "global.h" +#include "input.h" +#include "memory.h" +#include "tricubic.h" + +#include +#include +#include /* ---------------------------------------------------------------------------- * Constructor used to get info from caller, and prepare other necessary data @@ -19,6 +27,7 @@ Interpolate::Interpolate(int nx, int ny, int nz, int ndm, doublecomplex **DM) data = DM; Dfdx = Dfdy = Dfdz = D2fdxdy = D2fdxdz = D2fdydz = D3fdxdydz = NULL; flag_reset_gamma = flag_allocated_dfs = 0; + input = NULL; return; } @@ -265,17 +274,19 @@ void Interpolate::set_method() { char str[MAXLINE]; int im = 1; - printf("\n");for(int i=0; i<80; i++) printf("="); - printf("\nWhich interpolation method would you like to use?\n"); + if (input == NULL) input = new UserInput(0); + + puts("\n================================================================================"); + printf("Which interpolation method would you like to use?\n"); printf(" 1. Tricubic;\n 2. Trilinear;\n"); printf("Your choice [1]: "); - fgets(str,MAXLINE,stdin); + input->read_stdin(str); char *ptr = strtok(str," \t\n\r\f"); if (ptr) im = atoi(ptr); which =2-im%2; printf("Your selection: %d\n", which); - for(int i=0; i<80; i++) printf("="); printf("\n\n"); + puts("================================================================================\n"); if (which == 1) tricubic_init(); diff --git a/tools/phonon/interpolate.h b/tools/phonon/interpolate.h index c650b30908..b9e0242b96 100644 --- a/tools/phonon/interpolate.h +++ b/tools/phonon/interpolate.h @@ -1,16 +1,7 @@ #ifndef INTERPOLATION_H #define INTERPOLATION_H -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "memory.h" -#include "tricubic.h" - -extern "C"{ -#include "f2c.h" -#include "clapack.h" -} +#include "zheevd.h" class Interpolate{ public: @@ -23,11 +14,13 @@ public: int UseGamma; + class UserInput *input; + private: void tricubic_init(); void tricubic(double *, doublecomplex *); void trilinear(double *, doublecomplex *); - Memory *memory; + class Memory *memory; int which; int Nx, Ny, Nz, Npt, ndim; diff --git a/tools/phonon/kpath.cpp b/tools/phonon/kpath.cpp index 842e680611..49730b42b6 100644 --- a/tools/phonon/kpath.cpp +++ b/tools/phonon/kpath.cpp @@ -1,11 +1,19 @@ -#include "global.h" + #include "kpath.h" +#include "global.h" +#include "dynmat.h" +#include "memory.h" +#include "qnodes.h" + #ifdef UseSPG extern "C"{ #include "spglib.h" } -#include "math.h" +#include +#include +#include +#include /* ---------------------------------------------------------------------------- * Class kPath will help to find the high symmetry k-path for a given lattice. @@ -47,11 +55,15 @@ kPath::kPath(DynMat *dm, QNodes *qn) for (int idim = 0; idim < sysdim; ++idim) atpos[i][idim] = dynmat->basis[i][idim]; // get the space group number - double symprec = 1.e-4, pos[num_atom][3]; + double symprec = 1.0e-3; + double **pos; + memory->create(pos,num_atom,3,"kpath:pos"); + if (dynmat->symprec > 0.0) symprec = dynmat->symprec; + for (int i = 0; i < num_atom; ++i) for (int j = 0; j < 3; ++j) pos[i][j] = atpos[i][j]; - spgnum = spg_get_international(symbol, latvec, pos, attyp, num_atom, symprec); - + spgnum = spg_get_international(symbol, latvec, (double (*)[3])pos, attyp, num_atom, symprec); + memory->destroy(pos); return; } @@ -61,7 +73,7 @@ kPath::kPath(DynMat *dm, QNodes *qn) void kPath::show_info() { // display the unit cell info read - for (int ii = 0; ii < 80; ++ii) printf("-"); printf("\n"); + puts("--------------------------------------------------------------------------------"); printf("The basis vectors of the unit cell:\n"); for (int idim = 0; idim < 3; ++idim){ printf(" A%d =", idim+1); @@ -76,12 +88,10 @@ void kPath::show_info() if (num_atom > NUMATOM) printf(" ... (%d atoms omitted.)\n", num_atom-NUMATOM); printf("The space group number of your unit cell is: %d => %s\n", spgnum, symbol); - for (int ii = 0; ii < 80; ++ii) printf("-"); printf("\n"); - + puts("--------------------------------------------------------------------------------"); return; } - /* ---------------------------------------------------------------------------- * Free the memeory used by kPath. * ---------------------------------------------------------------------------- */ @@ -2765,9 +2775,16 @@ void kPath::show_path() if (q == NULL) return; int nbin = q->ndstr.size(); if (nbin > 0){ - printf("\nk-path for the current lattice will be:\n\t%s", q->ndstr[0].c_str()); + puts("\n--------------------------------------------------------------------------------"); + printf("k-path for the current lattice will be:\n %s", q->ndstr[0].c_str()); for (int is = 1; is < nbin; ++is) printf("-%s", q->ndstr[is].c_str()); - printf("\n"); + + printf("\n\nThe fractional coordinates of these paths are:\n"); + for (int is = 0; is < nbin-1; ++is) + printf(" [%6.4f %6.4f %6.4f] --> [%6.4f %6.4f %6.4f] (%s - %s)\n", q->qs[is][0], + q->qs[is][1], q->qs[is][2], q->qe[is][0], q->qe[is][1], q->qe[is][2], + q->ndstr[is].c_str(), q->ndstr[is+1].c_str() ); + puts("--------------------------------------------------------------------------------"); } return; diff --git a/tools/phonon/kpath.h b/tools/phonon/kpath.h index bbcedf15d4..ade1e3a27c 100644 --- a/tools/phonon/kpath.h +++ b/tools/phonon/kpath.h @@ -4,14 +4,9 @@ #ifndef KPATH_H #define KPATH_H -#include "qnodes.h" -#include "dynmat.h" -#include "memory.h" - class kPath{ public: - - kPath(DynMat *, QNodes *); + kPath(class DynMat *, class QNodes *); ~kPath(); void kpath(); @@ -19,13 +14,11 @@ public: void show_info(); private: - - Memory *memory; - - DynMat *dynmat; - QNodes *q; + class Memory *memory; + class DynMat *dynmat; + class QNodes *q; char symbol[11]; - int spgnum, sysdim, fftdim, num_atom, *attyp; + int spgnum, sysdim, num_atom, *attyp; double latvec[3][3], **atpos; }; diff --git a/tools/phonon/main.cpp b/tools/phonon/main.cpp index d7d5baa1cc..d0193a037c 100644 --- a/tools/phonon/main.cpp +++ b/tools/phonon/main.cpp @@ -1,10 +1,6 @@ -#include "stdio.h" -#include "stdlib.h" #include "dynmat.h" #include "phonon.h" -using namespace std; - int main(int argc, char** argv) { diff --git a/tools/phonon/memory.cpp b/tools/phonon/memory.cpp index 4d65e83ef8..18dfa2fa43 100644 --- a/tools/phonon/memory.cpp +++ b/tools/phonon/memory.cpp @@ -1,8 +1,8 @@ -#include "stdio.h" -#include "stdlib.h" -#include "string.h" #include "memory.h" +#include +#include + /* ---------------------------------------------------------------------- safe malloc ------------------------------------------------------------------------- */ diff --git a/tools/phonon/memory.h b/tools/phonon/memory.h index ae2feceba3..13eeca4b14 100644 --- a/tools/phonon/memory.h +++ b/tools/phonon/memory.h @@ -4,18 +4,16 @@ #define __STDC_LIMIT_MACROS #define __STDC_FORMAT_MACROS -#include "stdio.h" -#include "stdlib.h" -#include "limits.h" -#include "stdint.h" -#include "inttypes.h" +#include +#include +#include typedef int64_t bigint; #define BIGINT_FORMAT "%" PRId64 #define ATOBIGINT atoll class Memory { - public: +public: Memory(){}; void *smalloc(bigint n, const char *); @@ -24,11 +22,11 @@ class Memory { void fail(const char *); /* ---------------------------------------------------------------------- - create a 1d array -------------------------------------------------------------------------- */ + create a 1d array + ------------------------------------------------------------------------- */ template - TYPE *create(TYPE *&array, int n, const char *name) + TYPE *create(TYPE *&array, int n, const char *name) { bigint nbytes = sizeof(TYPE) * n; array = (TYPE *) smalloc(nbytes,name); @@ -36,42 +34,42 @@ class Memory { }; template - TYPE **create(TYPE **&array, int n, const char *name) {fail(name);} + TYPE **create(TYPE **&, int, const char *name) {fail(name);} /* ---------------------------------------------------------------------- grow or shrink 1d array -------------------------------------------------------------------------- */ + ------------------------------------------------------------------------- */ template - TYPE *grow(TYPE *&array, int n, const char *name) + TYPE *grow(TYPE *&array, int n, const char *name) { if (array == NULL) return create(array,n,name); - + bigint nbytes = sizeof(TYPE) * n; array = (TYPE *) srealloc(array,nbytes,name); return array; }; template - TYPE **grow(TYPE **&array, int n, const char *name) {fail(name);} + TYPE **grow(TYPE **&, int, const char *name) {fail(name);} /* ---------------------------------------------------------------------- - destroy a 1d array -------------------------------------------------------------------------- */ + destroy a 1d array + ------------------------------------------------------------------------- */ template - void destroy(TYPE *array) + void destroy(TYPE *array) { sfree(array); }; /* ---------------------------------------------------------------------- - create a 1d array with index from nlo to nhi inclusive + create a 1d array with index from nlo to nhi inclusive cannot grow it -------------------------------------------------------------------------- */ + ------------------------------------------------------------------------- */ template - TYPE *create1d_offset(TYPE *&array, int nlo, int nhi, const char *name) + TYPE *create1d_offset(TYPE *&array, int nlo, int nhi, const char *name) { bigint nbytes = sizeof(TYPE) * (nhi-nlo+1); array = (TYPE *) smalloc(nbytes,name); @@ -80,76 +78,76 @@ class Memory { } template - TYPE **create1d_offset(TYPE **&array, int nlo, int nhi, const char *name) + TYPE **create1d_offset(TYPE **&, int, int, const char *name) {fail(name);} /* ---------------------------------------------------------------------- - destroy a 1d array with index offset -------------------------------------------------------------------------- */ + destroy a 1d array with index offset + ------------------------------------------------------------------------- */ template - void destroy1d_offset(TYPE *array, int offset) + void destroy1d_offset(TYPE *array, int offset) { if (array) sfree(&array[offset]); } /* ---------------------------------------------------------------------- - create a 2d array -------------------------------------------------------------------------- */ + create a 2d array + ------------------------------------------------------------------------- */ template - TYPE **create(TYPE **&array, int n1, int n2, const char *name) + TYPE **create(TYPE **&array, int n1, int n2, const char *name) { bigint nbytes = sizeof(TYPE) * n1*n2; TYPE *data = (TYPE *) smalloc(nbytes,name); nbytes = sizeof(TYPE *) * n1; array = (TYPE **) smalloc(nbytes,name); - + int n = 0; for (int i = 0; i < n1; i++) { - array[i] = &data[n]; - n += n2; + array[i] = &data[n]; + n += n2; } return array; } template - TYPE ***create(TYPE ***&array, int n1, int n2, const char *name) + TYPE ***create(TYPE ***&, int, int, const char *name) {fail(name);} /* ---------------------------------------------------------------------- grow or shrink 1st dim of a 2d array last dim must stay the same -------------------------------------------------------------------------- */ + ------------------------------------------------------------------------- */ template - TYPE **grow(TYPE **&array, int n1, int n2, const char *name) + TYPE **grow(TYPE **&array, int n1, int n2, const char *name) { if (array == NULL) return create(array,n1,n2,name); - + bigint nbytes = sizeof(TYPE) * n1*n2; TYPE *data = (TYPE *) srealloc(array[0],nbytes,name); nbytes = sizeof(TYPE *) * n1; array = (TYPE **) srealloc(array,nbytes,name); - + int n = 0; for (int i = 0; i < n1; i++) { - array[i] = &data[n]; - n += n2; + array[i] = &data[n]; + n += n2; } return array; } template - TYPE ***grow(TYPE ***&array, int n1, int n2, const char *name) + TYPE ***grow(TYPE ***&, int, int, const char *name) {fail(name);} /* ---------------------------------------------------------------------- - destroy a 2d array -------------------------------------------------------------------------- */ + destroy a 2d array + ------------------------------------------------------------------------- */ template - void destroy(TYPE **array) + void destroy(TYPE **array) { if (array == NULL) return; sfree(array[0]); @@ -157,42 +155,11 @@ class Memory { } /* ---------------------------------------------------------------------- - create a 2d array with 2nd index from n2lo to n2hi inclusive - cannot grow it -------------------------------------------------------------------------- */ + create a 3d array + ------------------------------------------------------------------------- */ template - TYPE **create2d_offset(TYPE **&array, int n1, int n2lo, int n2hi, - const char *name) - { - int n2 = n2hi - n2lo + 1; - create(array,n1,n2,name); - for (int i = 0; i < n1; i++) array[i] -= n2lo; - return array; - } - - template - TYPE ***create2d_offset(TYPE ***&array, int n1, int n2lo, int n2hi, - const char *name) {fail(name);} - -/* ---------------------------------------------------------------------- - destroy a 2d array with 2nd index offset -------------------------------------------------------------------------- */ - - template - void destroy2d_offset(TYPE **array, int offset) - { - if (array == NULL) return; - sfree(&array[0][offset]); - sfree(array); - } - -/* ---------------------------------------------------------------------- - create a 3d array -------------------------------------------------------------------------- */ - - template - TYPE ***create(TYPE ***&array, int n1, int n2, int n3, const char *name) + TYPE ***create(TYPE ***&array, int n1, int n2, int n3, const char *name) { bigint nbytes = sizeof(TYPE) * n1*n2*n3; TYPE *data = (TYPE *) smalloc(nbytes,name); @@ -200,62 +167,62 @@ class Memory { TYPE **plane = (TYPE **) smalloc(nbytes,name); nbytes = sizeof(TYPE **) * n1; array = (TYPE ***) smalloc(nbytes,name); - + int i,j; int n = 0; for (i = 0; i < n1; i++) { - array[i] = &plane[i*n2]; - for (j = 0; j < n2; j++) { - plane[i*n2+j] = &data[n]; - n += n3; - } + array[i] = &plane[i*n2]; + for (j = 0; j < n2; j++) { + plane[i*n2+j] = &data[n]; + n += n3; + } } return array; } template - TYPE ****create(TYPE ****&array, int n1, int n2, int n3, const char *name) + TYPE ****create(TYPE ****&, int, int, int, const char *name) {fail(name);} /* ---------------------------------------------------------------------- grow or shrink 1st dim of a 3d array last 2 dims must stay the same -------------------------------------------------------------------------- */ + ------------------------------------------------------------------------- */ template - TYPE ***grow(TYPE ***&array, int n1, int n2, int n3, const char *name) + TYPE ***grow(TYPE ***&array, int n1, int n2, int n3, const char *name) { if (array == NULL) return create(array,n1,n2,n3,name); - + bigint nbytes = sizeof(TYPE) * n1*n2*n3; TYPE *data = (TYPE *) srealloc(array[0][0],nbytes,name); nbytes = sizeof(TYPE *) * n1*n2; TYPE **plane = (TYPE **) srealloc(array[0],nbytes,name); nbytes = sizeof(TYPE **) * n1; array = (TYPE ***) srealloc(array,nbytes,name); - + int i,j; int n = 0; for (i = 0; i < n1; i++) { - array[i] = &plane[i*n2]; - for (j = 0; j < n2; j++) { - plane[i*n2+j] = &data[n]; - n += n3; - } + array[i] = &plane[i*n2]; + for (j = 0; j < n2; j++) { + plane[i*n2+j] = &data[n]; + n += n3; + } } return array; } template - TYPE ****grow(TYPE ****&array, int n1, int n2, int n3, const char *name) + TYPE ****grow(TYPE ****&, int, int, int, const char *name) {fail(name);} /* ---------------------------------------------------------------------- - destroy a 3d array -------------------------------------------------------------------------- */ + destroy a 3d array + ------------------------------------------------------------------------- */ template - void destroy(TYPE ***array) + void destroy(TYPE ***array) { if (array == NULL) return; sfree(array[0][0]); @@ -263,168 +230,23 @@ class Memory { sfree(array); } -/* ---------------------------------------------------------------------- - create a 3d array with 1st index from n1lo to n1hi inclusive - cannot grow it -------------------------------------------------------------------------- */ - - template - TYPE ***create3d_offset(TYPE ***&array, int n1lo, int n1hi, - int n2, int n3, const char *name) - { - int n1 = n1hi - n1lo + 1; - create(array,n1,n2,n3,name); - array -= n1lo; - return array; - } - - template - TYPE ****create3d_offset(TYPE ****&array, int n1lo, int n1hi, - int n2, int n3, const char *name) - {fail(name);} - -/* ---------------------------------------------------------------------- - free a 3d array with 1st index offset -------------------------------------------------------------------------- */ - - template - void destroy3d_offset(TYPE ***array, int offset) - { - if (array) destroy(&array[offset]); - } - -/* ---------------------------------------------------------------------- - create a 3d array with - 1st index from n1lo to n1hi inclusive, - 2nd index from n2lo to n2hi inclusive, - 3rd index from n3lo to n3hi inclusive - cannot grow it -------------------------------------------------------------------------- */ - - template - TYPE ***create3d_offset(TYPE ***&array, int n1lo, int n1hi, - int n2lo, int n2hi, int n3lo, int n3hi, - const char *name) - { - int n1 = n1hi - n1lo + 1; - int n2 = n2hi - n2lo + 1; - int n3 = n3hi - n3lo + 1; - create(array,n1,n2,n3,name); - - for (int i = 0; i < n1*n2; i++) array[0][i] -= n3lo; - for (int i = 0; i < n1; i++) array[i] -= n2lo; - array -= n1lo; - return array; - } - - template - TYPE ****create3d_offset(TYPE ****&array, int n1lo, int n1hi, - int n2lo, int n2hi, int n3lo, int n3hi, - const char *name) - {fail(name);} - -/* ---------------------------------------------------------------------- - free a 3d array with all 3 indices offset -------------------------------------------------------------------------- */ - - template - void destroy3d_offset(TYPE ***array, - int n1_offset, int n2_offset, int n3_offset) - { - if (array == NULL) return; - sfree(&array[n1_offset][n2_offset][n3_offset]); - sfree(&array[n1_offset][n2_offset]); - sfree(&array[n1_offset]); - } - -/* ---------------------------------------------------------------------- - create a 4d array -------------------------------------------------------------------------- */ - - template - TYPE ****create(TYPE ****&array, int n1, int n2, int n3, int n4, - const char *name) - { - bigint nbytes = sizeof(TYPE) * n1*n2*n3*n4; - TYPE *data = (double *) smalloc(nbytes,name); - nbytes = sizeof(TYPE *) * n1*n2*n3; - TYPE **cube = (double **) smalloc(nbytes,name); - nbytes = sizeof(TYPE **) * n1*n2; - TYPE ***plane = (double ***) smalloc(nbytes,name); - nbytes = sizeof(TYPE ***) * n1; - array = (double ****) smalloc(nbytes,name); - - int i,j,k; - int n = 0; - for (i = 0; i < n1; i++) { - array[i] = &plane[i*n2]; - for (j = 0; j < n2; j++) { - plane[i*n2+j] = &cube[i*n2*n3+j*n3]; - for (k = 0; k < n3; k++) { - cube[i*n2*n3+j*n3+k] = &data[n]; - n += n4; - } - } - } - return array; - } - - template - TYPE *****create(TYPE *****&array, int n1, int n2, int n3, int n4, - const char *name) - {fail(name);} - -/* ---------------------------------------------------------------------- - destroy a 4d array -------------------------------------------------------------------------- */ - - template - void destroy(TYPE ****array) - { - if (array == NULL) return; - sfree(array[0][0][0]); - sfree(array[0][0]); - sfree(array[0]); - sfree(array); - } - /* ---------------------------------------------------------------------- memory usage of arrays, including pointers -------------------------------------------------------------------------- */ + ------------------------------------------------------------------------- */ template - bigint usage(TYPE *array, int n) + bigint usage(TYPE *, int n) { bigint bytes = sizeof(TYPE) * n; return bytes; } template - bigint usage(TYPE **array, int n1, int n2) + bigint usage(TYPE **, int n1, int n2) { bigint bytes = sizeof(TYPE) * n1*n2; bytes += sizeof(TYPE *) * n1; return bytes; } - - template - bigint usage(TYPE ***array, int n1, int n2, int n3) - { - bigint bytes = sizeof(TYPE) * n1*n2*n3; - bytes += sizeof(TYPE *) * n1*n2; - bytes += sizeof(TYPE **) * n1; - return bytes; - } - - template - bigint usage(TYPE ****array, int n1, int n2, int n3, int n4) - { - bigint bytes = sizeof(TYPE) * n1*n2*n3*n4; - bytes += sizeof(TYPE *) * n1*n2*n3; - bytes += sizeof(TYPE **) * n1*n2; - bytes += sizeof(TYPE ***) * n1; - return bytes; - } }; - #endif diff --git a/tools/phonon/phonon.cpp b/tools/phonon/phonon.cpp index 56fa409e06..06372dcd1b 100644 --- a/tools/phonon/phonon.cpp +++ b/tools/phonon/phonon.cpp @@ -1,9 +1,18 @@ -#include -#include "string.h" + #include "phonon.h" -#include "green.h" -#include "timer.h" + #include "global.h" +#include "dynmat.h" +#include "green.h" +#include "input.h" +#include "memory.h" +#include "timer.h" +#include "zheevd.h" + +#include +#include +#include +#include #ifdef UseSPG extern "C"{ @@ -27,6 +36,7 @@ Phonon::Phonon(DynMat *dm) dynmat = dm; sysdim = dynmat->sysdim; ndim = dynmat->fftdim; + input = dm->input; dos = NULL; ldos = NULL; qpts = NULL; @@ -42,10 +52,7 @@ Phonon::Phonon(DynMat *dm) // display the menu char str[MAXLINE]; while ( 1 ){ - printf("\n"); - for (int i = 0; i < 37; ++i) printf("="); - printf(" Menu "); - for (int i = 0; i < 37; ++i) printf("="); printf("\n"); + puts("\n===================================== Menu ====================================="); printf(" 1. Phonon DOS evaluation;\n"); printf(" 2. Phonon dispersion curves;\n"); printf(" 3. Dynamical matrix at arbitrary q;\n"); @@ -64,9 +71,10 @@ Phonon::Phonon(DynMat *dm) // read user choice int job = 0; printf("Your choice [0]: "); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) job = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) job = atoi(strtok(str," \t\n\r\f")); printf("\nYour selection: %d\n", job); - for (int i = 0; i < 80; ++i) printf("=");printf("\n\n"); + puts("================================================================================\n"); // now to do the job according to user's choice if (job == 1) pdos(); @@ -138,7 +146,8 @@ void Phonon::pdos() // Now to ask for the output frequency range printf("\nThe frequency range of all q-points are: [%g %g]\n", fmin, fmax); printf("Please input the desired range to get DOS [%g %g]: ", fmin, fmax); - if (count_words(fgets(str,MAXLINE,stdin)) >= 2){ + input->read_stdin(str); + if (count_words(str) >= 2){ fmin = atof(strtok(str," \t\n\r\f")); fmax = atof(strtok(NULL," \t\n\r\f")); } @@ -147,7 +156,8 @@ void Phonon::pdos() ndos = 201; printf("Please input the number of intervals [%d]: ", ndos); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) ndos = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) ndos = atoi(strtok(str," \t\n\r\f")); ndos += (ndos+1)%2; ndos = MAX(2,ndos); @@ -170,7 +180,8 @@ void Phonon::pdos() // smooth dos ? printf("Would you like to smooth the phonon dos? (y/n)[n]: "); - if (count_words(fgets(str,MAXLINE,stdin)) > 0){ + input->read_stdin(str); + if (count_words(str) > 0){ char *flag = strtok(str," \t\n\r\f"); if (strcmp(flag,"y") == 0 || strcmp(flag,"Y") == 0) smooth(dos, ndos); } @@ -194,7 +205,8 @@ void Phonon::writeDOS() char str[MAXLINE]; // now to output the phonon DOS printf("\nPlease input the filename to write DOS [pdos.dat]: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) strcpy(str, "pdos.dat"); + input->read_stdin(str); + if (count_words(str) < 1) strcpy(str, "pdos.dat"); char *fname = strtok(str," \t\n\r\f"); printf("The total phonon DOS will be written to file: %s\n", fname); @@ -234,7 +246,7 @@ void Phonon::writeLDOS() const double one3 = 1./double(sysdim); char str[MAXLINE]; for (int ilocal = 0; ilocal < nlocal; ++ilocal){ - sprintf(str,"pldos_%d.dat", locals[ilocal]); + snprintf(str, MAXLINE-1, "pldos_%d.dat", locals[ilocal]); char *fname = strtok(str," \t\n\r\f"); FILE *fp = fopen(fname, "w"); fname = NULL; @@ -281,7 +293,7 @@ void Phonon::ldos_rsgf() fmin = fmax = egvs[0]; for (int i = 1; i < ndim; ++i){fmin = MIN(fmin, egvs[i]); fmax = MAX(fmax, egvs[i]);} - delete []egvs; + delete[] egvs; } else { fmin = 0.; fmax = 20.; @@ -297,7 +309,8 @@ void Phonon::ldos_rsgf() printf("\nThere are %d atoms in each unit cell of your lattice.\n", dynmat->nucell); printf("Please input the index/index range/index range and increment of atom(s)\n"); printf("in the unit cell to evaluate LDOS, q to exit [%d]: ", ik); - int nr = count_words( fgets(str,MAXLINE,stdin) ); + input->read_stdin(str); + int nr = count_words(str); if (nr < 1){ istr = iend = ik; iinc = 1; @@ -327,7 +340,8 @@ void Phonon::ldos_rsgf() } printf("Please input the frequency range to evaluate LDOS [%g %g]: ", fmin, fmax); - if (count_words(fgets(str,MAXLINE,stdin)) >= 2){ + input->read_stdin(str); + if (count_words(str) >= 2){ fmin = atof(strtok(str," \t\n\r\f")); fmax = atof(strtok(NULL," \t\n\r\f")); } @@ -335,16 +349,19 @@ void Phonon::ldos_rsgf() printf("The frequency range for your LDOS is [%g %g].\n", fmin, fmax); printf("Please input the desired number of points in LDOS [%d]: ", ndos); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) ndos = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) ndos = atoi(strtok(str," \t\n\r\f")); if (ndos < 2) break; ndos += (ndos+1)%2; printf("Please input the maximum # of Lanczos iterations [%d]: ", nit); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) nit = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) nit = atoi(strtok(str," \t\n\r\f")); if (nit < 1) break; printf("Please input the value of epsilon for delta-function [%g]: ", eps); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) eps = atof(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) eps = atof(strtok(str," \t\n\r\f")); if (eps <= 0.) break; // prepare array for local pdos @@ -395,8 +412,11 @@ void Phonon::dmanyq() { char str[MAXLINE]; double q[3]; - do printf("Please input the q-point to output the dynamical matrix:"); - while (count_words(fgets(str,MAXLINE,stdin)) < 3); + while ( 1 ){ + printf("Please input the q-point to output the dynamical matrix: "); + input->read_stdin(str); + if (count_words(str) >= 3) break; + } q[0] = atof(strtok(str," \t\n\r\f")); q[1] = atof(strtok(NULL," \t\n\r\f")); q[2] = atof(strtok(NULL," \t\n\r\f")); @@ -413,11 +433,13 @@ void Phonon::dmanyq() void Phonon::vfanyq() { char str[MAXLINE]; - double q[3], egvs[ndim]; + double q[3]; + double *egvs = new double[ndim]; while ( 1 ){ printf("Please input the q-point to compute the frequencies, q to exit: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 3) break; + input->read_stdin(str); + if (count_words(str) < 3) break; q[0] = atof(strtok(str, " \t\n\r\f")); q[1] = atof(strtok(NULL," \t\n\r\f")); @@ -427,9 +449,11 @@ void Phonon::vfanyq() dynmat->geteigen(egvs, 0); printf("q-point: [%lg %lg %lg], ", q[0], q[1], q[2]); printf("vibrational frequencies at this q-point:\n"); - for (int i = 0; i < ndim; ++i) printf("%lg ", egvs[i]); printf("\n\n"); + for (int i = 0; i < ndim; ++i) printf("%lg ", egvs[i]); + printf("\n\n"); } - + + delete[] egvs; return; } @@ -439,15 +463,18 @@ void Phonon::vfanyq() void Phonon::vecanyq() { char str[MAXLINE]; - double q[3], egvs[ndim]; + double q[3]; + double *egvs = new double[ndim]; doublecomplex **eigvec = dynmat->DM_q; printf("Please input the filename to output the result [eigvec.dat]: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) strcpy(str,"eigvec.dat"); + input->read_stdin(str); + if (count_words(str) < 1) strcpy(str,"eigvec.dat"); FILE *fp = fopen(strtok(str," \t\n\r\f"), "w"); while ( 1 ){ printf("Please input the q-point to compute the frequencies, q to exit: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 3) break; + input->read_stdin(str); + if (count_words(str) < 3) break; q[0] = atof(strtok(str, " \t\n\r\f")); q[1] = atof(strtok(NULL," \t\n\r\f")); @@ -475,6 +502,7 @@ void Phonon::vecanyq() fprintf(fp,"\n"); } fclose(fp); + delete[] egvs; eigvec = NULL; return; } @@ -488,7 +516,8 @@ void Phonon::DMdisp() char str[MAXLINE]; printf("Please input the filename to output the DM data [DMDisp.dat]: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) strcpy(str, "DMDisp.dat"); + input->read_stdin(str); + if (count_words(str) < 1) strcpy(str, "DMDisp.dat"); char *fname = strtok(str," \t\n\r\f"); FILE *fp = fopen(fname, "w"); fname = NULL; @@ -503,7 +532,8 @@ void Phonon::DMdisp() for (int i = 0; i < 3; ++i) qstr[i] = qend[i]; printf("\nPlease input the start q-point in unit of B1->B3, q to exit [%g %g %g]: ", qstr[0], qstr[1], qstr[2]); - int n = count_words(fgets(str,MAXLINE,stdin)); + input->read_stdin(str); + int n = count_words(str); char *ptr = strtok(str," \t\n\r\f"); if ((n == 1) && (strcmp(ptr,"q") == 0)) break; else if (n >= 3){ @@ -512,14 +542,18 @@ void Phonon::DMdisp() qstr[2] = atof(strtok(NULL," \t\n\r\f")); } - do printf("Please input the end q-point in unit of B1->B3: "); - while (count_words(fgets(str,MAXLINE,stdin)) < 3); + while ( 1 ){ + printf("Please input the end q-point in unit of B1->B3: "); + input->read_stdin(str); + if (count_words(str) >= 3) break; + } qend[0] = atof(strtok(str," \t\n\r\f")); qend[1] = atof(strtok(NULL," \t\n\r\f")); qend[2] = atof(strtok(NULL," \t\n\r\f")); printf("Please input the # of points along the line [%d]: ", nq); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) nq = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) nq = atoi(strtok(str," \t\n\r\f")); nq = MAX(nq,2); for (int i=0; i<3; i++) qinc[i] = (qend[i]-qstr[i])/double(nq-1); @@ -588,7 +622,8 @@ void Phonon::therm() char str[MAXLINE]; printf("\nPlease input the filename to output thermal properties [therm.dat]:"); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) strcpy(str, "therm.dat"); + input->read_stdin(str); + if (count_words(str) < 1) strcpy(str, "therm.dat"); char *fname = strtok(str," \t\n\r\f"); FILE *fp = fopen(fname, "a"); fname = NULL; // header line @@ -630,7 +665,8 @@ void Phonon::therm() fprintf(fp,"%lg %lg %lg %lg %lg %lg\n", T, Uvib, Svib, Fvib, ZPE, Cvib); printf("Please input the desired temperature (K), enter to exit: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) break; + input->read_stdin(str); + if (count_words(str) < 1) break; T = atof(strtok(str," \t\n\r\f")); } while (T > 0.); @@ -646,12 +682,14 @@ void Phonon::local_therm() { char str[MAXLINE]; printf("\nWould you like to compute the local thermal properties (y/n)[n]: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) return; + input->read_stdin(str); + if (count_words(str) < 1) return; char *ptr = strtok(str," \t\n\r\f"); if (strcmp(ptr,"y") != 0 && strcmp(ptr, "Y") != 0 && strcmp(ptr, "yes") != 0) return; printf("Please input the filename to output vibrational thermal info [localtherm.dat]: "); - if (count_words(fgets(str,MAXLINE,stdin)) < 1) strcpy(str, "localtherm.dat"); + input->read_stdin(str); + if (count_words(str) < 1) strcpy(str, "localtherm.dat"); FILE *fp = fopen(strtok(str," \t\n\r\f"), "w"); fprintf(fp,"# atom Temp U_vib (eV) S_vib (kB) F_vib (eV) C_vib (kB) ZPE (eV)\n"); @@ -672,7 +710,8 @@ void Phonon::local_therm() while ( 1 ){ printf("\nPlease input the temperature at which to evaluate the local vibrational\n"); printf("thermal properties, non-positive number to exit [%g]: ", T); - if (count_words(fgets(str,MAXLINE,stdin)) > 0){ + input->read_stdin(str); + if (count_words(str) > 0){ T = atoi(strtok(str," \t\n\r\f")); if (T <= 0.) break; } @@ -765,7 +804,8 @@ void Phonon::QMesh() printf("\nThe q-mesh size from the read dynamical matrix is: %d x %d x %d\n", nx, ny, nz); printf("A denser mesh can be interpolated, but NOTE a too dense mesh can cause segmentation fault.\n"); printf("Please input your desired q-mesh size [%d %d %d]: ", nx, ny, nz); - if (count_words(fgets(str,MAXLINE,stdin)) >= 3){ + input->read_stdin(str); + if (count_words(str) >= 3){ nx = atoi(strtok(str," \t\n\r\f")); ny = atoi(strtok(NULL," \t\n\r\f")); nz = atoi(strtok(NULL," \t\n\r\f")); @@ -780,7 +820,8 @@ void Phonon::QMesh() int method = 2; printf("Please select your method to generate the q-points:\n"); printf(" 1. uniform;\n 2. Monkhost-Pack mesh;\nYour choice [2]: "); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) method = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) method = atoi(strtok(str," \t\n\r\f")); method = 2 - method%2; printf("Your selection: %d\n", method); #endif @@ -831,7 +872,7 @@ void Phonon::QMesh() for (int idim = 0; idim < sysdim; ++idim) atpos[i][idim] = dynmat->basis[i][idim]; // display the unit cell info read - printf("\n");for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n"); + puts("\n================================================================================"); printf("The basis vectors of the unit cell:\n"); for (int idim = 0; idim < 3; ++idim) printf(" A%d = %lg %lg %lg\n", idim+1, latvec[0][idim], latvec[1][idim], latvec[2][idim]); @@ -845,14 +886,21 @@ void Phonon::QMesh() mesh[0] = nx; mesh[1] = ny; mesh[2] = nz; shift[0] = shift[1] = shift[2] = 0; int num_grid = mesh[0]*mesh[1]*mesh[2]; - int grid_point[num_grid][3], map[num_grid]; - double symprec = 1.e-4, pos[num_atom][3]; + int **grid_point; + memory->create(grid_point, num_grid, 3, "phonon:grid_point"); + int *map = new int[num_grid]; + double symprec = 1.0e-3; + double **pos; + memory->create(pos, num_atom, 3, "phonon:pos"); + if (dynmat->symprec > 0.) symprec = dynmat->symprec; for (int i = 0; i < num_atom; ++i) - for (int j = 0; j < 3; ++j) pos[i][j] = atpos[i][j]; + for (int j = 0; j < 3; ++j) + pos[i][j] = atpos[i][j]; // if spglib >= 1.0.3 is used - nq = spg_get_ir_reciprocal_mesh(grid_point, map, mesh, shift, is_time_reversal, latvec, pos, attyp, num_atom, symprec); + nq = spg_get_ir_reciprocal_mesh((int (*)[3])grid_point, map, mesh, shift, is_time_reversal, + latvec, (double (*)[3])pos, attyp, num_atom, symprec); memory->create(wt, nq, "QMesh:wt"); memory->create(qpts, nq,3,"QMesh:qpts"); @@ -873,11 +921,14 @@ void Phonon::QMesh() qpts[numq][2] = double(grid_point[i][2])/double(mesh[2]); numq++; } - wt[iq2idx[iq]] += 1.; + wt[iq2idx[iq]] += 1.0; } - delete []iq2idx; - - double wsum = 0.; + delete[] iq2idx; + delete[] map; + memory->destroy(grid_point); + memory->destroy(pos); + + double wsum = 0.0; for (int iq = 0; iq < nq; ++iq) wsum += wt[iq]; for (int iq = 0; iq < nq; ++iq) wt[iq] /= wsum; @@ -898,7 +949,8 @@ void Phonon::ldos_egv() char str[MAXLINE], *ptr; printf("\nThe # of atoms per cell is: %d, please input the atom IDs to compute\n", dynmat->nucell); printf("local PDOS, IDs begin with 0: "); - int nmax = count_words(fgets(str,MAXLINE,stdin)); + input->read_stdin(str); + int nmax = count_words(str); if (nmax < 1) return; memory->destroy(locals); @@ -920,7 +972,8 @@ void Phonon::ldos_egv() fmin = 0.; fmax = 10.; printf("Please input the freqency (nv, THz) range to compute PDOS [%g %g]: ", fmin, fmax); - if (count_words(fgets(str,MAXLINE,stdin)) >= 2) { + input->read_stdin(str); + if (count_words(str) >= 2) { fmin = atof(strtok(str," \t\n\r\f")); fmax = atof(strtok(NULL," \t\n\r\f")); } @@ -928,7 +981,8 @@ void Phonon::ldos_egv() ndos = 201; printf("Please input your desired # of points in PDOS [%d]: ", ndos); - if (count_words(fgets(str,MAXLINE,stdin)) > 0) ndos = atoi(strtok(str," \t\n\r\f")); + input->read_stdin(str); + if (count_words(str) > 0) ndos = atoi(strtok(str," \t\n\r\f")); if (ndos < 2) return; ndos += (ndos+1)%2; @@ -957,7 +1011,8 @@ void Phonon::ldos_egv() Timer *time = new Timer(); // memory and pointer for eigenvalues and eigenvectors - double egval[ndim], offset=fmin-0.5*df; + double offset=fmin-0.5*df; + double *egval = new double[ndim]; doublecomplex **egvec = dynmat->DM_q; printf("\nNow to compute the phonons and DOSs "); fflush(stdout); @@ -985,6 +1040,7 @@ void Phonon::ldos_egv() } } } + delete[] egval; egvec = NULL; printf("Done!\nNow to normalize the DOSs ..."); fflush(stdout); @@ -1008,10 +1064,7 @@ void Phonon::ldos_egv() * ---------------------------------------------------------------------------- */ void Phonon::ShowCell() { - printf("\n"); - for (int i = 0; i < 30; ++i) printf("="); - printf(" Unit Cell Info "); - for (int i = 0; i < 30; ++i) printf("="); printf("\n"); + puts("============================== Unit Cell Info =============================="); printf("Number of atoms in the unit cell: %d\n", dynmat->nucell); printf("Basis vectors of the unit cell:\n"); printf(" %15.8f %15.8f %15.8f\n", dynmat->basevec[0], dynmat->basevec[1], dynmat->basevec[2]); @@ -1024,8 +1077,7 @@ void Phonon::ShowCell() printf("Atomic type and fractional coordinates:\n"); for (int i = 0; i < dynmat->nucell; ++i) printf("%4d %12.8f %12.8f %12.8f\n", dynmat->attyp[i], dynmat->basis[i][0], dynmat->basis[i][1], dynmat->basis[i][2]); - for (int i = 0; i < 80; ++i) printf("="); - printf("\n"); + puts("================================================================================"); return; } @@ -1101,7 +1153,7 @@ int Phonon::count_words(const char *line) strcpy(copy,line); char *ptr; - if (ptr = strchr(copy,'#')) *ptr = '\0'; + if ((ptr = strchr(copy,'#'))) *ptr = '\0'; if (strtok(copy," \t\n\r\f") == NULL) { memory->destroy(copy); diff --git a/tools/phonon/phonon.h b/tools/phonon/phonon.h index 69a1fe5d50..46ce17f268 100644 --- a/tools/phonon/phonon.h +++ b/tools/phonon/phonon.h @@ -1,22 +1,16 @@ #ifndef PHONON_H #define PHONON_H -#include "stdio.h" -#include "stdlib.h" -#include -#include "dynmat.h" -#include "memory.h" - -using namespace std; - class Phonon{ public: - Phonon(DynMat *); + Phonon(class DynMat *); ~Phonon(); - DynMat *dynmat; + class DynMat *dynmat; private: + class UserInput *input; + int nq, ndim, sysdim; double **qpts, *wt; double **eigs; @@ -25,7 +19,7 @@ private: double *dos, fmin, fmax, df, rdf; double ***ldos; - Memory *memory; + class Memory *memory; void QMesh(); void ComputeAll(); diff --git a/tools/phonon/phonopy.cpp b/tools/phonon/phonopy.cpp index cfe32ab61a..a6b991efac 100644 --- a/tools/phonon/phonopy.cpp +++ b/tools/phonon/phonopy.cpp @@ -1,9 +1,20 @@ + #ifdef FFTW3 -#include + #include "phonopy.h" -#include "math.h" -#include "kpath.h" -#include "fftw3.h" + +#include "global.h" +#include "dynmat.h" +#include "input.h" +#include "memory.h" + +#include + +#include +#include +#include +#include +#include /* ---------------------------------------------------------------------------- * Class Phonopy is designed to interface with phonopy. @@ -14,13 +25,16 @@ Phonopy::Phonopy(DynMat *dynmat) memory = new Memory(); sysdim = dm->sysdim; fftdim = dm->fftdim; + input = dm->input; fftdim2 = fftdim * fftdim; nucell = dm->nucell; nx = ny = nz = 5; write(1); char str[MAXLINE]; - if (count_words(fgets(str,MAXLINE,stdin)) >= 3){ + if (input == NULL) input = new UserInput(0); + input->read_stdin(str); + if (count_words(str) >= 3){ nx = atoi(strtok(str," \t\n\r\f")); ny = atoi(strtok(NULL," \t\n\r\f")); nz = atoi(strtok(NULL," \t\n\r\f")); @@ -36,7 +50,7 @@ Phonopy::Phonopy(DynMat *dynmat) memory->create(mass, nucell, "Phonopy:mass"); for (int i = 0; i < nucell; ++i){ - double m = 1./dm->M_inv_sqrt[i]; + double m = 1.0/dm->M_inv_sqrt[i]; mass[i] = m * m; } @@ -68,7 +82,7 @@ return; void Phonopy::write(int flag) { if (flag == 1){ // basic information - for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n"); + puts("================================================================================"); printf("Now to prepare the input files for phonopy.\n"); printf("The dimension of your present supercell is : %d x %d x %d.\n", dm->nx, dm->ny, dm->nz); printf("The size of the force constant matrix will be: %d x %d.\n", dm->npt*3, dm->npt*3); @@ -84,19 +98,18 @@ void Phonopy::write(int flag) } else if (flag == 4){ printf("Done!\nThe force constants information is extracted and written to FORCE_CONSTANTS,\n"); printf("the primitive cell is written to POSCAR.primitive, and the input file for\n"); - printf("phonopy band evaluation is written to band.conf.\n"); - printf("One should be able to obtain the phonon band structure after correcting\n"); - printf("the element names in POSCAR.primitive and band.conf by running\n"); - printf("`phonopy --readfc -c POSCAR.primitive -p band.conf`.\n"); - for (int ii = 0; ii < 80; ++ii) printf("-"); - printf("\n*** Remember to change the element names. ***\n"); -#ifdef UseSPG - for (int ii = 0; ii < 80; ++ii) printf("-"); -#endif + printf("phonopy band evaluation is written to band.conf.\n\n"); + printf("One should be able to obtain the phonon band structure after\n"); + printf(" 1) Correcting the `element names` in POSCAR.primitive and band.conf;\n"); + printf(" 2) Running `phonopy --readfc -c POSCAR.primitive -p band.conf`.\n\n"); + printf("Or the phonon density of states after\n"); + printf(" 1) Correcting the `element names` in POSCAR.primitive and mesh.conf;\n"); + printf(" 2) Running `phonopy --readfc -c POSCAR.primitive -p mesh.conf`.\n"); + puts("--------------------------------------------------------------------------------"); + printf("*** Remember to modify the `element names`. ***\n"); } else if (flag == 5){ - for (int ii = 0; ii < 80; ++ii) printf("="); printf("\n"); - + puts("================================================================================"); } return; } @@ -162,7 +175,9 @@ void Phonopy::phonopy() memory->destroy(out); // in POSCAR, atoms are sorted/aggregated by type, while for LAMMPS there is no such requirment - int type_id[nucell], num_type[nucell], ntype = 0; + int *type_id = new int[nucell]; + int *num_type = new int[nucell]; + int ntype = 0; for (int i = 0; i < nucell; ++i) num_type[i] = 0; for (int i = 0; i < nucell; ++i){ int ip = ntype; @@ -221,7 +236,14 @@ void Phonopy::phonopy() // write the primitive cell in POSCAR format fp = fopen("POSCAR.primitive", "w"); fprintf(fp, "Fix-phonon unit cell"); - for (int ip = 0; ip < ntype; ++ip) fprintf(fp, ", Elem-%d: %lg", type_id[ip], mass[ip]); + for (int ip = 0; ip < ntype; ++ip){ + for (int i = 0; i < nucell; ++i){ + if (dm->attyp[i] == type_id[ip]){ + fprintf(fp, ", Elem-%d: %lg", type_id[ip], mass[i]); + break; + } + } + } fprintf(fp, "\n1.\n"); int ndim = 0; for (int idim = 0; idim < 3; ++idim){ @@ -240,57 +262,48 @@ void Phonopy::phonopy() } fclose(fp); -#ifdef UseSPG - // Get high symmetry k-path - QNodes *q = new QNodes(); - kPath *kp = new kPath(dm, q); - kp->kpath(); -#endif - + // mesh.conf + fp = fopen("mesh.conf", "w"); + fprintf(fp, "# From Fix-phonon"); + for (int ip = 0; ip < ntype; ++ip){ + for (int i = 0; i < nucell; ++i){ + if (dm->attyp[i] == type_id[ip]){ + fprintf(fp, ", Elem-%d: %lg", type_id[ip], mass[i]); + break; + } + } + } + fprintf(fp, "\n\nATOM_NAME = "); + for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "Elem-%d ", type_id[ip]); + fprintf(fp, "\nDIM = %d %d %d\n", nx, ny, nz); + fprintf(fp, "MP = 31 31 31\nFORCE_CONSTANTS = READ\n"); + fprintf(fp, "#FC_SYMMETRY = .TRUE.\n#SYMMETRY_TOLERANCE = 0.01\n"); + fclose(fp); + + // band.conf fp = fopen("band.conf", "w"); fprintf(fp, "# From Fix-phonon"); - for (int ip = 0; ip < ntype; ++ip) fprintf(fp, ", Elem-%d: %lg", type_id[ip], mass[ip]); + for (int ip = 0; ip < ntype; ++ip){ + for (int i = 0; i < nucell; ++i){ + if (dm->attyp[i] == type_id[ip]){ + fprintf(fp, ", Elem-%d: %lg", type_id[ip], mass[i]); + break; + } + } + } fprintf(fp, "\n\nATOM_NAME = "); for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "Elem-%d ", type_id[ip]); - fprintf(fp, "\nDIM = %d %d %d\nBAND = ", nx, ny, nz); -#ifdef UseSPG - int nsect = q->qs.size(); - for (int i = 0; i < nsect; ++i){ - fprintf(fp, " %lg %lg %lg", q->qs[i][0], q->qs[i][1], q->qs[i][2]); - if (i+1 < nsect){ - double dq = 0.; - for (int j = 0; j < 3; ++j) dq += (q->qe[i][j] - q->qs[i+1][j]) * (q->qe[i][j] - q->qs[i+1][j]); - if (dq > ZERO) { - fprintf(fp, " %lg %lg %lg,", q->qe[i][0], q->qe[i][1], q->qe[i][2]); - } - } else if (i+1 == nsect){ - fprintf(fp, " %lg %lg %lg\n", q->qe[i][0], q->qe[i][1], q->qe[i][2]); - } - } -#endif - fprintf(fp, "\nBAND_POINTS = 21\nBAND_LABELS ="); -#ifdef UseSPG - for (int i = 0; i < q->ndstr.size(); ++i){ - std::size_t found = q->ndstr[i].find("{/Symbol G}"); - if (found != std::string::npos) q->ndstr[i].replace(found, found+11, "$\\Gamma$"); - found = q->ndstr[i].find("/"); - if (found != std::string::npos) q->ndstr[i].replace(found, found, " "); - fprintf(fp, " %s", q->ndstr[i].c_str()); - } -#endif - fprintf(fp, "\nFORCE_CONSTANTS = READ\nBAND_CONNECTION = .TRUE.\n"); + fprintf(fp, "\nDIM = %d %d %d\nBAND = AUTO\n", nx, ny, nz); + fprintf(fp, "BAND_POINTS = 21\nFORCE_CONSTANTS = READ\nBAND_CONNECTION = .TRUE.\n"); + fprintf(fp, "#FC_SYMMETRY = .TRUE.\n#SYMMETRY_TOLERANCE = 0.01\n"); // output info write(4); -#ifdef UseSPG - kp->show_path(); - delete kp; - delete q; -#endif write(5); - -return; + delete[] type_id; + delete[] num_type; + return; } /*------------------------------------------------------------------------------ @@ -304,7 +317,7 @@ int Phonopy::count_words(const char *line) strcpy(copy,line); char *ptr; - if (ptr = strchr(copy,'#')) *ptr = '\0'; + if ((ptr = strchr(copy,'#'))) *ptr = '\0'; if (strtok(copy," \t\n\r\f") == NULL) { memory->destroy(copy); @@ -314,7 +327,7 @@ int Phonopy::count_words(const char *line) while (strtok(NULL," \t\n\r\f")) n++; memory->destroy(copy); -return n; + return n; } /*----------------------------------------------------------------------------*/ #endif diff --git a/tools/phonon/phonopy.h b/tools/phonon/phonopy.h index 2f3006e791..e1200b8242 100644 --- a/tools/phonon/phonopy.h +++ b/tools/phonon/phonopy.h @@ -4,22 +4,16 @@ #ifndef PHONOPY_H #define PHONOPY_H -#include "stdio.h" -#include "stdlib.h" -#include "string.h" -#include "memory.h" -#include "qnodes.h" -#include "dynmat.h" -#include "global.h" +#include "zheevd.h" class Phonopy { public: - Phonopy(DynMat *); + Phonopy(class DynMat *); ~Phonopy(); private: - Memory *memory; - char str[MAXLINE]; + class UserInput *input; + class Memory *memory; int npt, fftdim2; // local variables int nx, ny, nz, nucell; // local variables int sysdim, fftdim; // local variables @@ -27,7 +21,7 @@ private: doublecomplex **FC_all; - DynMat *dm; + class DynMat *dm; void write(int); void get_my_FC(); void phonopy(); diff --git a/tools/phonon/timer.cpp b/tools/phonon/timer.cpp index 953257340d..b94bed40b1 100644 --- a/tools/phonon/timer.cpp +++ b/tools/phonon/timer.cpp @@ -1,4 +1,7 @@ #include "timer.h" + +#include + /* ----------------------------------------------------------------------------- * Initialization of time * -------------------------------------------------------------------------- */ diff --git a/tools/phonon/timer.h b/tools/phonon/timer.h index cd04dea56d..993a33f9f3 100644 --- a/tools/phonon/timer.h +++ b/tools/phonon/timer.h @@ -1,9 +1,7 @@ #ifndef TIMER_H #define TIMER_H -#include "stdio.h" -#include "stdlib.h" -#include "time.h" +#include class Timer { public: diff --git a/tools/phonon/tricubic/CMakeLists.txt b/tools/phonon/tricubic/CMakeLists.txt new file mode 100644 index 0000000000..d70b44c2b2 --- /dev/null +++ b/tools/phonon/tricubic/CMakeLists.txt @@ -0,0 +1,18 @@ + +# Support Linux from Ubuntu 20.04LTS onward, CentOS 7.x (with EPEL), +# macOS, MSVC 2019 (=Version 16) +cmake_minimum_required(VERSION 3.16) + +# set up project +project(tricubic VERSION 1.1 DESCRIPTION "Tricubic library" LANGUAGES CXX) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) + +# hacks for MSVC to prevent lots of pointless warnings about "unsafe" functions +if(MSVC) + add_compile_options(/wd4244) + add_compile_options(/wd4267) + add_compile_definitions(_CRT_SECURE_NO_WARNINGS) +endif() + +add_library(tricubic STATIC tricubic.cpp) +target_include_directories(tricubic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/tools/phonon/tricubic/LICENSE b/tools/phonon/tricubic/LICENSE new file mode 100644 index 0000000000..d60c31a97a --- /dev/null +++ b/tools/phonon/tricubic/LICENSE @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/tools/phonon/tricubic/README.md b/tools/phonon/tricubic/README.md new file mode 100644 index 0000000000..0e8058339e --- /dev/null +++ b/tools/phonon/tricubic/README.md @@ -0,0 +1,28 @@ +# libtricubic + +This folder contains a slightly refactored version of version 1.0 of +the _libtricubic_ library, developed by François Lekien in 2004. + +The following paper explaining the method was published in 2005: + +> Lekien, F., & Marsden, J. (2005). _Tricubic interpolation in three +> dimensions._ International Journal for Numerical Methods in Engineering, +> 63(3), 455–471. doi:10.1002/nme.1296 + +Some additional notes and the full matrix can be found in the technical notes: + +> Lekien, F., Coulliette, C., & Marsden, J. (2004). _Tricubic Engine - Technical +> Notes and Full Matrix. + +The main article refers to the author's website +(http://gyre.cds.caltech.edu/pub/software/tricubic/) to download the code and +documentation. Unfortunately, this website no longer exists. Even the +archive.org snapshot is useless; [A single snapshot from December 3rd 2009 is +available](https://web.archive.org/web/20091203115835/http://gyre.cds.caltech.edu/pub/software/tricubic) +which seems like an FTP listing. No files are accessible. + +The source code was obtained from https://github.com/nbigaouette/libtricubic/ +Only the sources for the library were retained. No functional changes were +made, but some common programming conventions were applied, source files +merged, and build support for CMake added. + diff --git a/tools/phonon/tricubic/tricubic.cpp b/tools/phonon/tricubic/tricubic.cpp new file mode 100644 index 0000000000..974ed6aa52 --- /dev/null +++ b/tools/phonon/tricubic/tricubic.cpp @@ -0,0 +1,185 @@ + +#include "tricubic.h" + +#include + +static const int A[64][64] = { + { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-3, 3, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 2,-2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9,-9,-9, 9, 0, 0, 0, 0, 6, 3,-6,-3, 0, 0, 0, 0, 6,-6, 3,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-6, 6, 6,-6, 0, 0, 0, 0,-3,-3, 3, 3, 0, 0, 0, 0,-4, 4,-2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-2,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-6, 6, 6,-6, 0, 0, 0, 0,-4,-2, 4, 2, 0, 0, 0, 0,-3, 3,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4,-4,-4, 4, 0, 0, 0, 0, 2, 2,-2,-2, 0, 0, 0, 0, 2,-2, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,-9,-9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3,-6,-3, 0, 0, 0, 0, 6,-6, 3,-3, 0, 0, 0, 0, 4, 2, 2, 1, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3,-3, 3, 3, 0, 0, 0, 0,-4, 4,-2, 2, 0, 0, 0, 0,-2,-2,-1,-1, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4,-2, 4, 2, 0, 0, 0, 0,-3, 3,-3, 3, 0, 0, 0, 0,-2,-1,-2,-1, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,-4,-4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,-2,-2, 0, 0, 0, 0, 2,-2, 2,-2, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0}, + {-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 9,-9, 0, 0,-9, 9, 0, 0, 6, 3, 0, 0,-6,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,-6, 0, 0, 3,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-6, 6, 0, 0, 6,-6, 0, 0,-3,-3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 4, 0, 0,-2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-2, 0, 0,-1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0, 0, 0,-1, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,-9, 0, 0,-9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 3, 0, 0,-6,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,-6, 0, 0, 3,-3, 0, 0, 4, 2, 0, 0, 2, 1, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 0, 0, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3,-3, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 4, 0, 0,-2, 2, 0, 0,-2,-2, 0, 0,-1,-1, 0, 0}, + { 9, 0,-9, 0,-9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0,-6, 0,-3, 0, 6, 0,-6, 0, 3, 0,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 9, 0,-9, 0,-9, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 3, 0,-6, 0,-3, 0, 6, 0,-6, 0, 3, 0,-3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 2, 0, 2, 0, 1, 0}, + {-27,27,27,-27,27,-27,-27,27,-18,-9,18, 9,18, 9,-18,-9,-18,18,-9, 9,18,-18, 9,-9,-18,18,18,-18,-9, 9, 9,-9,-12,-6,-6,-3,12, 6, 6, 3,-12,-6,12, 6,-6,-3, 6, 3,-12,12,-6, 6,-6, 6,-3, 3,-8,-4,-4,-2,-4,-2,-2,-1}, + {18,-18,-18,18,-18,18,18,-18, 9, 9,-9,-9,-9,-9, 9, 9,12,-12, 6,-6,-12,12,-6, 6,12,-12,-12,12, 6,-6,-6, 6, 6, 6, 3, 3,-6,-6,-3,-3, 6, 6,-6,-6, 3, 3,-3,-3, 8,-8, 4,-4, 4,-4, 2,-2, 4, 4, 2, 2, 2, 2, 1, 1}, + {-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0,-3, 0, 3, 0, 3, 0,-4, 0, 4, 0,-2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-2, 0,-1, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0,-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 0,-3, 0, 3, 0, 3, 0,-4, 0, 4, 0,-2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-2, 0,-1, 0,-1, 0}, + {18,-18,-18,18,-18,18,18,-18,12, 6,-12,-6,-12,-6,12, 6, 9,-9, 9,-9,-9, 9,-9, 9,12,-12,-12,12, 6,-6,-6, 6, 6, 3, 6, 3,-6,-3,-6,-3, 8, 4,-8,-4, 4, 2,-4,-2, 6,-6, 6,-6, 3,-3, 3,-3, 4, 2, 4, 2, 2, 1, 2, 1}, + {-12,12,12,-12,12,-12,-12,12,-6,-6, 6, 6, 6, 6,-6,-6,-6, 6,-6, 6, 6,-6, 6,-6,-8, 8, 8,-8,-4, 4, 4,-4,-3,-3,-3,-3, 3, 3, 3, 3,-4,-4, 4, 4,-2,-2, 2, 2,-4, 4,-4, 4,-2, 2,-2, 2,-2,-2,-2,-2,-1,-1,-1,-1}, + { 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-6, 6, 0, 0, 6,-6, 0, 0,-4,-2, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2,-1, 0, 0,-2,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 4,-4, 0, 0,-4, 4, 0, 0, 2, 2, 0, 0,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-6, 6, 0, 0, 6,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4,-2, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-3, 3, 0, 0,-3, 3, 0, 0,-2,-1, 0, 0,-2,-1, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,-4, 0, 0,-4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0,-2,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,-2, 0, 0, 2,-2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0}, + {-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 0,-2, 0, 4, 0, 2, 0,-3, 0, 3, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0,-2, 0,-1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0,-6, 0, 6, 0, 6, 0,-6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,-4, 0,-2, 0, 4, 0, 2, 0,-3, 0, 3, 0,-3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,-2, 0,-1, 0,-2, 0,-1, 0}, + {18,-18,-18,18,-18,18,18,-18,12, 6,-12,-6,-12,-6,12, 6,12,-12, 6,-6,-12,12,-6, 6, 9,-9,-9, 9, 9,-9,-9, 9, 8, 4, 4, 2,-8,-4,-4,-2, 6, 3,-6,-3, 6, 3,-6,-3, 6,-6, 3,-3, 6,-6, 3,-3, 4, 2, 2, 1, 4, 2, 2, 1}, + {-12,12,12,-12,12,-12,-12,12,-6,-6, 6, 6, 6, 6,-6,-6,-8, 8,-4, 4, 8,-8, 4,-4,-6, 6, 6,-6,-6, 6, 6,-6,-4,-4,-2,-2, 4, 4, 2, 2,-3,-3, 3, 3,-3,-3, 3, 3,-4, 4,-2, 2,-4, 4,-2, 2,-2,-2,-1,-1,-2,-2,-1,-1}, + { 4, 0,-4, 0,-4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,-2, 0,-2, 0, 2, 0,-2, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, 0, 0, 4, 0,-4, 0,-4, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0,-2, 0,-2, 0, 2, 0,-2, 0, 2, 0,-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0}, + {-12,12,12,-12,12,-12,-12,12,-8,-4, 8, 4, 8, 4,-8,-4,-6, 6,-6, 6, 6,-6, 6,-6,-6, 6, 6,-6,-6, 6, 6,-6,-4,-2,-4,-2, 4, 2, 4, 2,-4,-2, 4, 2,-4,-2, 4, 2,-3, 3,-3, 3,-3, 3,-3, 3,-2,-1,-2,-1,-2,-1,-2,-1}, + { 8,-8,-8, 8,-8, 8, 8,-8, 4, 4,-4,-4,-4,-4, 4, 4, 4,-4, 4,-4,-4, 4,-4, 4, 4,-4,-4, 4, 4,-4,-4, 4, 2, 2, 2, 2,-2,-2,-2,-2, 2, 2,-2,-2, 2, 2,-2,-2, 2,-2, 2,-2, 2,-2, 2,-2, 1, 1, 1, 1, 1, 1, 1, 1} +}; + +static const char tricubic_version_stored[] = "1.1"; + +static int ijk2n(int i, int j, int k) { + return(i+4*j+16*k); +} + +static void point2xyz(int p, int *x, int *y, int *z) { + switch (p) { + case 0: *x=0; *y=0; *z=0; break; + case 1: *x=1; *y=0; *z=0; break; + case 2: *x=0; *y=1; *z=0; break; + case 3: *x=1; *y=1; *z=0; break; + case 4: *x=0; *y=0; *z=1; break; + case 5: *x=1; *y=0; *z=1; break; + case 6: *x=0; *y=1; *z=1; break; + case 7: *x=1; *y=1; *z=1; break; + default:*x=0; *y=0; *z=0; + } +} + +const char *tricubic_version(void) { + return(tricubic_version_stored); +} + +void tricubic_pointID2xyz(int id, int *x, int *y, int *z) { + point2xyz(id,x,y,z); +} + +void tricubic_pointID2xyz(int id, double *x, double *y, double *z) { + int x2,y2,z2; + point2xyz(id,&x2,&y2,&z2); + *x=(double)(x2); + *y=(double)(y2); + *z=(double)(z2); +} + +void tricubic_get_coeff_stacked(double a[64], double x[64]) { + int i,j; + for (i=0;i<64;i++) { + a[i]=(double)(0.0); + for (j=0;j<64;j++) { + a[i]+=A[i][j]*x[j]; + } + } +} + +void tricubic_get_coeff(double a[64], double f[8], double dfdx[8], double dfdy[8], double dfdz[8], double d2fdxdy[8], double d2fdxdz[8], double d2fdydz[8], double d3fdxdydz[8]) { + int i; + double x[64]; + for (i=0;i<8;i++) { + x[0+i]=f[i]; + x[8+i]=dfdx[i]; + x[16+i]=dfdy[i]; + x[24+i]=dfdz[i]; + x[32+i]=d2fdxdy[i]; + x[40+i]=d2fdxdz[i]; + x[48+i]=d2fdydz[i]; + x[56+i]=d3fdxdydz[i]; + } + tricubic_get_coeff_stacked(a,x); +} + +double tricubic_eval(double a[64], double x, double y, double z) { + int i,j,k; + double ret=(double)(0.0); + /* TRICUBIC EVAL + This is the short version of tricubic_eval. It is used to compute + the value of the function at a given point (x,y,z). To compute + partial derivatives of f, use the full version with the extra args. + */ + for (i=0;i<4;i++) { + for (j=0;j<4;j++) { + for (k=0;k<4;k++) { + ret+=a[ijk2n(i,j,k)]*pow(x,i)*pow(y,j)*pow(z,k); + } + } + } + return(ret); +} + +double tricubic_eval(double a[64], double x, double y, double z, int derx, int dery, int derz) { + int i,j,k; + double ret=(double)(0.0); + double cont; + int w; + /* TRICUBIC_EVAL + The full version takes 3 extra integers args that allows to evaluate + any partial derivative of f at the point + derx=dery=derz=0 => f + derx=2 dery=derz=0 => d2f/dx2 + derx=dery=derz=1 =? d3f/dxdydz + NOTICE that (derx>3)||(dery>3)||(derz>3) => returns 0.0 + this computes \frac{\partial ^{derx+dery+derz} d}{\partial x ^{derx} \partial y ^{dery} \partial z ^{derz}} + */ + for (i=derx;i<4;i++) { + for (j=dery;j<4;j++) { + for (k=derz;k<4;k++) { + cont=a[ijk2n(i,j,k)]*pow(x,i-derx)*pow(y,j-dery)*pow(z,k-derz); + for (w=0;w Date: Sat, 29 Apr 2023 03:55:54 -0400 Subject: [PATCH 106/448] update so it can be built either standalone or as subdir with LAMMPS --- tools/phonon/CMakeLists.txt | 21 +++++++++++++++++++++ tools/phonon/version.h.in | 1 + 2 files changed, 22 insertions(+) create mode 100644 tools/phonon/version.h.in diff --git a/tools/phonon/CMakeLists.txt b/tools/phonon/CMakeLists.txt index 283b995590..02ccee25a3 100644 --- a/tools/phonon/CMakeLists.txt +++ b/tools/phonon/CMakeLists.txt @@ -47,6 +47,10 @@ add_executable(phana ) target_include_directories(phana PUBLIC $) +if(NOT LAMMPS_DIR) + set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../cmake/Modules) + set(LAMMPS_THIRDPARTY_URL "https://download.lammps.org/thirdparty") +endif() find_package(FFTW3) if(FFTW3_FOUND) target_compile_definitions(phana PRIVATE FFTW3) @@ -56,12 +60,29 @@ endif() # build bundeled libraries add_subdirectory(tricubic) +# standalone build must build our own version of linalg +if(NOT LAMMPS_DIR) + if(NOT USE_INTERNAL_LINALG) + find_package(LAPACK) + find_package(BLAS) + endif() + if(NOT LAPACK_FOUND OR NOT BLAS_FOUND OR USE_INTERNAL_LINALG) + file(GLOB LINALG_SOURCES CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/linalg/[^.]*.cpp) + add_library(linalg STATIC ${LINALG_SOURCES}) + set(BLAS_LIBRARIES "$") + set(LAPACK_LIBRARIES "$") + else() + list(APPEND LAPACK_LIBRARIES ${BLAS_LIBRARIES}) + endif() +endif() + option(USE_SPGLIB "Download and use spglib for phonon DOS and other optional properties" ON) if(USE_SPGLIB) set(SPGLIB_URL "https://github.com/spglib/spglib/archive/refs/tags/v1.11.2.1.tar.gz" CACHE STRING "URL for spglib v1.x tarball") set(SPGLIB_MD5 "3089782bc85b5034dd4765a18ee70bc7" CACHE STRING "MD5 checksum for spglib tarball") mark_as_advanced(SPGLIB_URL) mark_as_advanced(SPGLIB_MD5) + include(LAMMPSUtils) GetFallbackURL(SPGLIB_URL SPGLIB_FALLBACK) include(ExternalProject) diff --git a/tools/phonon/version.h.in b/tools/phonon/version.h.in new file mode 100644 index 0000000000..1f6fb01373 --- /dev/null +++ b/tools/phonon/version.h.in @@ -0,0 +1 @@ +#define VERSION @CMAKE_PROJECT_VERSION@ From a2b74c846648a6b956aa66915a79340f1f6f2ee2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 20:23:13 -0400 Subject: [PATCH 107/448] small doc update --- doc/src/Tools.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/Tools.rst b/doc/src/Tools.rst index 2eae1aabc7..bccb9abe73 100644 --- a/doc/src/Tools.rst +++ b/doc/src/Tools.rst @@ -883,9 +883,9 @@ dependencies and redirects the download to the local cache. phonon tool ------------------------ -The phonon subdirectory contains a post-processing tool useful for -analyzing the output of the :doc:`fix phonon ` command in -the PHONON package. +The phonon subdirectory contains a post-processing tool, *phana*, useful +for analyzing the output of the :doc:`fix phonon ` command +in the PHONON package. See the README file for instruction on building the tool and what library it needs. And see the examples/PACKAGES/phonon directory From 73b8bb8617cdddc2a2a812090d40bb26e2a9b539 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 20:41:44 -0400 Subject: [PATCH 108/448] fix bug that breaks compilation with -DLAMMPS_BIGBIG --- src/compute_count_type.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index feadcb04ba..4fd814cdff 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -144,7 +144,7 @@ void ComputeCountType::compute_vector() // bond types can be negative for SHAKE else if (mode == BOND) { - int **bond_atom = atom->bond_atom; + tagint **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; int *num_bond = atom->num_bond; int *mask = atom->mask; From b38544a9e86612e130690dcd56460c3d50802a0a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 20:43:05 -0400 Subject: [PATCH 109/448] apply clang-format --- src/compute_count_type.cpp | 50 ++++++++++++++++++++------------------ src/compute_count_type.h | 2 +- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 4fd814cdff..786506280e 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -23,7 +23,7 @@ using namespace LAMMPS_NS; -enum{ATOM,BOND}; +enum { ATOM, BOND }; /* ---------------------------------------------------------------------- */ @@ -33,9 +33,12 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute( // process args - if (strcmp(arg[3],"atom") == 0) mode = ATOM; - else if (strcmp(arg[3],"bond") == 0) mode = BOND; - else error->all(FLERR, "Invalid compute count/type keyword {}",arg[3]); + if (strcmp(arg[3], "atom") == 0) + mode = ATOM; + else if (strcmp(arg[3], "bond") == 0) + mode = BOND; + else + error->all(FLERR, "Invalid compute count/type keyword {}", arg[3]); if (mode == ATOM) { vector_flag = 1; @@ -49,10 +52,10 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute( } if (mode == BOND && !atom->avec->bonds_allow) - error->all(FLERR,"Cannot use compute count/type bond command with no bonds allowed"); + error->all(FLERR, "Cannot use compute count/type bond command with no bonds allowed"); // output vector - + vector = new double[size_vector]; // work vectors @@ -86,13 +89,13 @@ double ComputeCountType::compute_scalar() int **bond_type = atom->bond_type; int nlocal = atom->nlocal; - int m,nbond; + int m, nbond; int count = 0; // count broken bonds with bond_type = 0 // ignore group setting since 2 atoms in a broken bond // can be arbitrarily far apart - + for (int i = 0; i < nlocal; i++) { nbond = num_bond[i]; for (m = 0; m < nbond; m++) @@ -101,14 +104,13 @@ double ComputeCountType::compute_scalar() // sum across procs as bigint, then convert to double // correct for double counting if newton_bond off - + bigint bcount_me = count; bigint bcount; MPI_Allreduce(&bcount_me, &bcount, 1, MPI_LMP_BIGINT, MPI_SUM, world); if (force->newton_bond == 0) bcount /= 2; - if (bcount > MAXDOUBLEINT) - error->all(FLERR,"Compute count/type overflow"); + if (bcount > MAXDOUBLEINT) error->all(FLERR, "Compute count/type overflow"); scalar = bcount; return scalar; } @@ -132,12 +134,11 @@ void ComputeCountType::compute_vector() for (int m = 0; m < ntypes; m++) count[m] = 0; for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - count[type[i]-1]++; + if (mask[i] & groupbit) count[type[i] - 1]++; nvec = ntypes; } - + // count bonds by type // both atoms in bond must be in group to be counted // skip type = 0 bonds, they are counted by compute_scalar @@ -150,11 +151,11 @@ void ComputeCountType::compute_vector() int *mask = atom->mask; int nlocal = atom->nlocal; int nbondtypes = atom->nbondtypes; - - int j,m,nbond,itype; + + int j, m, nbond, itype; int flag = 0; for (int m = 0; m < nbondtypes; m++) count[m] = 0; - + for (int i = 0; i < nlocal; i++) { nbond = num_bond[i]; for (m = 0; m < nbond; m++) { @@ -166,17 +167,19 @@ void ComputeCountType::compute_vector() flag = 1; continue; } - + if ((mask[i] & groupbit) && (mask[j] & groupbit)) { - if (itype > 0) count[itype-1]++; - else count[-itype-1]++; + if (itype > 0) + count[itype - 1]++; + else + count[-itype - 1]++; } } } int flagany; MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); - if (flagany) error->all(FLERR,"Missing bond atom in compute count/type"); + if (flagany) error->all(FLERR, "Missing bond atom in compute count/type"); nvec = nbondtypes; } @@ -186,11 +189,10 @@ void ComputeCountType::compute_vector() for (int m = 0; m < nvec; m++) bcount_me[m] = count[m]; MPI_Allreduce(bcount_me, bcount, nvec, MPI_LMP_BIGINT, MPI_SUM, world); - if (force->newton_bond == 0) + if (force->newton_bond == 0) for (int m = 0; m < nvec; m++) bcount[m] /= 2; for (int m = 0; m < nvec; m++) - if (bcount[m] > MAXDOUBLEINT) - error->all(FLERR,"Compute count/type overflow"); + if (bcount[m] > MAXDOUBLEINT) error->all(FLERR, "Compute count/type overflow"); for (int m = 0; m < nvec; m++) vector[m] = bcount[m]; } diff --git a/src/compute_count_type.h b/src/compute_count_type.h index 0ed7a22467..27b1669b1d 100644 --- a/src/compute_count_type.h +++ b/src/compute_count_type.h @@ -34,7 +34,7 @@ class ComputeCountType : public Compute { protected: int mode; - + int *count; bigint *bcount_me; bigint *bcount; From ff29ef7d3160c9597b9fb637619982afcf8e0adc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 20:57:32 -0400 Subject: [PATCH 110/448] use more obvious representation of 2^53 --- src/lmptype.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lmptype.h b/src/lmptype.h index 891d5bdf89..769f730d6a 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -95,8 +95,8 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT_MAX #define MAXBIGINT INT64_MAX -#define MAXDOUBLEINT 9007199254740992 // 2^53 - +#define MAXDOUBLEINT (1L<<53) + #define MPI_LMP_TAGINT MPI_INT #define MPI_LMP_IMAGEINT MPI_INT #define MPI_LMP_BIGINT MPI_LL @@ -133,7 +133,7 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT64_MAX #define MAXBIGINT INT64_MAX -#define MAXDOUBLEINT 9007199254740992 // 2^53 +#define MAXDOUBLEINT (1L<<53) #define MPI_LMP_TAGINT MPI_LL #define MPI_LMP_IMAGEINT MPI_LL From ba747e554489263046a67e6a4a551c8f080e1c0f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 21:10:18 -0400 Subject: [PATCH 111/448] suppress bogus warnings with gcc 13.0 and later --- src/fmt/core.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/fmt/core.h b/src/fmt/core.h index 0634f94412..86d60485f2 100644 --- a/src/fmt/core.h +++ b/src/fmt/core.h @@ -1742,7 +1742,14 @@ constexpr auto encode_types() -> unsigned long long { template FMT_CONSTEXPR FMT_INLINE auto make_value(T&& val) -> value { +#if FMT_GCC_VERSION && FMT_GCC_VERSION >= 1300 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdangling-reference" const auto& arg = arg_mapper().map(FMT_FORWARD(val)); +# pragma GCC diagnostic pop +#else + const auto& arg = arg_mapper().map(FMT_FORWARD(val)); +#endif constexpr bool formattable_char = !std::is_same::value; From c8d5b9e4d072c46c1795e696e26fc09b48016510 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 23:52:04 -0400 Subject: [PATCH 112/448] avoid uninitialized pointers --- src/compute_count_type.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 786506280e..0cd109a1eb 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -27,9 +27,10 @@ enum { ATOM, BOND }; /* ---------------------------------------------------------------------- */ -ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) +ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : + Compute(lmp, narg, arg), count(nullptr), bcount(nullptr), bcount_me(nullptr) { - if (narg != 4) error->all(FLERR, "Illegal compute count/type command"); + if (narg != 4) error->all(FLERR, "Incorrect number of args for compute count/type command"); // process args @@ -51,7 +52,7 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute( extvector = 1; } - if (mode == BOND && !atom->avec->bonds_allow) + if ((mode == BOND) && !atom->avec->bonds_allow) error->all(FLERR, "Cannot use compute count/type bond command with no bonds allowed"); // output vector From 56f791eec2b7499a8e38b744c55988085a9811db Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 1 May 2023 23:52:35 -0400 Subject: [PATCH 113/448] avoid uninitialized data access for scalar data --- src/compute.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/compute.cpp b/src/compute.cpp index d7e8e8d5a4..dcad4954fc 100644 --- a/src/compute.cpp +++ b/src/compute.cpp @@ -36,11 +36,9 @@ int Compute::instance_total = 0; /* ---------------------------------------------------------------------- */ Compute::Compute(LAMMPS *lmp, int narg, char **arg) : - Pointers(lmp), - id(nullptr), style(nullptr), - vector(nullptr), array(nullptr), vector_atom(nullptr), - array_atom(nullptr), vector_local(nullptr), array_local(nullptr), extlist(nullptr), - tlist(nullptr), vbiasall(nullptr) + Pointers(lmp), id(nullptr), style(nullptr), vector(nullptr), array(nullptr), + vector_atom(nullptr), array_atom(nullptr), vector_local(nullptr), array_local(nullptr), + extlist(nullptr), tlist(nullptr), vbiasall(nullptr) { instance_me = instance_total++; @@ -69,6 +67,7 @@ Compute::Compute(LAMMPS *lmp, int narg, char **arg) : pressatomflag = peatomflag = 0; create_attribute = 0; tempbias = 0; + scalar = 0.0; timeflag = 0; comm_forward = comm_reverse = 0; @@ -105,8 +104,8 @@ Compute::~Compute() { if (copymode) return; - delete [] id; - delete [] style; + delete[] id; + delete[] style; memory->destroy(tlist); } From 12135bac770ecc591b05a31ad437a72038553b14 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 10:22:37 -0400 Subject: [PATCH 114/448] add unit tests for compute count/type --- unittest/commands/test_compute_global.cpp | 54 +++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index d7573d8d16..4efc3f1b91 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -294,6 +294,60 @@ TEST_F(ComputeGlobalTest, Reduction) EXPECT_DOUBLE_EQ(rep[2], 26); EXPECT_DOUBLE_EQ(rep[3], max[0]); } + +TEST_F(ComputeGlobalTest, Counts) +{ + if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); + + BEGIN_HIDE_OUTPUT(); + command("pair_style lj/cut 10.0"); + command("pair_coeff * * 0.01 3.0"); + command("bond_style harmonic"); + command("bond_coeff * 100.0 1.5"); + + command("variable t1 atom type==1"); + command("variable t2 atom type==2"); + command("variable t3 atom type==3"); + command("variable t4 atom type==4"); + command("variable t5 atom type==5"); + command("compute asum all reduce sum v_t1 v_t2 v_t3 v_t4 v_t5"); + command("compute acnt all count/type atom"); + command("compute bcnt all count/type bond"); + command("thermo_style custom c_asum[*] c_acnt[*]"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + auto asum = get_vector("asum"); + auto acnt = get_vector("acnt"); + auto bcnt = get_vector("bcnt"); + auto bbrk = get_scalar("bcnt"); + + EXPECT_DOUBLE_EQ(bbrk, 0.0); + + EXPECT_DOUBLE_EQ(asum[0], acnt[0]); + EXPECT_DOUBLE_EQ(asum[1], acnt[1]); + EXPECT_DOUBLE_EQ(asum[2], acnt[2]); + EXPECT_DOUBLE_EQ(asum[3], acnt[3]); + EXPECT_DOUBLE_EQ(asum[4], acnt[4]); + + EXPECT_DOUBLE_EQ(bcnt[0], 3.0); + EXPECT_DOUBLE_EQ(bcnt[1], 6.0); + EXPECT_DOUBLE_EQ(bcnt[2], 3.0); + EXPECT_DOUBLE_EQ(bcnt[3], 2.0); + EXPECT_DOUBLE_EQ(bcnt[4], 10.0); + + BEGIN_HIDE_OUTPUT(); + command("delete_bonds all bond 3"); + command("run 0 post no"); + END_HIDE_OUTPUT(); + + EXPECT_DOUBLE_EQ(bbrk, 0.0); // should be 3 + EXPECT_DOUBLE_EQ(bcnt[0], 3.0); + EXPECT_DOUBLE_EQ(bcnt[1], 6.0); + EXPECT_DOUBLE_EQ(bcnt[2], 3.0); // should be 0 + EXPECT_DOUBLE_EQ(bcnt[3], 2.0); + EXPECT_DOUBLE_EQ(bcnt[4], 10.0); +} } // namespace LAMMPS_NS int main(int argc, char **argv) From eacb420e211452392442b34b26add5693dd3c092 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 10:34:36 -0400 Subject: [PATCH 115/448] whitespace --- doc/src/compute_count_type.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index 9ab0b1009f..8cbd6aec9b 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -13,7 +13,7 @@ Syntax * ID, group-ID are documented in :doc:`compute ` command * count/type = style name of this compute command * mode = {atom} or {bond} - + Examples """""""" From d2bb1b420da791f73b141fc1ad52027b17846d16 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 11:49:13 -0400 Subject: [PATCH 116/448] simplify and cleanup --- unittest/commands/test_compute_global.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 4efc3f1b91..7e5b3d4483 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -300,10 +300,8 @@ TEST_F(ComputeGlobalTest, Counts) if (lammps_get_natoms(lmp) == 0.0) GTEST_SKIP(); BEGIN_HIDE_OUTPUT(); - command("pair_style lj/cut 10.0"); - command("pair_coeff * * 0.01 3.0"); - command("bond_style harmonic"); - command("bond_coeff * 100.0 1.5"); + command("pair_style zero 10.0"); + command("pair_coeff * *"); command("variable t1 atom type==1"); command("variable t2 atom type==2"); @@ -341,6 +339,8 @@ TEST_F(ComputeGlobalTest, Counts) command("run 0 post no"); END_HIDE_OUTPUT(); + bcnt = get_vector("bcnt"); + bbrk = get_scalar("bcnt"); EXPECT_DOUBLE_EQ(bbrk, 0.0); // should be 3 EXPECT_DOUBLE_EQ(bcnt[0], 3.0); EXPECT_DOUBLE_EQ(bcnt[1], 6.0); From c5e4f7c5fdb39331149bb361880ea97d39c8b8f2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 11:49:55 -0400 Subject: [PATCH 117/448] modernize --- src/compute_pressure.cpp | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/compute_pressure.cpp b/src/compute_pressure.cpp index 30b83c4996..12e2e22223 100644 --- a/src/compute_pressure.cpp +++ b/src/compute_pressure.cpp @@ -55,13 +55,11 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : if (strcmp(arg[3],"NULL") == 0) id_temp = nullptr; else { id_temp = utils::strdup(arg[3]); - - int icompute = modify->find_compute(id_temp); - if (icompute < 0) - error->all(FLERR,"Could not find compute pressure temperature ID"); - if (modify->compute[icompute]->tempflag == 0) - error->all(FLERR,"Compute pressure temperature ID does not " - "compute temperature"); + auto icompute = modify->get_compute_by_id(id_temp); + if (!icompute) + error->all(FLERR,"Could not find compute pressure temperature ID {}", id_temp); + if (!icompute->tempflag) + error->all(FLERR,"Compute pressure temperature ID {} does not compute temperature", id_temp); } // process optional args @@ -129,8 +127,7 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : // error check if (keflag && id_temp == nullptr) - error->all(FLERR,"Compute pressure requires temperature ID " - "to include kinetic energy"); + error->all(FLERR,"Compute pressure requires temperature ID to include kinetic energy"); vector = new double[size_vector]; nvirial = 0; @@ -141,10 +138,10 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : ComputePressure::~ComputePressure() { - delete [] id_temp; - delete [] vector; - delete [] vptr; - delete [] pstyle; + delete[] id_temp; + delete[] vector; + delete[] vptr; + delete[] pstyle; } /* ---------------------------------------------------------------------- */ @@ -159,10 +156,9 @@ void ComputePressure::init() // fixes could have changed or compute_modify could have changed it if (keflag) { - int icompute = modify->find_compute(id_temp); - if (icompute < 0) - error->all(FLERR,"Could not find compute pressure temperature ID"); - temperature = modify->compute[icompute]; + temperature = modify->get_compute_by_id(id_temp); + if (!temperature) + error->all(FLERR,"Could not find compute pressure temperature ID {}", id_temp); } // recheck if pair style with and without suffix exists @@ -348,6 +344,6 @@ void ComputePressure::virial_compute(int n, int ndiag) void ComputePressure::reset_extra_compute_fix(const char *id_new) { - delete [] id_temp; + delete[] id_temp; id_temp = utils::strdup(id_new); } From 8ca1e2d417f0f7628773a905e0308636e7bb3b9f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 11:50:15 -0400 Subject: [PATCH 118/448] add OpenMP suppression for GNU 13 compilers --- tools/valgrind/OpenMP.supp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/valgrind/OpenMP.supp b/tools/valgrind/OpenMP.supp index 703c71bf74..e92e34e816 100644 --- a/tools/valgrind/OpenMP.supp +++ b/tools/valgrind/OpenMP.supp @@ -134,6 +134,17 @@ fun:GOMP_parallel obj:* } +{ + OpenMP_init_part12 + Memcheck:Leak + match-leak-kinds: reachable + fun:calloc + fun:gomp_malloc_cleared + ... + fun:call_init + ... + obj:* +} { OpenMP_init_clang1 Memcheck:Leak From d13096e08b7159debf77cf51b32914e3f2c20370 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 12:08:55 -0400 Subject: [PATCH 119/448] improve error message --- src/compute_pressure.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compute_pressure.cpp b/src/compute_pressure.cpp index 12e2e22223..2c90af5fc1 100644 --- a/src/compute_pressure.cpp +++ b/src/compute_pressure.cpp @@ -36,10 +36,9 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), - vptr(nullptr), id_temp(nullptr), pstyle(nullptr) + Compute(lmp, narg, arg), vptr(nullptr), id_temp(nullptr), pstyle(nullptr) { - if (narg < 4) error->all(FLERR,"Illegal compute pressure command"); + if (narg < 4) utils::missing_cmd_args(FLERR,"compute pressure", error); if (igroup) error->all(FLERR,"Compute pressure must use group all"); scalar_flag = vector_flag = 1; @@ -52,8 +51,9 @@ ComputePressure::ComputePressure(LAMMPS *lmp, int narg, char **arg) : // store temperature ID used by pressure computation // ensure it is valid for temperature computation - if (strcmp(arg[3],"NULL") == 0) id_temp = nullptr; - else { + if (strcmp(arg[3],"NULL") == 0) { + id_temp = nullptr; + } else { id_temp = utils::strdup(arg[3]); auto icompute = modify->get_compute_by_id(id_temp); if (!icompute) From aa4447413ae32c3c51db83cb75facb8eafcb0d12 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 2 May 2023 13:39:37 -0600 Subject: [PATCH 120/448] expand to angles, dihedrals, impropers --- doc/src/Howto_broken_bonds.rst | 35 ++-- doc/src/compute_count_type.rst | 68 +++++-- src/compute_count_type.cpp | 330 ++++++++++++++++++++++++++------- src/compute_count_type.h | 6 + 4 files changed, 335 insertions(+), 104 deletions(-) diff --git a/doc/src/Howto_broken_bonds.rst b/doc/src/Howto_broken_bonds.rst index 4fd0bcc30f..282d2b32a4 100644 --- a/doc/src/Howto_broken_bonds.rst +++ b/doc/src/Howto_broken_bonds.rst @@ -1,9 +1,9 @@ Broken Bonds ============ -Typically, bond interactions persist for the duration of a simulation -in LAMMPS. However, some commands allow bonds to break, including the -following: +Typically, molecular bond interactions persist for the duration of a +simulation in LAMMPS. However, some commands break bonds dynamically, +including the following: * :doc:`bond_style quartic ` * :doc:`fix bond/break ` @@ -14,39 +14,40 @@ A bond can break if it is stretched beyond a user-defined threshold or more generally if other criteria are met. For the quartic bond style, when a bond is broken its bond type is set -to 0 and pairwise forces between the two atoms in the broken bond are -"turned on". Angles, dihedrals, etc cannot be defined for the system -when :doc:`bond_style quartic ` is used. +to 0 to effectively break it and pairwise forces between the two atoms +in the broken bond are "turned on". Angles, dihedrals, etc cannot be +defined for a system when :doc:`bond_style quartic ` is +used. The :doc:`fix bond/break ` and :doc:`fix bond/react ` commands allow breaking of bonds within a molecular -topology with also defines angles, dihedrals, etc. These fixes will -update internal topology data structures when bonds are broken, so -that the appropriate angle, dihederal, etc interactions are also -turned off. They will also trigger a rebuild of the neighbor list +topology with may also define angles, dihedrals, etc. These commands +update internal topology data structures to remove broken bonds, as +well as the appropriate angle, dihederal, etc interactions which +include the bond. They also trigger a rebuild of the neighbor list when this occurs, to turn on the appropriate pairwise forces. In the BPM package, one can either turn off all pair interactions between bonded particles or leave them on, overlaying pair forces on top of bond forces. To remove pair forces, the special bond list is -dynamically updated. More details can be found on the :doc:`Howto BPM +dynamically updated. More details can be found on the :doc:`Howto BPM ` page. Note that when bonds are dumped to a file via the :doc:`dump local ` command, bonds with type 0 are not included. -The :doc:`delete_bonds ` command can also be used to -query the status of broken bonds (type = 0) or permanently delete -them, e.g.: +The :doc:`delete_bonds ` command can be used to query +the status of broken bonds with type = 0 or permanently delete them, +e.g.: .. code-block:: LAMMPS delete_bonds all stats delete_bonds all bond 0 remove -The compute :doc:`count/type bond ` command -tallies the current number of bonds for each bond type. It also -tallies broken bonds with type = 0. +The compute :doc:`count/type ` command tallies the +current number of bonds (or angles, etc) for each bond (angle, etc) +type. It also tallies broken bonds with type = 0. The compute :doc:`nbond/atom ` command tallies the current number of bonds each atom is part of, excluding broken bonds diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index 9ab0b1009f..e9f531ef64 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -12,7 +12,7 @@ Syntax * ID, group-ID are documented in :doc:`compute ` command * count/type = style name of this compute command -* mode = {atom} or {bond} +* mode = {atom} or {bond} or {angle} or {dihedral} or {improper} Examples """""""" @@ -26,28 +26,46 @@ Description """"""""""" Define a computation that counts the current number of atoms for each -atom type or the number of bonds for each bond type. The former can -be useful if atoms are added to or deleted from the system in random -ways, e.g. via the :doc:`fix deposit `, :doc:`fix pour -`, or :doc:`fix evaporate ` commands. The -latter can be useful in reactive simulations where molecular bonds are -broken or created. +atom type. Or the number of bonds (angles, dihedrals, impropers) for +each bond (angle, dihedral, improper) type. -Note that for this command, bonds are defined as the topological kind -enumerated in a data file, initially read by the :doc:`read_data +The former can be useful if atoms are added to or deleted from the +system in random ways, e.g. via the :doc:`fix deposit `, +:doc:`fix pour `, or :doc:`fix evaporate ` +commands. The latter can be useful in reactive simulations where +molecular bonds are broken or created, as well as angles, dihedrals, +impropers. + +Note that for this command, bonds (angles, etc) are the topological +kind enumerated in a data file, initially read by the :doc:`read_data ` command or defined by the :doc:`molecule ` command. They do not refer to implicit bonds defined on-the-fly by bond-order or reactive pair styles based on the current conformation of small clusters of atoms. -These commands can create and/or break topological bonds: +These commands can turn off topological bonds (angles, etc) by setting +their bond (angle, etc) types to negative values. This command +includes the turned-off bonds (angles, etc) in the count for each +type: +* :doc:`fix shake ` +* :doc:`delete_bonds ` + +These commands can create and/or break topological bonds (angles, +etc). In the case of breaking, they remove the bond (angle, etc) from +the system, so that they no longer exist (:doc:`bond_style quartic +` is the exception, see the discussion below). Thus +they are not included in the counts for each type: + +* :doc:`delete_bonds remove ` +* :doc:`bond_style quartic ` * :doc:`fix bond/react ` * :doc:`fix bond/create ` * :doc:`fix bond/break ` -* :doc:`bond_style quartic ` * :doc:`BPM package ` bond styles +---------- + If the {mode} setting is {atom} then the count of atoms for each atom type is tallied. Only atoms in the specified group are counted. @@ -56,11 +74,22 @@ type is tallied. Only bonds with both atoms in the specified group are counted. For {mode} = {bond}, broken bonds with a bond type of zero are also -counted. Some of the commands listed above which break bonds, do this -by setting their types to zero. See the :doc:`Howto broken bonds -` doc page for details. Note that the group -setting is ignored for broken bonds; all broken bonds in the system -are counted. +counted. The :doc:`bond_style quartic ` breaks a bond +by doing this. See the :doc:`Howto broken bonds ` +doc page for more details. Note that the group setting is ignored for +broken bonds; all broken bonds in the system are counted. + +If the {mode} setting is {angle} then the count of angles for each +angle type is tallied. Only angles with all 3 atoms in the specified +group are counted. + +If the {mode} setting is {dihedral} then the count of dihedrals for +each dihedral type is tallied. Only dihedrals with all 4 atoms in the +specified group are counted. + +If the {mode} setting is {improper} then the count of impropers for +each improper type is tallied. Only impropers with all 4 atoms in the +specified group are counted. ---------- @@ -68,11 +97,12 @@ Output info """"""""""" This compute calculates a global vector of counts. If the mode is -{atom}, the vector length is the number of atom types. If the mode is -{bond}, the vector length is the number of bond types. +{atom} or {bond} or {angle} or {dihedral} or {improper}, then the +vector length is the number of atom types or bond types or angle types +or dihedral types or improper types, respectively. If the mode is {bond} this compute also calculates a global scalar -which is the number of broken bonds. +which is the number of broken bonds with type = 0, as explained above. These values can be used by any command that uses global scalar or vector values from a compute as input. See the :doc:`Howto output diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index feadcb04ba..36aa21da70 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -14,7 +14,6 @@ #include "compute_count_type.h" #include "atom.h" -#include "atom_vec.h" #include "domain.h" #include "error.h" #include "force.h" @@ -23,7 +22,7 @@ using namespace LAMMPS_NS; -enum{ATOM,BOND}; +enum{ATOM,BOND,ANGLE,DIHEDRAL,IMPROPER}; /* ---------------------------------------------------------------------- */ @@ -35,8 +34,24 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute( if (strcmp(arg[3],"atom") == 0) mode = ATOM; else if (strcmp(arg[3],"bond") == 0) mode = BOND; + else if (strcmp(arg[3],"angle") == 0) mode = ANGLE; + else if (strcmp(arg[3],"dihedral") == 0) mode = DIHEDRAL; + else if (strcmp(arg[3],"improper") == 0) mode = IMPROPER; else error->all(FLERR, "Invalid compute count/type keyword {}",arg[3]); + // error check + + if (mode == BOND && !atom->nbondtypes) + error->all(FLERR,"Compute count/type bond command with no bonds defined"); + if (mode == ANGLE && !atom->nangletypes) + error->all(FLERR,"Compute count/type bond command with no angles defined"); + if (mode == DIHEDRAL && !atom->ndihedraltypes) + error->all(FLERR,"Compute count/type dihedral command with no dihedrals defined"); + if (mode == IMPROPER && !atom->nimpropertypes) + error->all(FLERR,"Compute count/type improper command with no impropers defined"); + + // set vector lengths + if (mode == ATOM) { vector_flag = 1; size_vector = atom->ntypes; @@ -46,11 +61,20 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : Compute( size_vector = atom->nbondtypes; extscalar = 1; extvector = 1; + } else if (mode == ANGLE) { + vector_flag = 1; + size_vector = atom->nangletypes; + extvector = 1; + } else if (mode == DIHEDRAL) { + vector_flag = 1; + size_vector = atom->ndihedraltypes; + extvector = 1; + } else if (mode == IMPROPER) { + vector_flag = 1; + size_vector = atom->nimpropertypes; + extvector = 1; } - if (mode == BOND && !atom->avec->bonds_allow) - error->all(FLERR,"Cannot use compute count/type bond command with no bonds allowed"); - // output vector vector = new double[size_vector]; @@ -121,76 +145,246 @@ void ComputeCountType::compute_vector() int nvec; - // count atoms by type - // atom must be in group to be counted - - if (mode == ATOM) { - int *type = atom->type; - int *mask = atom->mask; - int nlocal = atom->nlocal; - int ntypes = atom->ntypes; - - for (int m = 0; m < ntypes; m++) count[m] = 0; - for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - count[type[i]-1]++; - - nvec = ntypes; - } + if (mode == ATOM) nvec = count_atoms(); + else if (mode == BOND) nvec = count_bonds(); + else if (mode == ANGLE) nvec = count_angles(); + else if (mode == DIHEDRAL) nvec = count_dihedrals(); + else if (mode == IMPROPER) nvec = count_impropers(); - // count bonds by type - // both atoms in bond must be in group to be counted - // skip type = 0 bonds, they are counted by compute_scalar - // bond types can be negative for SHAKE - - else if (mode == BOND) { - int **bond_atom = atom->bond_atom; - int **bond_type = atom->bond_type; - int *num_bond = atom->num_bond; - int *mask = atom->mask; - int nlocal = atom->nlocal; - int nbondtypes = atom->nbondtypes; - - int j,m,nbond,itype; - int flag = 0; - for (int m = 0; m < nbondtypes; m++) count[m] = 0; - - for (int i = 0; i < nlocal; i++) { - nbond = num_bond[i]; - for (m = 0; m < nbond; m++) { - itype = bond_type[i][m]; - if (itype == 0) continue; - - j = atom->map(bond_atom[i][m]); - if (j < 0) { - flag = 1; - continue; - } - - if ((mask[i] & groupbit) && (mask[j] & groupbit)) { - if (itype > 0) count[itype-1]++; - else count[-itype-1]++; - } - } - } - - int flagany; - MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); - if (flagany) error->all(FLERR,"Missing bond atom in compute count/type"); - - nvec = nbondtypes; - } - // sum across procs as bigint, then convert to double - // correct for double counting if newton_bond off + // correct for multiple counting if newton_bond off for (int m = 0; m < nvec; m++) bcount_me[m] = count[m]; MPI_Allreduce(bcount_me, bcount, nvec, MPI_LMP_BIGINT, MPI_SUM, world); - if (force->newton_bond == 0) - for (int m = 0; m < nvec; m++) bcount[m] /= 2; - + + if (force->newton_bond == 0) { + if (mode == BOND) + for (int m = 0; m < nvec; m++) bcount[m] /= 2; + else if (mode == ANGLE) + for (int m = 0; m < nvec; m++) bcount[m] /= 3; + if (mode == DIHEDRAL || mode == IMPROPER) + for (int m = 0; m < nvec; m++) bcount[m] /= 4; + } + for (int m = 0; m < nvec; m++) if (bcount[m] > MAXDOUBLEINT) error->all(FLERR,"Compute count/type overflow"); for (int m = 0; m < nvec; m++) vector[m] = bcount[m]; } + +/* ---------------------------------------------------------------------- + count atoms by type + atom must be in group to be counted +---------------------------------------------------------------------- */ + +int ComputeCountType::count_atoms() +{ + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int ntypes = atom->ntypes; + + for (int m = 0; m < ntypes; m++) count[m] = 0; + for (int i = 0; i < nlocal; i++) + if (mask[i] & groupbit) + count[type[i]-1]++; + + return ntypes; +} + +/* ---------------------------------------------------------------------- + count bonds by type + both atoms in bond must be in group to be counted + skip type = 0 bonds, they are counted by compute_scalar() + bond types can be negative, count them as if positive +---------------------------------------------------------------------- */ + +int ComputeCountType::count_bonds() +{ + int **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + int *num_bond = atom->num_bond; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int nbondtypes = atom->nbondtypes; + + int j,m,nbond,itype; + int flag = 0; + for (int m = 0; m < nbondtypes; m++) count[m] = 0; + + for (int i = 0; i < nlocal; i++) { + nbond = num_bond[i]; + for (m = 0; m < nbond; m++) { + itype = bond_type[i][m]; + if (itype == 0) continue; + + j = atom->map(bond_atom[i][m]); + if (j < 0) { + flag = 1; + continue; + } + + if ((mask[i] & groupbit) && (mask[j] & groupbit)) { + if (itype > 0) count[itype-1]++; + else count[-itype-1]++; + } + } + } + + int flagany; + MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); + if (flagany) error->all(FLERR,"Missing bond atom in compute count/type"); + + return nbondtypes; +} + +/* ---------------------------------------------------------------------- + count angles by type + all 3 atoms in angle must be in group to be counted + angle types can be negative, count them as if positive +---------------------------------------------------------------------- */ + +int ComputeCountType::count_angles() +{ + int **angle_atom1 = atom->angle_atom1; + int **angle_atom2 = atom->angle_atom2; + int **angle_atom3 = atom->angle_atom3; + int **angle_type = atom->angle_type; + int *num_angle = atom->num_angle; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int nangletypes = atom->nangletypes; + + int j1,j2,j3,m,nangle,itype; + int flag = 0; + for (int m = 0; m < nangletypes; m++) count[m] = 0; + + for (int i = 0; i < nlocal; i++) { + nangle = num_angle[i]; + for (m = 0; m < nangle; m++) { + itype = angle_type[i][m]; + + j1 = atom->map(angle_atom1[i][m]); + j2 = atom->map(angle_atom2[i][m]); + j3 = atom->map(angle_atom3[i][m]); + if (j1 < 0 || j2 < 0 || j3 < 0) { + flag = 1; + continue; + } + + if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && + (mask[j3] & groupbit)) { + if (itype > 0) count[itype-1]++; + else count[-itype-1]++; + } + } + } + + int flagany; + MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); + if (flagany) error->all(FLERR,"Missing angle atom in compute count/type"); + + return nangletypes; +} + +/* ---------------------------------------------------------------------- + count dihedrals by type + all 4 atoms in dihedral must be in group to be counted + dihedral types can be negative, count them as if positive +---------------------------------------------------------------------- */ + +int ComputeCountType::count_dihedrals() +{ + int **dihedral_atom1 = atom->dihedral_atom1; + int **dihedral_atom2 = atom->dihedral_atom2; + int **dihedral_atom3 = atom->dihedral_atom3; + int **dihedral_atom4 = atom->dihedral_atom4; + int **dihedral_type = atom->dihedral_type; + int *num_dihedral = atom->num_dihedral; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int ndihedraltypes = atom->ndihedraltypes; + + int j1,j2,j3,j4,m,ndihedral,itype; + int flag = 0; + for (int m = 0; m < ndihedraltypes; m++) count[m] = 0; + + for (int i = 0; i < nlocal; i++) { + ndihedral = num_dihedral[i]; + for (m = 0; m < ndihedral; m++) { + itype = dihedral_type[i][m]; + + j1 = atom->map(dihedral_atom1[i][m]); + j2 = atom->map(dihedral_atom2[i][m]); + j3 = atom->map(dihedral_atom3[i][m]); + j4 = atom->map(dihedral_atom4[i][m]); + if (j1 < 0 || j2 < 0 || j3 < 0 || j4 < 0) { + flag = 1; + continue; + } + + if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && + (mask[j3] & groupbit) && (mask[j4] & groupbit)) { + if (itype > 0) count[itype-1]++; + else count[-itype-1]++; + } + } + } + + int flagany; + MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); + if (flagany) error->all(FLERR,"Missing dihedral atom in compute count/type"); + + return ndihedraltypes; +} + +/* ---------------------------------------------------------------------- + count impropers by type + all 4 atoms in improper must be in group to be counted + improper types can be negative, count them as if positive +---------------------------------------------------------------------- */ + +int ComputeCountType::count_impropers() +{ + int **improper_atom1 = atom->improper_atom1; + int **improper_atom2 = atom->improper_atom2; + int **improper_atom3 = atom->improper_atom3; + int **improper_atom4 = atom->improper_atom4; + int **improper_type = atom->improper_type; + int *num_improper = atom->num_improper; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int nimpropertypes = atom->nimpropertypes; + + int j1,j2,j3,j4,m,nimproper,itype; + int flag = 0; + for (int m = 0; m < nimpropertypes; m++) count[m] = 0; + + for (int i = 0; i < nlocal; i++) { + nimproper = num_improper[i]; + for (m = 0; m < nimproper; m++) { + itype = improper_type[i][m]; + + j1 = atom->map(improper_atom1[i][m]); + j2 = atom->map(improper_atom2[i][m]); + j3 = atom->map(improper_atom3[i][m]); + j4 = atom->map(improper_atom4[i][m]); + if (j1 < 0 || j2 < 0 || j3 < 0 || j4 < 0) { + flag = 1; + continue; + } + + if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && + (mask[j3] & groupbit) && (mask[j4] & groupbit)) { + if (itype > 0) count[itype-1]++; + else count[-itype-1]++; + } + } + } + + int flagany; + MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); + if (flagany) error->all(FLERR,"Missing improper atom in compute count/type"); + + return nimpropertypes; +} diff --git a/src/compute_count_type.h b/src/compute_count_type.h index 0ed7a22467..68a51cb42a 100644 --- a/src/compute_count_type.h +++ b/src/compute_count_type.h @@ -38,6 +38,12 @@ class ComputeCountType : public Compute { int *count; bigint *bcount_me; bigint *bcount; + + int count_atoms(); + int count_bonds(); + int count_angles(); + int count_dihedrals(); + int count_impropers(); }; } // namespace LAMMPS_NS From 8a9091595df80f2834cb7452e8d1cc0a8cd1a7b0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 15:56:45 -0400 Subject: [PATCH 121/448] Revert "use more obvious representation of 2^53" This reverts commit ff29ef7d3160c9597b9fb637619982afcf8e0adc as it conflicts with how MSVC interprets 1L (it would require 1LL which creates issues with other compilers). --- src/lmptype.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lmptype.h b/src/lmptype.h index 769f730d6a..891d5bdf89 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -95,8 +95,8 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT_MAX #define MAXBIGINT INT64_MAX -#define MAXDOUBLEINT (1L<<53) - +#define MAXDOUBLEINT 9007199254740992 // 2^53 + #define MPI_LMP_TAGINT MPI_INT #define MPI_LMP_IMAGEINT MPI_INT #define MPI_LMP_BIGINT MPI_LL @@ -133,7 +133,7 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT64_MAX #define MAXBIGINT INT64_MAX -#define MAXDOUBLEINT (1L<<53) +#define MAXDOUBLEINT 9007199254740992 // 2^53 #define MPI_LMP_TAGINT MPI_LL #define MPI_LMP_IMAGEINT MPI_LL From 3119434932f05b1276ece2c7d17bfbd1076f44fd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 15:59:34 -0400 Subject: [PATCH 122/448] apply clang-format --- src/compute_count_type.cpp | 147 +++++++++++++++++++++---------------- 1 file changed, 82 insertions(+), 65 deletions(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index ed0467c435..5c27dd39ca 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -22,7 +22,7 @@ using namespace LAMMPS_NS; -enum{ATOM, BOND, ANGLE, DIHEDRAL, IMPROPER}; +enum { ATOM, BOND, ANGLE, DIHEDRAL, IMPROPER }; /* ---------------------------------------------------------------------- */ @@ -33,23 +33,29 @@ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : // process args - if (strcmp(arg[3],"atom") == 0) mode = ATOM; - else if (strcmp(arg[3],"bond") == 0) mode = BOND; - else if (strcmp(arg[3],"angle") == 0) mode = ANGLE; - else if (strcmp(arg[3],"dihedral") == 0) mode = DIHEDRAL; - else if (strcmp(arg[3],"improper") == 0) mode = IMPROPER; - else error->all(FLERR, "Invalid compute count/type keyword {}",arg[3]); + if (strcmp(arg[3], "atom") == 0) + mode = ATOM; + else if (strcmp(arg[3], "bond") == 0) + mode = BOND; + else if (strcmp(arg[3], "angle") == 0) + mode = ANGLE; + else if (strcmp(arg[3], "dihedral") == 0) + mode = DIHEDRAL; + else if (strcmp(arg[3], "improper") == 0) + mode = IMPROPER; + else + error->all(FLERR, "Invalid compute count/type keyword {}", arg[3]); // error check - + if (mode == BOND && !atom->nbondtypes) - error->all(FLERR,"Compute count/type bond command with no bonds defined"); + error->all(FLERR, "Compute count/type bond command with no bonds defined"); if (mode == ANGLE && !atom->nangletypes) - error->all(FLERR,"Compute count/type bond command with no angles defined"); + error->all(FLERR, "Compute count/type bond command with no angles defined"); if (mode == DIHEDRAL && !atom->ndihedraltypes) - error->all(FLERR,"Compute count/type dihedral command with no dihedrals defined"); + error->all(FLERR, "Compute count/type dihedral command with no dihedrals defined"); if (mode == IMPROPER && !atom->nimpropertypes) - error->all(FLERR,"Compute count/type improper command with no impropers defined"); + error->all(FLERR, "Compute count/type improper command with no impropers defined"); // set vector lengths @@ -145,18 +151,23 @@ void ComputeCountType::compute_vector() int nvec; - if (mode == ATOM) nvec = count_atoms(); - else if (mode == BOND) nvec = count_bonds(); - else if (mode == ANGLE) nvec = count_angles(); - else if (mode == DIHEDRAL) nvec = count_dihedrals(); - else if (mode == IMPROPER) nvec = count_impropers(); - + if (mode == ATOM) + nvec = count_atoms(); + else if (mode == BOND) + nvec = count_bonds(); + else if (mode == ANGLE) + nvec = count_angles(); + else if (mode == DIHEDRAL) + nvec = count_dihedrals(); + else if (mode == IMPROPER) + nvec = count_impropers(); + // sum across procs as bigint, then convert to double // correct for multiple counting if newton_bond off for (int m = 0; m < nvec; m++) bcount_me[m] = count[m]; MPI_Allreduce(bcount_me, bcount, nvec, MPI_LMP_BIGINT, MPI_SUM, world); - + if (force->newton_bond == 0) { if (mode == BOND) for (int m = 0; m < nvec; m++) bcount[m] /= 2; @@ -165,7 +176,7 @@ void ComputeCountType::compute_vector() if (mode == DIHEDRAL || mode == IMPROPER) for (int m = 0; m < nvec; m++) bcount[m] /= 4; } - + for (int m = 0; m < nvec; m++) if (bcount[m] > MAXDOUBLEINT) error->all(FLERR, "Compute count/type overflow"); for (int m = 0; m < nvec; m++) vector[m] = bcount[m]; @@ -182,11 +193,10 @@ int ComputeCountType::count_atoms() int *mask = atom->mask; int nlocal = atom->nlocal; int ntypes = atom->ntypes; - + for (int m = 0; m < ntypes; m++) count[m] = 0; for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) - count[type[i]-1]++; + if (mask[i] & groupbit) count[type[i] - 1]++; return ntypes; } @@ -206,34 +216,36 @@ int ComputeCountType::count_bonds() int *mask = atom->mask; int nlocal = atom->nlocal; int nbondtypes = atom->nbondtypes; - - int j,m,nbond,itype; + + int j, m, nbond, itype; int flag = 0; for (int m = 0; m < nbondtypes; m++) count[m] = 0; - + for (int i = 0; i < nlocal; i++) { nbond = num_bond[i]; for (m = 0; m < nbond; m++) { itype = bond_type[i][m]; if (itype == 0) continue; - + j = atom->map(bond_atom[i][m]); if (j < 0) { flag = 1; continue; } - + if ((mask[i] & groupbit) && (mask[j] & groupbit)) { - if (itype > 0) count[itype-1]++; - else count[-itype-1]++; + if (itype > 0) + count[itype - 1]++; + else + count[-itype - 1]++; } } } int flagany; MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); - if (flagany) error->all(FLERR,"Missing bond atom in compute count/type"); - + if (flagany) error->all(FLERR, "Missing bond atom in compute count/type"); + return nbondtypes; } @@ -253,16 +265,16 @@ int ComputeCountType::count_angles() int *mask = atom->mask; int nlocal = atom->nlocal; int nangletypes = atom->nangletypes; - - int j1,j2,j3,m,nangle,itype; + + int j1, j2, j3, m, nangle, itype; int flag = 0; for (int m = 0; m < nangletypes; m++) count[m] = 0; - + for (int i = 0; i < nlocal; i++) { nangle = num_angle[i]; for (m = 0; m < nangle; m++) { itype = angle_type[i][m]; - + j1 = atom->map(angle_atom1[i][m]); j2 = atom->map(angle_atom2[i][m]); j3 = atom->map(angle_atom3[i][m]); @@ -270,19 +282,20 @@ int ComputeCountType::count_angles() flag = 1; continue; } - - if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && - (mask[j3] & groupbit)) { - if (itype > 0) count[itype-1]++; - else count[-itype-1]++; + + if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && (mask[j3] & groupbit)) { + if (itype > 0) + count[itype - 1]++; + else + count[-itype - 1]++; } } } int flagany; MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); - if (flagany) error->all(FLERR,"Missing angle atom in compute count/type"); - + if (flagany) error->all(FLERR, "Missing angle atom in compute count/type"); + return nangletypes; } @@ -303,16 +316,16 @@ int ComputeCountType::count_dihedrals() int *mask = atom->mask; int nlocal = atom->nlocal; int ndihedraltypes = atom->ndihedraltypes; - - int j1,j2,j3,j4,m,ndihedral,itype; + + int j1, j2, j3, j4, m, ndihedral, itype; int flag = 0; for (int m = 0; m < ndihedraltypes; m++) count[m] = 0; - + for (int i = 0; i < nlocal; i++) { ndihedral = num_dihedral[i]; for (m = 0; m < ndihedral; m++) { itype = dihedral_type[i][m]; - + j1 = atom->map(dihedral_atom1[i][m]); j2 = atom->map(dihedral_atom2[i][m]); j3 = atom->map(dihedral_atom3[i][m]); @@ -321,19 +334,21 @@ int ComputeCountType::count_dihedrals() flag = 1; continue; } - - if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && - (mask[j3] & groupbit) && (mask[j4] & groupbit)) { - if (itype > 0) count[itype-1]++; - else count[-itype-1]++; + + if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && (mask[j3] & groupbit) && + (mask[j4] & groupbit)) { + if (itype > 0) + count[itype - 1]++; + else + count[-itype - 1]++; } } } int flagany; MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); - if (flagany) error->all(FLERR,"Missing dihedral atom in compute count/type"); - + if (flagany) error->all(FLERR, "Missing dihedral atom in compute count/type"); + return ndihedraltypes; } @@ -354,16 +369,16 @@ int ComputeCountType::count_impropers() int *mask = atom->mask; int nlocal = atom->nlocal; int nimpropertypes = atom->nimpropertypes; - - int j1,j2,j3,j4,m,nimproper,itype; + + int j1, j2, j3, j4, m, nimproper, itype; int flag = 0; for (int m = 0; m < nimpropertypes; m++) count[m] = 0; - + for (int i = 0; i < nlocal; i++) { nimproper = num_improper[i]; for (m = 0; m < nimproper; m++) { itype = improper_type[i][m]; - + j1 = atom->map(improper_atom1[i][m]); j2 = atom->map(improper_atom2[i][m]); j3 = atom->map(improper_atom3[i][m]); @@ -372,18 +387,20 @@ int ComputeCountType::count_impropers() flag = 1; continue; } - - if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && - (mask[j3] & groupbit) && (mask[j4] & groupbit)) { - if (itype > 0) count[itype-1]++; - else count[-itype-1]++; + + if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && (mask[j3] & groupbit) && + (mask[j4] & groupbit)) { + if (itype > 0) + count[itype - 1]++; + else + count[-itype - 1]++; } } } int flagany; MPI_Allreduce(&flag, &flagany, 1, MPI_INT, MPI_SUM, world); - if (flagany) error->all(FLERR,"Missing improper atom in compute count/type"); - + if (flagany) error->all(FLERR, "Missing improper atom in compute count/type"); + return nimpropertypes; } From e8a77c61ac72a9933f9d10d68026b5e0e9901214 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 16:19:53 -0400 Subject: [PATCH 123/448] whitespace --- doc/src/compute_count_type.rst | 2 +- src/lmptype.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index 2e3098b5ea..bb276ea21b 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -50,7 +50,7 @@ type: * :doc:`fix shake ` * :doc:`delete_bonds ` - + These commands can create and/or break topological bonds (angles, etc). In the case of breaking, they remove the bond (angle, etc) from the system, so that they no longer exist (:doc:`bond_style quartic diff --git a/src/lmptype.h b/src/lmptype.h index 891d5bdf89..ecd6ee5761 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -96,7 +96,7 @@ typedef int64_t bigint; #define MAXTAGINT INT_MAX #define MAXBIGINT INT64_MAX #define MAXDOUBLEINT 9007199254740992 // 2^53 - + #define MPI_LMP_TAGINT MPI_INT #define MPI_LMP_IMAGEINT MPI_INT #define MPI_LMP_BIGINT MPI_LL From b6e211dd62147c4f35ee70396f2831dfc2613492 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 16:20:20 -0400 Subject: [PATCH 124/448] consistently declare variables when used only --- src/compute_count_type.cpp | 64 +++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 35 deletions(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 5c27dd39ca..47bbe36dd2 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -27,7 +27,7 @@ enum { ATOM, BOND, ANGLE, DIHEDRAL, IMPROPER }; /* ---------------------------------------------------------------------- */ ComputeCountType::ComputeCountType(LAMMPS *lmp, int narg, char **arg) : - Compute(lmp, narg, arg), count(nullptr), bcount(nullptr), bcount_me(nullptr) + Compute(lmp, narg, arg), count(nullptr), bcount_me(nullptr), bcount(nullptr) { if (narg != 4) error->all(FLERR, "Incorrect number of args for compute count/type command"); @@ -117,24 +117,22 @@ double ComputeCountType::compute_scalar() int **bond_type = atom->bond_type; int nlocal = atom->nlocal; - int m, nbond; - int count = 0; - // count broken bonds with bond_type = 0 // ignore group setting since 2 atoms in a broken bond // can be arbitrarily far apart + int count = 0; for (int i = 0; i < nlocal; i++) { - nbond = num_bond[i]; - for (m = 0; m < nbond; m++) + int nbond = num_bond[i]; + for (int m = 0; m < nbond; m++) if (bond_type[i][m] == 0) count++; } // sum across procs as bigint, then convert to double // correct for double counting if newton_bond off + bigint bcount = 0; bigint bcount_me = count; - bigint bcount; MPI_Allreduce(&bcount_me, &bcount, 1, MPI_LMP_BIGINT, MPI_SUM, world); if (force->newton_bond == 0) bcount /= 2; @@ -217,17 +215,16 @@ int ComputeCountType::count_bonds() int nlocal = atom->nlocal; int nbondtypes = atom->nbondtypes; - int j, m, nbond, itype; int flag = 0; for (int m = 0; m < nbondtypes; m++) count[m] = 0; for (int i = 0; i < nlocal; i++) { - nbond = num_bond[i]; - for (m = 0; m < nbond; m++) { - itype = bond_type[i][m]; + int nbond = num_bond[i]; + for (int m = 0; m < nbond; m++) { + int itype = bond_type[i][m]; if (itype == 0) continue; - j = atom->map(bond_atom[i][m]); + int j = atom->map(bond_atom[i][m]); if (j < 0) { flag = 1; continue; @@ -266,18 +263,17 @@ int ComputeCountType::count_angles() int nlocal = atom->nlocal; int nangletypes = atom->nangletypes; - int j1, j2, j3, m, nangle, itype; int flag = 0; for (int m = 0; m < nangletypes; m++) count[m] = 0; for (int i = 0; i < nlocal; i++) { - nangle = num_angle[i]; - for (m = 0; m < nangle; m++) { - itype = angle_type[i][m]; + int nangle = num_angle[i]; + for (int m = 0; m < nangle; m++) { + int itype = angle_type[i][m]; - j1 = atom->map(angle_atom1[i][m]); - j2 = atom->map(angle_atom2[i][m]); - j3 = atom->map(angle_atom3[i][m]); + int j1 = atom->map(angle_atom1[i][m]); + int j2 = atom->map(angle_atom2[i][m]); + int j3 = atom->map(angle_atom3[i][m]); if (j1 < 0 || j2 < 0 || j3 < 0) { flag = 1; continue; @@ -317,19 +313,18 @@ int ComputeCountType::count_dihedrals() int nlocal = atom->nlocal; int ndihedraltypes = atom->ndihedraltypes; - int j1, j2, j3, j4, m, ndihedral, itype; int flag = 0; for (int m = 0; m < ndihedraltypes; m++) count[m] = 0; for (int i = 0; i < nlocal; i++) { - ndihedral = num_dihedral[i]; - for (m = 0; m < ndihedral; m++) { - itype = dihedral_type[i][m]; + int ndihedral = num_dihedral[i]; + for (int m = 0; m < ndihedral; m++) { + int itype = dihedral_type[i][m]; - j1 = atom->map(dihedral_atom1[i][m]); - j2 = atom->map(dihedral_atom2[i][m]); - j3 = atom->map(dihedral_atom3[i][m]); - j4 = atom->map(dihedral_atom4[i][m]); + int j1 = atom->map(dihedral_atom1[i][m]); + int j2 = atom->map(dihedral_atom2[i][m]); + int j3 = atom->map(dihedral_atom3[i][m]); + int j4 = atom->map(dihedral_atom4[i][m]); if (j1 < 0 || j2 < 0 || j3 < 0 || j4 < 0) { flag = 1; continue; @@ -370,19 +365,18 @@ int ComputeCountType::count_impropers() int nlocal = atom->nlocal; int nimpropertypes = atom->nimpropertypes; - int j1, j2, j3, j4, m, nimproper, itype; int flag = 0; for (int m = 0; m < nimpropertypes; m++) count[m] = 0; for (int i = 0; i < nlocal; i++) { - nimproper = num_improper[i]; - for (m = 0; m < nimproper; m++) { - itype = improper_type[i][m]; + int nimproper = num_improper[i]; + for (int m = 0; m < nimproper; m++) { + int itype = improper_type[i][m]; - j1 = atom->map(improper_atom1[i][m]); - j2 = atom->map(improper_atom2[i][m]); - j3 = atom->map(improper_atom3[i][m]); - j4 = atom->map(improper_atom4[i][m]); + int j1 = atom->map(improper_atom1[i][m]); + int j2 = atom->map(improper_atom2[i][m]); + int j3 = atom->map(improper_atom3[i][m]); + int j4 = atom->map(improper_atom4[i][m]); if (j1 < 0 || j2 < 0 || j3 < 0 || j4 < 0) { flag = 1; continue; From 3f8cd4577cd161a7ac9a04781bcf2882336a46fb Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 16:20:29 -0400 Subject: [PATCH 125/448] update unit test --- unittest/commands/test_compute_global.cpp | 66 ++++++++++++++++++----- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 7e5b3d4483..6c365c8c2b 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -308,45 +308,83 @@ TEST_F(ComputeGlobalTest, Counts) command("variable t3 atom type==3"); command("variable t4 atom type==4"); command("variable t5 atom type==5"); - command("compute asum all reduce sum v_t1 v_t2 v_t3 v_t4 v_t5"); - command("compute acnt all count/type atom"); + command("compute tsum all reduce sum v_t1 v_t2 v_t3 v_t4 v_t5"); + command("compute tcnt all count/type atom"); command("compute bcnt all count/type bond"); - command("thermo_style custom c_asum[*] c_acnt[*]"); + command("compute acnt all count/type angle"); + command("compute dcnt all count/type dihedral"); + command("compute icnt all count/type improper"); + command("thermo_style custom c_tsum[*] c_tcnt[*] c_bcnt[*] c_acnt[*] c_dcnt[*] c_icnt[*]"); command("run 0 post no"); END_HIDE_OUTPUT(); - auto asum = get_vector("asum"); - auto acnt = get_vector("acnt"); + auto tsum = get_vector("tsum"); + auto tcnt = get_vector("tcnt"); auto bcnt = get_vector("bcnt"); auto bbrk = get_scalar("bcnt"); + auto acnt = get_vector("acnt"); + auto dcnt = get_vector("dcnt"); + auto icnt = get_vector("icnt"); + + EXPECT_DOUBLE_EQ(tsum[0], tcnt[0]); + EXPECT_DOUBLE_EQ(tsum[1], tcnt[1]); + EXPECT_DOUBLE_EQ(tsum[2], tcnt[2]); + EXPECT_DOUBLE_EQ(tsum[3], tcnt[3]); + EXPECT_DOUBLE_EQ(tsum[4], tcnt[4]); EXPECT_DOUBLE_EQ(bbrk, 0.0); - EXPECT_DOUBLE_EQ(asum[0], acnt[0]); - EXPECT_DOUBLE_EQ(asum[1], acnt[1]); - EXPECT_DOUBLE_EQ(asum[2], acnt[2]); - EXPECT_DOUBLE_EQ(asum[3], acnt[3]); - EXPECT_DOUBLE_EQ(asum[4], acnt[4]); - EXPECT_DOUBLE_EQ(bcnt[0], 3.0); EXPECT_DOUBLE_EQ(bcnt[1], 6.0); EXPECT_DOUBLE_EQ(bcnt[2], 3.0); EXPECT_DOUBLE_EQ(bcnt[3], 2.0); EXPECT_DOUBLE_EQ(bcnt[4], 10.0); + EXPECT_DOUBLE_EQ(acnt[0], 6.0); + EXPECT_DOUBLE_EQ(acnt[1], 10.0); + EXPECT_DOUBLE_EQ(acnt[2], 5.0); + EXPECT_DOUBLE_EQ(acnt[3], 9.0); + + EXPECT_DOUBLE_EQ(dcnt[0], 3.0); + EXPECT_DOUBLE_EQ(dcnt[1], 8.0); + EXPECT_DOUBLE_EQ(dcnt[2], 3.0); + EXPECT_DOUBLE_EQ(dcnt[3], 4.0); + EXPECT_DOUBLE_EQ(dcnt[4], 13.0); + + EXPECT_DOUBLE_EQ(icnt[0], 1.0); + EXPECT_DOUBLE_EQ(icnt[1], 1.0); + BEGIN_HIDE_OUTPUT(); - command("delete_bonds all bond 3"); + command("delete_bonds all bond 3 remove"); command("run 0 post no"); END_HIDE_OUTPUT(); bcnt = get_vector("bcnt"); bbrk = get_scalar("bcnt"); - EXPECT_DOUBLE_EQ(bbrk, 0.0); // should be 3 + acnt = get_vector("acnt"); + dcnt = get_vector("dcnt"); + icnt = get_vector("icnt"); + + EXPECT_DOUBLE_EQ(bbrk, 0.0); EXPECT_DOUBLE_EQ(bcnt[0], 3.0); EXPECT_DOUBLE_EQ(bcnt[1], 6.0); - EXPECT_DOUBLE_EQ(bcnt[2], 3.0); // should be 0 + EXPECT_DOUBLE_EQ(bcnt[2], 0.0); EXPECT_DOUBLE_EQ(bcnt[3], 2.0); EXPECT_DOUBLE_EQ(bcnt[4], 10.0); + + EXPECT_DOUBLE_EQ(acnt[0], 6.0); + EXPECT_DOUBLE_EQ(acnt[1], 10.0); + EXPECT_DOUBLE_EQ(acnt[2], 5.0); + EXPECT_DOUBLE_EQ(acnt[3], 9.0); + + EXPECT_DOUBLE_EQ(dcnt[0], 3.0); + EXPECT_DOUBLE_EQ(dcnt[1], 8.0); + EXPECT_DOUBLE_EQ(dcnt[2], 3.0); + EXPECT_DOUBLE_EQ(dcnt[3], 4.0); + EXPECT_DOUBLE_EQ(dcnt[4], 13.0); + + EXPECT_DOUBLE_EQ(icnt[0], 1.0); + EXPECT_DOUBLE_EQ(icnt[1], 1.0); } } // namespace LAMMPS_NS From 6d050374c34b18ea65b06fe06feed36834d61e35 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 16:24:43 -0400 Subject: [PATCH 126/448] fix compilation with -DLAMMPS_BIGBIG --- src/compute_count_type.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 47bbe36dd2..84b31e8b85 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -208,7 +208,7 @@ int ComputeCountType::count_atoms() int ComputeCountType::count_bonds() { - int **bond_atom = atom->bond_atom; + tagint **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; int *num_bond = atom->num_bond; int *mask = atom->mask; @@ -254,9 +254,9 @@ int ComputeCountType::count_bonds() int ComputeCountType::count_angles() { - int **angle_atom1 = atom->angle_atom1; - int **angle_atom2 = atom->angle_atom2; - int **angle_atom3 = atom->angle_atom3; + tagint **angle_atom1 = atom->angle_atom1; + tagint **angle_atom2 = atom->angle_atom2; + tagint **angle_atom3 = atom->angle_atom3; int **angle_type = atom->angle_type; int *num_angle = atom->num_angle; int *mask = atom->mask; @@ -303,10 +303,10 @@ int ComputeCountType::count_angles() int ComputeCountType::count_dihedrals() { - int **dihedral_atom1 = atom->dihedral_atom1; - int **dihedral_atom2 = atom->dihedral_atom2; - int **dihedral_atom3 = atom->dihedral_atom3; - int **dihedral_atom4 = atom->dihedral_atom4; + tagint **dihedral_atom1 = atom->dihedral_atom1; + tagint **dihedral_atom2 = atom->dihedral_atom2; + tagint **dihedral_atom3 = atom->dihedral_atom3; + tagint **dihedral_atom4 = atom->dihedral_atom4; int **dihedral_type = atom->dihedral_type; int *num_dihedral = atom->num_dihedral; int *mask = atom->mask; @@ -355,10 +355,10 @@ int ComputeCountType::count_dihedrals() int ComputeCountType::count_impropers() { - int **improper_atom1 = atom->improper_atom1; - int **improper_atom2 = atom->improper_atom2; - int **improper_atom3 = atom->improper_atom3; - int **improper_atom4 = atom->improper_atom4; + tagint **improper_atom1 = atom->improper_atom1; + tagint **improper_atom2 = atom->improper_atom2; + tagint **improper_atom3 = atom->improper_atom3; + tagint **improper_atom4 = atom->improper_atom4; int **improper_type = atom->improper_type; int *num_improper = atom->num_improper; int *mask = atom->mask; From 36632e33566bd6a93f08539461d5051bd71a1097 Mon Sep 17 00:00:00 2001 From: Joel Thomas Clemmer Date: Tue, 2 May 2023 14:28:17 -0600 Subject: [PATCH 127/448] Clarifying how BPM package works --- doc/src/Howto_broken_bonds.rst | 14 ++++++++------ doc/src/compute_count_type.rst | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/doc/src/Howto_broken_bonds.rst b/doc/src/Howto_broken_bonds.rst index 282d2b32a4..9fcd676c36 100644 --- a/doc/src/Howto_broken_bonds.rst +++ b/doc/src/Howto_broken_bonds.rst @@ -19,6 +19,14 @@ in the broken bond are "turned on". Angles, dihedrals, etc cannot be defined for a system when :doc:`bond_style quartic ` is used. +Similarly, bond styles in the BPM package are also incompatible with +angles, dihedrals, etc. and when a bond breaks its type is set to zero. +However, in the BPM package one can either turn off all pair interactions +between bonded particles or leave them on, overlaying pair forces on +top of bond forces. To remove pair forces, the special bond list is +dynamically updated. More details can be found on the :doc:`Howto BPM +` page. + The :doc:`fix bond/break ` and :doc:`fix bond/react ` commands allow breaking of bonds within a molecular topology with may also define angles, dihedrals, etc. These commands @@ -27,12 +35,6 @@ well as the appropriate angle, dihederal, etc interactions which include the bond. They also trigger a rebuild of the neighbor list when this occurs, to turn on the appropriate pairwise forces. -In the BPM package, one can either turn off all pair interactions -between bonded particles or leave them on, overlaying pair forces on -top of bond forces. To remove pair forces, the special bond list is -dynamically updated. More details can be found on the :doc:`Howto BPM -` page. - Note that when bonds are dumped to a file via the :doc:`dump local ` command, bonds with type 0 are not included. diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index bb276ea21b..b92fe2f2fb 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -54,8 +54,9 @@ type: These commands can create and/or break topological bonds (angles, etc). In the case of breaking, they remove the bond (angle, etc) from the system, so that they no longer exist (:doc:`bond_style quartic -` is the exception, see the discussion below). Thus -they are not included in the counts for each type: +` and :doc:`BPM bond styles ` are exceptions, +see the discussion below). Thus they are not included in the counts +for each type: * :doc:`delete_bonds remove ` * :doc:`bond_style quartic ` @@ -74,10 +75,11 @@ type is tallied. Only bonds with both atoms in the specified group are counted. For {mode} = {bond}, broken bonds with a bond type of zero are also -counted. The :doc:`bond_style quartic ` breaks a bond -by doing this. See the :doc:`Howto broken bonds ` -doc page for more details. Note that the group setting is ignored for -broken bonds; all broken bonds in the system are counted. +counted. The :doc:`bond_style quartic ` and :doc:`BPM +bond styles ` break bonds by doing this. See the :doc:` +Howto broken bonds ` doc page for more details. +Note that the group setting is ignored for broken bonds; all broken +bonds in the system are counted. If the {mode} setting is {angle} then the count of angles for each angle type is tallied. Only angles with all 3 atoms in the specified From 7b5fecfad72d6313536edc4d6c3a0a8595f37b15 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 17:24:38 -0400 Subject: [PATCH 128/448] make phana installation in LAMMPS compatible with ubuntu 18.04LTS --- cmake/Modules/Tools.cmake | 4 ++-- tools/phonon/CMakeLists.spglib | 2 +- tools/phonon/CMakeLists.txt | 2 +- tools/phonon/tricubic/CMakeLists.txt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/Modules/Tools.cmake b/cmake/Modules/Tools.cmake index ba91a557bc..285c5f2405 100644 --- a/cmake/Modules/Tools.cmake +++ b/cmake/Modules/Tools.cmake @@ -33,6 +33,8 @@ if(BUILD_TOOLS) endif() install(TARGETS msi2lmp DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES ${LAMMPS_DOC_DIR}/msi2lmp.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + + add_subdirectory(${LAMMPS_TOOLS_DIR}/phonon ${CMAKE_BINARY_DIR}/phana_build) endif() if(BUILD_LAMMPS_SHELL) @@ -63,8 +65,6 @@ if(BUILD_LAMMPS_SHELL) install(TARGETS lammps-shell EXPORT LAMMPS_Targets DESTINATION ${CMAKE_INSTALL_BINDIR}) install(DIRECTORY ${LAMMPS_TOOLS_DIR}/lammps-shell/icons DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/) install(FILES ${LAMMPS_TOOLS_DIR}/lammps-shell/lammps-shell.desktop DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications/) - - add_subdirectory(${LAMMPS_TOOLS_DIR}/phonon ${CMAKE_BINARY_DIR}/phana_build) endif() diff --git a/tools/phonon/CMakeLists.spglib b/tools/phonon/CMakeLists.spglib index 9e22445b80..566e58a2b6 100644 --- a/tools/phonon/CMakeLists.spglib +++ b/tools/phonon/CMakeLists.spglib @@ -47,7 +47,7 @@ set(SOURCES ${PROJECT_SOURCE_DIR}/src/arithmetic.c ${PROJECT_SOURCE_DIR}/src/symmetry.c) add_library(symspg STATIC ${SOURCES}) -install(TARGETS symspg LIBRARY) +install(TARGETS symspg ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib) # Header file install(FILES ${PROJECT_SOURCE_DIR}/src/spglib.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include) diff --git a/tools/phonon/CMakeLists.txt b/tools/phonon/CMakeLists.txt index 02ccee25a3..60da1cc79f 100644 --- a/tools/phonon/CMakeLists.txt +++ b/tools/phonon/CMakeLists.txt @@ -1,7 +1,7 @@ # Support Linux from Ubuntu 20.04LTS onward, CentOS 7.x (with EPEL), # macOS, MSVC 2019 (=Version 16) -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.10) # set timestamp of downloaded files to that of archive if(POLICY CMP0135) diff --git a/tools/phonon/tricubic/CMakeLists.txt b/tools/phonon/tricubic/CMakeLists.txt index d70b44c2b2..190c6ceb80 100644 --- a/tools/phonon/tricubic/CMakeLists.txt +++ b/tools/phonon/tricubic/CMakeLists.txt @@ -1,7 +1,7 @@ # Support Linux from Ubuntu 20.04LTS onward, CentOS 7.x (with EPEL), # macOS, MSVC 2019 (=Version 16) -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.10) # set up project project(tricubic VERSION 1.1 DESCRIPTION "Tricubic library" LANGUAGES CXX) From a8dcb3987a2279db88cfa3d684522ef1912b5ff1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 17:29:06 -0400 Subject: [PATCH 129/448] silence compiler warning --- tools/phonon/phonopy.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/phonon/phonopy.cpp b/tools/phonon/phonopy.cpp index a6b991efac..2cee319aa7 100644 --- a/tools/phonon/phonopy.cpp +++ b/tools/phonon/phonopy.cpp @@ -250,7 +250,8 @@ void Phonopy::phonopy() for (int jdim = 0; jdim < 3; ++jdim) fprintf(fp, "%lg ", dm->basevec[ndim++]); fprintf(fp, "\n"); } - for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "Elem-%d ", type_id[ip]); fprintf(fp, "\n"); + for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "Elem-%d ", type_id[ip]); + fprintf(fp, "\n"); for (int ip = 0; ip < ntype; ++ip) fprintf(fp, "%d ", num_type[ip]); fprintf(fp, "\nDirect\n"); for (int ip = 0; ip < ntype; ++ip){ From 3e3ed89f33428e6324bca28f90b3bc966f7c804a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 17:30:23 -0400 Subject: [PATCH 130/448] avoid out-of-range access if an angle/dihedral/improper type is set to 0 --- src/compute_count_type.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compute_count_type.cpp b/src/compute_count_type.cpp index 84b31e8b85..3cb2e6bc3a 100644 --- a/src/compute_count_type.cpp +++ b/src/compute_count_type.cpp @@ -282,7 +282,7 @@ int ComputeCountType::count_angles() if ((mask[j1] & groupbit) && (mask[j2] & groupbit) && (mask[j3] & groupbit)) { if (itype > 0) count[itype - 1]++; - else + else if (itype < 0) count[-itype - 1]++; } } @@ -334,7 +334,7 @@ int ComputeCountType::count_dihedrals() (mask[j4] & groupbit)) { if (itype > 0) count[itype - 1]++; - else + else if (itype < 0) count[-itype - 1]++; } } @@ -386,7 +386,7 @@ int ComputeCountType::count_impropers() (mask[j4] & groupbit)) { if (itype > 0) count[itype - 1]++; - else + else if (itype < 0) count[-itype - 1]++; } } From 7ab30aa4684bf2bbf843f1b930274f5d0aa500de Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 2 May 2023 17:32:57 -0400 Subject: [PATCH 131/448] add versionadded tag --- doc/src/compute_count_type.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index b92fe2f2fb..73e9d50f73 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -25,6 +25,8 @@ Examples Description """"""""""" +.. versionadded:: TBD + Define a computation that counts the current number of atoms for each atom type. Or the number of bonds (angles, dihedrals, impropers) for each bond (angle, dihedral, improper) type. From 2542a7e840acce323660751d479d3ad2e313ca1e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 3 May 2023 00:39:59 -0400 Subject: [PATCH 132/448] avoid integer overflow --- tools/phonon/dynmat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/phonon/dynmat.cpp b/tools/phonon/dynmat.cpp index aeb8fe6430..b7cd4dde63 100644 --- a/tools/phonon/dynmat.cpp +++ b/tools/phonon/dynmat.cpp @@ -137,7 +137,7 @@ DynMat::DynMat(int narg, char **arg) memory->create(DM_q, fftdim,fftdim,"DynMat:DM_q"); // read all dynamical matrix info into DM_all - if (fread(DM_all[0], sizeof(doublecomplex), npt*fftdim2, fp) != size_t(npt*fftdim2)){ + if (fread(DM_all[0], sizeof(doublecomplex), npt*size_t(fftdim2), fp) != npt*size_t(fftdim2)) { printf("\nError while reading the DM from file: %s\n", binfile); fclose(fp); exit(1); From 62858115b291d81a16aff649380edb2c812823ed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 3 May 2023 07:36:27 -0400 Subject: [PATCH 133/448] offset positions so bin indices are >= 0 even for positions < 0 --- src/EXTRA-COMPUTE/compute_stress_cartesian.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index bd7b19cced..90405640fd 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -221,6 +221,7 @@ void ComputeStressCartesian::compute_array() double *special_coul = force->special_coul; double *special_lj = force->special_lj; int newton_pair = force->newton_pair; + double *boxlo = domain->boxlo; // invoke half neighbor list (will copy or build if necessary) neighbor->build_one(list); @@ -243,9 +244,9 @@ void ComputeStressCartesian::compute_array() // calculate number density and kinetic contribution to pressure for (i = 0; i < nlocal; i++) { - bin1 = (int) (x[i][dir1] / bin_width1) % nbins1; + bin1 = (int) ((x[i][dir1] - boxlo[dir1]) / bin_width1) % nbins1; bin2 = 0; - if (dims == 2) bin2 = (int) (x[i][dir2] / bin_width2) % nbins2; + if (dims == 2) bin2 = (int) ((x[i][dir2] - boxlo[dir2]) / bin_width2) % nbins2; j = bin1 + bin2 * nbins1; tdens[j] += 1; @@ -274,8 +275,8 @@ void ComputeStressCartesian::compute_array() xtmp = x[i][0]; ytmp = x[i][1]; ztmp = x[i][2]; - xi1 = x[i][dir1]; - xi2 = x[i][dir2]; + xi1 = x[i][dir1] - boxlo[dir1]; + xi2 = x[i][dir2] - boxlo[dir2]; itag = tag[i]; itype = type[i]; jlist = firstneigh[i]; From b560559b0affbb98d1c6c974d05b81d79b157adb Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 3 May 2023 10:37:41 -0600 Subject: [PATCH 134/448] Fix issues with Kokkos minimize --- src/KOKKOS/atom_kokkos.cpp | 13 +------------ src/KOKKOS/atom_kokkos.h | 1 - src/KOKKOS/fix_minimize_kokkos.cpp | 16 ---------------- src/KOKKOS/fix_minimize_kokkos.h | 1 - src/atom.h | 2 -- src/fix_addforce.cpp | 10 +++++----- 6 files changed, 6 insertions(+), 37 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index f9fa31bf2a..feca086911 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -358,18 +358,7 @@ void AtomKokkos::deallocate_topology() memoryKK->destroy_kokkos(k_improper_atom4, improper_atom4); } -/* ---------------------------------------------------------------------- - perform sync and modify for each of 2 masks - called by individual styles to override default sync/modify calls - done at higher levels (Verlet,Modify,etc) -------------------------------------------------------------------------- */ - -void AtomKokkos::sync_modify(ExecutionSpace execution_space, unsigned int datamask_read, - unsigned int datamask_modify) -{ - sync(execution_space, datamask_read); - modified(execution_space, datamask_modify); -} +/* ---------------------------------------------------------------------- */ AtomVec *AtomKokkos::new_avec(const std::string &style, int trysuffix, int &sflag) { diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index d1bb41a7b8..955f5093cb 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -120,7 +120,6 @@ class AtomKokkos : public Atom { int add_custom(const char *, int, int) override; void remove_custom(int, int, int) override; virtual void deallocate_topology(); - void sync_modify(ExecutionSpace, unsigned int, unsigned int) override; private: void sort_device(); class AtomVec *new_avec(const std::string &, int, int &) override; diff --git a/src/KOKKOS/fix_minimize_kokkos.cpp b/src/KOKKOS/fix_minimize_kokkos.cpp index 90ef0f4525..e2106b3d03 100644 --- a/src/KOKKOS/fix_minimize_kokkos.cpp +++ b/src/KOKKOS/fix_minimize_kokkos.cpp @@ -28,7 +28,6 @@ FixMinimizeKokkos::FixMinimizeKokkos(LAMMPS *lmp, int narg, char **arg) : FixMinimize(lmp, narg, arg) { kokkosable = 1; - sort_device = 1; atomKK = (AtomKokkos *) atom; } @@ -219,21 +218,6 @@ void FixMinimizeKokkos::copy_arrays(int i, int j, int /*delflag*/) k_vectors.modify(); } -/* ---------------------------------------------------------------------- - sort local atom-based arrays -------------------------------------------------------------------------- */ - -void FixMinimizeKokkos::sort_kokkos(Kokkos::BinSort &Sorter) -{ - // always sort on the device - - k_vectors.sync_device(); - - Sorter.sort(LMPDeviceType(), k_vectors.d_view); - - k_vectors.modify_device(); -} - /* ---------------------------------------------------------------------- pack values in local atom-based arrays for exchange with another proc ------------------------------------------------------------------------- */ diff --git a/src/KOKKOS/fix_minimize_kokkos.h b/src/KOKKOS/fix_minimize_kokkos.h index 121711b4e4..5a7b06ba3d 100644 --- a/src/KOKKOS/fix_minimize_kokkos.h +++ b/src/KOKKOS/fix_minimize_kokkos.h @@ -39,7 +39,6 @@ class FixMinimizeKokkos : public FixMinimize, public KokkosBase { void grow_arrays(int) override; void copy_arrays(int, int, int) override; - void sort_kokkos(Kokkos::BinSort &Sorter) override; int pack_exchange(int, double *) override; int unpack_exchange(int, double *) override; diff --git a/src/atom.h b/src/atom.h index 810a2829ed..6c38254652 100644 --- a/src/atom.h +++ b/src/atom.h @@ -366,8 +366,6 @@ class Atom : protected Pointers { virtual int add_custom(const char *, int, int); virtual void remove_custom(int, int, int); - virtual void sync_modify(ExecutionSpace, unsigned int, unsigned int) {} - void *extract(const char *); int extract_datatype(const char *); diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp index 5c60fbab2d..953f503144 100644 --- a/src/fix_addforce.cpp +++ b/src/fix_addforce.cpp @@ -103,6 +103,11 @@ FixAddForce::FixAddForce(LAMMPS *lmp, int narg, char **arg) : maxatom = 1; memory->create(sforce, maxatom, 4, "addforce:sforce"); + + // KOKKOS package + + datamask_read = X_MASK | F_MASK | IMAGE_MASK; + datamask_modify = F_MASK; } /* ---------------------------------------------------------------------- */ @@ -121,8 +126,6 @@ FixAddForce::~FixAddForce() int FixAddForce::setmask() { - datamask_read = datamask_modify = 0; - int mask = 0; mask |= POST_FORCE; mask |= POST_FORCE_RESPA; @@ -238,9 +241,6 @@ void FixAddForce::post_force(int vflag) v_init(vflag); - if (lmp->kokkos) - atom->sync_modify(Host, (unsigned int) (F_MASK | MASK_MASK), (unsigned int) F_MASK); - // update region if necessary if (region) region->prematch(); From 5a52369ffff5badf195df1cf2850f2da9dd4570f Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 3 May 2023 10:41:43 -0600 Subject: [PATCH 135/448] Reading mask too --- src/fix_addforce.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp index 953f503144..4920d57f4a 100644 --- a/src/fix_addforce.cpp +++ b/src/fix_addforce.cpp @@ -106,7 +106,7 @@ FixAddForce::FixAddForce(LAMMPS *lmp, int narg, char **arg) : // KOKKOS package - datamask_read = X_MASK | F_MASK | IMAGE_MASK; + datamask_read = X_MASK | F_MASK | MASK_MASK | IMAGE_MASK; datamask_modify = F_MASK; } From c9cfc952aa566ebde7b2d2c435c4ba16c7b14a67 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 3 May 2023 14:06:21 -0600 Subject: [PATCH 136/448] polishing variable doc page and code --- doc/src/variable.rst | 209 ++++++++++++++++++++++++------------------- src/variable.cpp | 208 ++++++++++++++++++++++++------------------ src/variable.h | 1 + 3 files changed, 238 insertions(+), 180 deletions(-) diff --git a/doc/src/variable.rst b/doc/src/variable.rst index 8bd33218ac..e892ece1b4 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -67,7 +67,7 @@ Syntax angmom(group,dim,region), torque(group,dim,region), inertia(group,dimdim,region), omega(group,dim,region) special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label) - feature functions = is_active(category,feature), is_available(category,feature), is_defined(category,id) + feature functions = is_available(category,feature), is_active(category,feature), is_defined(category,id) atom value = id[i], mass[i], type[i], mol[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i], q[i] atom vector = id, mass, type, mol, radius, q, x, y, z, vx, vy, vz, fx, fy, fz compute references = c_ID, c_ID[i], c_ID[i][j], C_ID, C_ID[i] @@ -495,36 +495,39 @@ is a valid (though strange) variable formula: Specifically, a formula can contain numbers, constants, thermo keywords, math operators, math functions, group functions, region -functions, atom values, atom vectors, compute references, fix -references, and references to other variables. +functions, special functions, feature functions, atom values, atom +vectors, compute references, fix references, and references to other +variables. -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Number | 0.2, 100, 1.0e20, -15.4, etc | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Constant | PI, version, on, off, true, false, yes, no | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Thermo keywords | vol, pe, ebond, etc | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Math operators | (), -x, x+y, x-y, x\*y, x/y, x\^y, x%y, x == y, x != y, x < y, x <= y, x > y, x >= y, x && y, x \|\| y, x \|\^ y, !x | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Math functions | sqrt(x), exp(x), ln(x), log(x), abs(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x), ramp(x,y), stagger(x,y), logfreq(x,y,z), logfreq2(x,y,z), logfreq3(x,y,z), stride(x,y,z), stride2(x,y,z,a,b,c), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z) | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Group functions | count(ID), mass(ID), charge(ID), xcm(ID,dim), vcm(ID,dim), fcm(ID,dim), bound(ID,dir), gyration(ID), ke(ID), angmom(ID,dim), torque(ID,dim), inertia(ID,dimdim), omega(ID,dim) | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Region functions | count(ID,IDR), mass(ID,IDR), charge(ID,IDR), xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), angmom(ID,dim,IDR), torque(ID,dim,IDR), inertia(ID,dimdim,IDR), omega(ID,dim,IDR) | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Special functions | sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), label2type(kind,label) | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Atom values | id[i], mass[i], type[i], mol[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i], q[i] | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Atom vectors | id, mass, type, mol, x, y, z, vx, vy, vz, fx, fy, fz, q | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Compute references | c_ID, c_ID[i], c_ID[i][j], C_ID, C_ID[i] | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Fix references | f_ID, f_ID[i], f_ID[i][j], F_ID, F_ID[i] | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Other variables | v_name, v_name[i] | -+--------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Number | 0.2, 100, 1.0e20, -15.4, etc | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Constant | PI, version, on, off, true, false, yes, no | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Thermo keywords | vol, pe, ebond, etc | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Math operators | (), -x, x+y, x-y, x\*y, x/y, x\^y, x%y, x == y, x != y, x < y, x <= y, x > y, x >= y, x && y, x \|\| y, x \|\^ y, !x | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Math functions | sqrt(x), exp(x), ln(x), log(x), abs(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), random(x,y,z), normal(x,y,z), ceil(x), floor(x), round(x), ramp(x,y), stagger(x,y), logfreq(x,y,z), logfreq2(x,y,z), logfreq3(x,y,z), stride(x,y,z), stride2(x,y,z,a,b,c), vdisplace(x,y), swiggle(x,y,z), cwiggle(x,y,z) | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Group functions | count(ID), mass(ID), charge(ID), xcm(ID,dim), vcm(ID,dim), fcm(ID,dim), bound(ID,dir), gyration(ID), ke(ID), angmom(ID,dim), torque(ID,dim), inertia(ID,dimdim), omega(ID,dim) | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Region functions | count(ID,IDR), mass(ID,IDR), charge(ID,IDR), xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), angmom(ID,dim,IDR), torque(ID,dim,IDR), inertia(ID,dimdim,IDR), omega(ID,dim,IDR) | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Special functions | sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label) | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Feature functions | is_available(category,feature), is_active(category,feature), is_defined(category,id) | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Atom values | id[i], mass[i], type[i], mol[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i], q[i] | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Atom vectors | id, mass, type, mol, x, y, z, vx, vy, vz, fx, fy, fz, q | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Compute references | c_ID, c_ID[i], c_ID[i][j], C_ID, C_ID[i] | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Fix references | f_ID, f_ID[i], f_ID[i][j], F_ID, F_ID[i] | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +| Other variables | v_name, v_name[i] | ++--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ Most of the formula elements produce a scalar value. Some produce a global or per-atom vector of values. Global vectors can be produced @@ -970,53 +973,87 @@ types, bond types and so on. For the full list of available keywords *name* and their meaning, see the documentation for extract_setting() via the link in this paragraph. -The label2type() function converts type labels into numeric types, using label -maps created by the :doc:`labelmap ` or :doc:`read_data ` -commands. The first argument is the label map kind (atom, bond, angle, -dihedral, or improper) and the second argument is the label. The function -returns the corresponding numeric type. +The label2type(kind,label) function converts type labels into numeric +types, using label maps created by the :doc:`labelmap ` or +:doc:`read_data ` commands. The first argument is the +label map kind (atom, bond, angle, dihedral, or improper) and the +second argument is the label. The function returns the corresponding +numeric type. ---------- Feature Functions ----------------- -Feature functions allow to probe the running LAMMPS executable for -whether specific features are either active, defined, or available. The -functions take two arguments, a *category* and a corresponding -*argument*\ . The arguments are strings and thus cannot be formulas +Feature functions allow probing of the running LAMMPS executable for +whether specific features are available, active, or defined. All 3 of +the functions take two arguments, a *category* and a category-specific +second argument. Both are strings and thus cannot be formulas themselves; only $-style immediate variable expansion is possible. -Return value is either 1.0 or 0.0 depending on whether the function -evaluates to true or false, respectively. +The return value of the functions is either 1.0 or 0.0 depending on +whether the function evaluates to true or false, respectively. -The *is_active(category,feature)* function allows to query for active -settings which are grouped by categories. Currently supported categories -and arguments are: +The *is_available(category,name)* function queries whether a specific +feature is available in the LAMMPS executable that is being run, i.e +whether it was included or enabled at compile time. -* *package*\ : argument = *gpu* or *intel* or *kokkos* or *omp* -* *newton*\ : argument = *pair* or *bond* or *any* -* *pair*\ : argument = *single* or *respa* or *manybody* or *tail* or *shift* -* *comm_style*\ : argument = *brick* or *tiled* -* *min_style*\ : argument = any of the compiled in minimizer styles -* *run_style*\ : argument = any of the compiled in run styles -* *atom_style*\ : argument = any of the compiled in atom style) -* *pair_style*\ : argument = any of the compiled in pair styles -* *bond_style*\ : argument = any of the compiled in bond styles -* *angle_style*\ : argument = any of the compiled in angle styles -* *dihedral_style*\ : argument = any of the compiled in dihedral styles -* *improper_style*\ : argument = any of the compiled in improper styles -* *kspace_style*\ : argument = any of the compiled in kspace styles +This supports the following categories: *command*, *compute*, *fix*, +*pair_style* and *feature*\ . For all the categories except *feature* +the *name* is a style name, e.g. *nve* for the *fix* category. Note +that many LAMMPS input script commands such as *create_atoms* are +actually instances of a command style which LAMMPS defines, as opposed +to built-in commands. For all of these styles except *command*, +appending of active suffixes is also tried before reporting failure. -Most of the settings are self-explanatory, the *single* argument in the -*pair* category allows to check whether a pair style supports a -Pair::single() function as needed by compute group/group and others -features or LAMMPS, *respa* allows to check whether the inner/middle/outer -mode of r-RESPA is supported. In the various style categories, -the checking is also done using suffix flags, if available and enabled. +The *feature* category checks the availability of the following +compile-time enabled features: GZIP support, PNG support, JPEG +support, FFMPEG support, and C++ exceptions for error +handling. Corresponding names are *gzip*, *png*, *jpeg*, *ffmpeg* and +*exceptions*\ . -Example 1: disable use of suffix for pppm when using GPU package -(i.e. run it on the CPU concurrently to running the pair style on the -GPU), but do use the suffix otherwise (e.g. with OPENMP). +Example: Only dump in a given format if the compiled binary supports it. + +.. code-block:: LAMMPS + + if "$(is_available(feature,png))" then "print 'PNG supported'" else "print 'PNG not supported'" + if "$(is_available(feature,ffmpeg)" then "dump 3 all movie 25 movie.mp4 type type zoom 1.6 adiam 1.0" + +The *is_active(category,feature)* function queries whether a specific +feature is currently active within LAMMPS. The features are grouped +by categories. Supported categories and features are: + +* *package*\ : features = *gpu* or *intel* or *kokkos* or *omp* +* *newton*\ : features = *pair* or *bond* or *any* +* *pair*\ : features = *single* or *respa* or *manybody* or *tail* or *shift* +* *comm_style*\ : features = *brick* or *tiled* +* *min_style*\ : features = a minimizer style name +* *run_style*\ : features = a run style name +* *atom_style*\ : features = an atom style name +* *pair_style*\ : features = a pair style name +* *bond_style*\ : features = a bond style name +* *angle_style*\ : features = an angle style name +* *dihedral_style*\ : features = a dihedral style name +* *improper_style*\ : features = an improper style name +* *kspace_style*\ : features = a kspace style name + +Most of the settings are self-explanatory. For the *package* +category, a package may have been included in the LAMMPS build, but +not have enabled by any input script command, and hence be inactive. +The *single* feature in the *pair* category checks whether the +currently defined pair style supports a Pair::single() function as +needed by compute group/group and others features or LAMMPS. +Similarly, the *respa* feature checks whether the inner/middle/outer +mode of r-RESPA is supported by the current pair style. + +For the categories with *style* in their name, only a single instance +of the style is ever active at any time in a LAMMPS simulation. Thus +the check is whether the currently active style matches the specified +name. This check is also done using suffix flags, if available and +enabled. + +Example 1: Disable use of suffix for PPPM when using GPU package +(i.e. run it on the CPU concurrently while running the pair style on +the GPU), but do use the suffix otherwise (e.g. with OPENMP). .. code-block:: LAMMPS @@ -1024,39 +1061,23 @@ GPU), but do use the suffix otherwise (e.g. with OPENMP). if $(is_active(package,gpu)) then "suffix off" kspace_style pppm -Example 2: use r-RESPA with inner/outer cutoff, if supported by pair -style, otherwise fall back to using pair and reducing the outer time -step +Example 2: Use r-RESPA with inner/outer cutoff, if supported by the +current pair style, otherwise fall back to using r-RESPA with simply +the pair keyword and reducing the outer time step. .. code-block:: LAMMPS timestep $(2.0*(1.0+2.0*is_active(pair,respa))) - if $(is_active(pair,respa)) then "run_style respa 4 3 2 2 improper 1 inner 2 5.5 7.0 outer 3 kspace 4" else "run_style respa 3 3 2 improper 1 pair 2 kspace 3" + if $(is_active(pair,respa)) then "run_style respa 4 3 2 2 improper 1 inner 2 5.5 7.0 outer 3 kspace 4" else "run_style respa 3 3 2 improper 1 pair 2 kspace 3" -The *is_available(category,name)* function allows to query whether -a specific optional feature is available, i.e. compiled in. -This currently works for the following categories: *command*, -*compute*, *fix*, *pair_style* and *feature*\ . For all categories -except *command* and *feature* also appending active suffixes is -tried before reporting failure. - -The *feature* category is used to check the availability of compiled in -features such as GZIP support, PNG support, JPEG support, FFMPEG support, -and C++ exceptions for error handling. Corresponding values for name are -*gzip*, *png*, *jpeg*, *ffmpeg* and *exceptions*\ . - -This enables writing input scripts which only dump using a given format if -the compiled binary supports it. - -.. code-block:: LAMMPS - - if "$(is_available(feature,png))" then "print 'PNG supported'" else "print 'PNG not supported'" - - if "$(is_available(feature,ffmpeg)" then "dump 3 all movie 25 movie.mp4 type type zoom 1.6 adiam 1.0" - -The *is_defined(categoy,id)* function allows to query categories like -*compute*, *dump*, *fix*, *group*, *region*, and *variable* whether an -entry with the provided name or id is defined. +The *is_defined(category,id)* function checks whether an instance of a +style or variable with a specific ID or name is currently defined +within LAMMPS. The suppported categories are *compute*, *dump*, +*fix*, *group*, *region*, and *variable*. Each of these styles (as +well as the variable command) can be speficied multiple times within +LAMMPS, each with a unique *id*. This function checks whether the +specified *id* exists. For category *variable", the *id* is the +variable name. ---------- diff --git a/src/variable.cpp b/src/variable.cpp index b9b3661af8..e21a3d1056 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -2031,7 +2031,8 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) if (math_function(word,contents,tree,treestack,ntreestack,argstack,nargstack,ivar)); else if (group_function(word,contents,tree,treestack,ntreestack,argstack,nargstack,ivar)); else if (special_function(word,contents,tree,treestack,ntreestack,argstack,nargstack,ivar)); - else print_var_error(FLERR,fmt::format("Invalid math/group/special function '{}()' " + else if (feature_function(word,contents,tree,treestack,ntreestack,argstack,nargstack,ivar)); + else print_var_error(FLERR,fmt::format("Invalid math/group/special/feature function '{}()' " "in variable formula", word),ivar); delete[] contents; @@ -3979,11 +3980,12 @@ Region *Variable::region_function(char *id, int ivar) process a special function in formula push result onto tree or arg stack word = special function - contents = str between parentheses with one,two,three args + contents = str between parentheses with one or more args return 0 if not a match, 1 if successfully processed customize by adding a special function: sum(x),min(x),max(x),ave(x),trap(x),slope(x), - gmask(x),rmask(x),grmask(x,y),next(x) + gmask(x),rmask(x),grmask(x,y),next(x), + is_file(x),is_ox(x),extract_setting(x),label2type(x,y) ------------------------------------------------------------------------- */ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **treestack, @@ -3992,20 +3994,60 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t double sx,sxx; double value,sy,sxy; - // word not a match to any special function + // word is not a match to any special function if (strcmp(word,"sum") != 0 && strcmp(word,"min") && strcmp(word,"max") != 0 && strcmp(word,"ave") != 0 && strcmp(word,"trap") != 0 && strcmp(word,"slope") != 0 && strcmp(word,"gmask") != 0 && strcmp(word,"rmask") != 0 && - strcmp(word,"grmask") != 0 && strcmp(word,"next") != 0 && strcmp(word,"is_active") != 0 && - strcmp(word,"is_defined") != 0 && strcmp(word,"is_available") != 0 && strcmp(word,"is_file") != 0 && + strcmp(word,"grmask") != 0 && strcmp(word,"next") != 0 && strcmp(word,"is_file") != 0 && strcmp(word,"is_os") != 0 && strcmp(word,"extract_setting") != 0 && strcmp(word,"label2type") != 0) return 0; + // process label2type() separately b/c its label arg can have commas in it + + if (strcmp(word,"label2type") == 0) { + if (!atom->labelmapflag) + print_var_error(FLERR,"Cannot use label2type() function without a labelmap",ivar); + + std::string typestr(args[0]); + std::string kind(args[1]); + + int value = -1; + if (kind == "atom") { + value = atom->lmap->find(typestr,Atom::ATOM); + } else if (kind == "bond") { + value = atom->lmap->find(typestr,Atom::BOND); + } else if (kind == "angle") { + value = atom->lmap->find(typestr,Atom::ANGLE); + } else if (kind == "dihedral") { + value = atom->lmap->find(typestr,Atom::DIHEDRAL); + } else if (kind == "improper") { + value = atom->lmap->find(typestr,Atom::IMPROPER); + } else { + print_var_error(FLERR, fmt::format("Invalid kind {} in label2type in variable",kind), ivar); + } + + if (value == -1) + print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type in variable", + kind, typestr), ivar); + + // save value in tree or on argstack + + if (tree) { + Tree *newtree = new Tree(); + newtree->type = VALUE; + newtree->value = value; + newtree->first = newtree->second = nullptr; + newtree->nextra = 0; + treestack[ntreestack++] = newtree; + } else argstack[nargstack++] = value; + + return 1; + } + + // process other special functions // parse contents for comma-separated args // narg = number of args, args = strings between commas - std::string contents_copy(contents); // for label2type - char *args[MAXFUNCARG]; int narg = parse_args(contents,args); @@ -4333,54 +4375,6 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t } else print_var_error(FLERR,"Invalid variable style in special function next",ivar); - } else if (strcmp(word,"is_active") == 0) { - if (narg != 2) - print_var_error(FLERR,"Invalid is_active() function in variable formula",ivar); - - Info info(lmp); - value = (info.is_active(args[0],args[1])) ? 1.0 : 0.0; - - // save value in tree or on argstack - - if (tree) { - auto newtree = new Tree(); - newtree->type = VALUE; - newtree->value = value; - treestack[ntreestack++] = newtree; - } else argstack[nargstack++] = value; - - } else if (strcmp(word,"is_available") == 0) { - if (narg != 2) - print_var_error(FLERR,"Invalid is_available() function in variable formula",ivar); - - Info info(lmp); - value = (info.is_available(args[0],args[1])) ? 1.0 : 0.0; - - // save value in tree or on argstack - - if (tree) { - auto newtree = new Tree(); - newtree->type = VALUE; - newtree->value = value; - treestack[ntreestack++] = newtree; - } else argstack[nargstack++] = value; - - } else if (strcmp(word,"is_defined") == 0) { - if (narg != 2) - print_var_error(FLERR,"Invalid is_defined() function in variable formula",ivar); - - Info info(lmp); - value = (info.is_defined(args[0],args[1])) ? 1.0 : 0.0; - - // save value in tree or on argstack - - if (tree) { - auto newtree = new Tree(); - newtree->type = VALUE; - newtree->value = value; - treestack[ntreestack++] = newtree; - } else argstack[nargstack++] = value; - } else if (strcmp(word,"is_file") == 0) { if (narg != 1) print_var_error(FLERR,"Invalid is_file() function in variable formula",ivar); @@ -4412,7 +4406,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t } else argstack[nargstack++] = value; } else if (strcmp(word,"extract_setting") == 0) { - if (narg != 1) print_var_error(FLERR,"Invalid extract_setting() function syntax in variable formula",ivar); + if (narg != 1) print_var_error(FLERR,"Invalid extract_setting() function in variable formula",ivar); value = lammps_extract_setting(lmp, args[0]); if (value < 0) { @@ -4428,45 +4422,87 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t newtree->value = value; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value; + } - } else if (strcmp(word,"label2type") == 0) { - if (!atom->labelmapflag) - print_var_error(FLERR,"Cannot use label2type() function without a labelmap",ivar); + // delete stored args - auto pos = contents_copy.find_first_of(','); - if (pos == std::string::npos) - print_var_error(FLERR, fmt::format("Invalid label2type({}) function in variable formula", - contents_copy), ivar); - std::string typestr = contents_copy.substr(pos+1); - std::string kind = contents_copy.substr(0, pos); + for (int i = 0; i < narg; i++) delete[] args[i]; - int value = -1; - if (kind == "atom") { - value = atom->lmap->find(typestr,Atom::ATOM); - } else if (kind == "bond") { - value = atom->lmap->find(typestr,Atom::BOND); - } else if (kind == "angle") { - value = atom->lmap->find(typestr,Atom::ANGLE); - } else if (kind == "dihedral") { - value = atom->lmap->find(typestr,Atom::DIHEDRAL); - } else if (kind == "improper") { - value = atom->lmap->find(typestr,Atom::IMPROPER); - } else { - print_var_error(FLERR, fmt::format("Invalid type kind {} in variable formula",kind), ivar); - } + return 1; +} - if (value == -1) - print_var_error(FLERR, fmt::format("Invalid {} type label {} in variable formula", - kind, typestr), ivar); +/* ---------------------------------------------------------------------- + process a feature function in formula + push result onto tree or arg stack + word = special function + contents = str between parentheses with one or more args + return 0 if not a match, 1 if successfully processed + customize by adding a feature function: + is_available(x,y),is_active(x,y),is_defined(x,y), +------------------------------------------------------------------------- */ + +int Variable::feature_function(char *word, char *contents, Tree **tree, Tree **treestack, + int &ntreestack, double *argstack, int &nargstack, int ivar) +{ + double value; + + // word is not a match to any feature function + + if (strcmp(word,"is_available") && strcmp(word,"is_active") && strcmp(word,"is_defined") != 0) + return 0; + + // process feature functions + // parse contents for comma-separated args + // narg = number of args, args = strings between commas + + char *args[MAXFUNCARG]; + int narg = parse_args(contents,args); + + if (strcmp(word,"is_available") == 0) { + if (narg != 2) + print_var_error(FLERR,"Invalid is_available() function in variable formula",ivar); + + Info info(lmp); + value = (info.is_available(args[0],args[1])) ? 1.0 : 0.0; // save value in tree or on argstack if (tree) { - Tree *newtree = new Tree(); + auto newtree = new Tree(); + newtree->type = VALUE; + newtree->value = value; + treestack[ntreestack++] = newtree; + } else argstack[nargstack++] = value; + + } else if (strcmp(word,"is_active") == 0) { + if (narg != 2) + print_var_error(FLERR,"Invalid is_active() function in variable formula",ivar); + + Info info(lmp); + value = (info.is_active(args[0],args[1])) ? 1.0 : 0.0; + + // save value in tree or on argstack + + if (tree) { + auto newtree = new Tree(); + newtree->type = VALUE; + newtree->value = value; + treestack[ntreestack++] = newtree; + } else argstack[nargstack++] = value; + + } else if (strcmp(word,"is_defined") == 0) { + if (narg != 2) + print_var_error(FLERR,"Invalid is_defined() function in variable formula",ivar); + + Info info(lmp); + value = (info.is_defined(args[0],args[1])) ? 1.0 : 0.0; + + // save value in tree or on argstack + + if (tree) { + auto newtree = new Tree(); newtree->type = VALUE; newtree->value = value; - newtree->first = newtree->second = nullptr; - newtree->nextra = 0; treestack[ntreestack++] = newtree; } else argstack[nargstack++] = value; } diff --git a/src/variable.h b/src/variable.h index 825a207d78..3bf398c950 100644 --- a/src/variable.h +++ b/src/variable.h @@ -141,6 +141,7 @@ class Variable : protected Pointers { int group_function(char *, char *, Tree **, Tree **, int &, double *, int &, int); Region *region_function(char *, int); int special_function(char *, char *, Tree **, Tree **, int &, double *, int &, int); + int feature_function(char *, char *, Tree **, Tree **, int &, double *, int &, int); void peratom2global(int, char *, double *, int, tagint, Tree **, Tree **, int &, double *, int &); int is_atom_vector(char *); void atom_vector(char *, Tree **, Tree **, int &); From 936b24e3b09b44df4babb252ade2a16806928af2 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 3 May 2023 16:36:05 -0600 Subject: [PATCH 137/448] allow vector variable to be initialized --- src/variable.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++--- src/variable.h | 3 ++ 2 files changed, 113 insertions(+), 6 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index e21a3d1056..600f0a56ff 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -479,6 +479,8 @@ void Variable::set(int narg, char **arg) // replace pre-existing var if also style VECTOR (allows it to be reset) // num = 1, which = 1st value // data = 1 value, string to eval + // if formula string is [value,value,...] then + // immediately store it as N-length vector and set dynamic flag to 0 } else if (strcmp(arg[1],"vector") == 0) { if (narg != 3) error->all(FLERR,"Illegal variable command: expected 3 arguments but found {}", narg); @@ -488,6 +490,10 @@ void Variable::set(int narg, char **arg) error->all(FLERR,"Cannot redefine variable as a different style"); delete[] data[ivar][0]; data[ivar][0] = utils::strdup(arg[2]); + if (data[ivar][0][0] == '[') { + parse_vector(ivar,data[ivar][0]); + vecs[ivar].dynamic = 0; + } else vecs[ivar].dynamic = 1; replaceflag = 1; } else { if (nvar == maxvar) grow(); @@ -497,6 +503,10 @@ void Variable::set(int narg, char **arg) pad[nvar] = 0; data[nvar] = new char*[num[nvar]]; data[nvar][0] = utils::strdup(arg[2]); + if (data[nvar][0][0] == '[') { + parse_vector(nvar,data[nvar][0]); + vecs[nvar].dynamic = 0; + } else vecs[nvar].dynamic = 1; } // PYTHON @@ -1137,18 +1147,30 @@ void Variable::compute_atom(int ivar, int igroup, double *result, int stride, in compute result of vector-style variable evaluation return length of vector and result pointer to vector values if length == 0 or -1 (mismatch), generate an error - if variable already computed on this timestep, just return - else evaluate the formula and its length, store results in VecVar entry + if necessary, evaluate the formula and its length, + store results in VecVar entry and return them ------------------------------------------------------------------------- */ int Variable::compute_vector(int ivar, double **result) { Tree *tree = nullptr; + + // if vector is not dynamic, just return stored values + + if (!vecs[ivar].dynamic) { + *result = vecs[ivar].values; + return vecs[ivar].n; + } + + // if vector already computed on this timestep, just return stored values + if (vecs[ivar].currentstep == update->ntimestep) { *result = vecs[ivar].values; return vecs[ivar].n; } + // evaluate vector afresh + if (eval_in_progress[ivar]) print_var_error(FLERR,"has a circular dependency",ivar); @@ -1246,7 +1268,8 @@ void Variable::grow() vecs = (VecVar *) memory->srealloc(vecs,maxvar*sizeof(VecVar),"var:vecvar"); for (int i = old; i < maxvar; i++) { - vecs[i].nmax = 0; + vecs[i].n = vecs[i].nmax = 0; + vecs[i].dynamic = 1; vecs[i].currentstep = -1; vecs[i].values = nullptr; } @@ -4008,8 +4031,13 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t if (!atom->labelmapflag) print_var_error(FLERR,"Cannot use label2type() function without a labelmap",ivar); - std::string typestr(args[0]); - std::string kind(args[1]); + std::string contents_copy(contents); + auto pos = contents_copy.find_first_of(','); + if (pos == std::string::npos) + print_var_error(FLERR, fmt::format("Invalid label2type({}) function in variable formula", + contents_copy), ivar); + std::string typestr = contents_copy.substr(pos+1); + std::string kind = contents_copy.substr(0, pos); int value = -1; if (kind == "atom") { @@ -4692,6 +4720,52 @@ void Variable::atom_vector(char *word, Tree **tree, Tree **treestack, int &ntree else if (strcmp(word,"fz") == 0) newtree->array = &atom->f[0][2]; } +/* ---------------------------------------------------------------------- + parse vector string with format [value,value,...] for vector-style variable + store numeric values in vecs[ivar] +------------------------------------------------------------------------- */ + +void Variable::parse_vector(int ivar, char *str) +{ + // unlimited allows for any vector length + + char **args; + int nvec = parse_args_unlimited(str,args); + + if (args[nvec-1][strlen(args[nvec-1])-1] != ']') + error->all(FLERR,"Vector variable formula lacks closing brace: {}",str); + + vecs[ivar].n = nvec; + vecs[ivar].nmax = nvec; + vecs[ivar].currentstep = -1; + memory->destroy(vecs[ivar].values); + memory->create(vecs[ivar].values,vecs[ivar].nmax,"variable:values"); + + char *onearg,*copy; + for (int i = 0; i < nvec; i++) { + onearg = utils::strdup(args[i]); + if (onearg[0] == '[') { + copy = utils::strdup(utils::trim(&onearg[1])); + delete[] onearg; + onearg = copy; + } + if (onearg[strlen(onearg)-1] == ']') { + onearg[strlen(onearg)-1] = '\0'; + copy = utils::strdup(utils::trim(onearg)); + delete[] onearg; + onearg = copy; + } + + vecs[ivar].values[i] = utils::numeric(FLERR, onearg, false, lmp); + delete[] onearg; + } + + // delete stored args + + for (int i = 0; i < nvec; i++) delete[] args[i]; + memory->sfree(args); +} + /* ---------------------------------------------------------------------- parse string for comma-separated args store copy of each arg in args array @@ -4717,6 +4791,37 @@ int Variable::parse_args(char *str, char **args) return narg; } +/* ---------------------------------------------------------------------- + parse string for comma-separated args + store copy of each arg in args array + grow args array as large as needed +------------------------------------------------------------------------- */ + +int Variable::parse_args_unlimited(char *str, char **&args) +{ + char *ptrnext; + int narg = 0; + char *ptr = str; + + int maxarg = 0; + args = nullptr; + + while (ptr) { + ptrnext = find_next_comma(ptr); + if (ptrnext) *ptrnext = '\0'; + if (narg == maxarg) { + maxarg += CHUNK; + args = (char **) memory->srealloc(args,maxarg*sizeof(char *),"variable:args"); + } + args[narg] = utils::strdup(utils::trim(ptr)); + narg++; + ptr = ptrnext; + if (ptr) ptr++; + } + + return narg; +} + /* ---------------------------------------------------------------------- find next comma in str skip commas inside one or more nested parenthesis @@ -4734,7 +4839,6 @@ char *Variable::find_next_comma(char *str) return nullptr; } - /* ---------------------------------------------------------------------- helper routine for printing variable name with error message ------------------------------------------------------------------------- */ diff --git a/src/variable.h b/src/variable.h index 3bf398c950..eccb58e526 100644 --- a/src/variable.h +++ b/src/variable.h @@ -90,6 +90,7 @@ class Variable : protected Pointers { struct VecVar { int n, nmax; + int dynamic; bigint currentstep; double *values; }; @@ -146,6 +147,8 @@ class Variable : protected Pointers { int is_atom_vector(char *); void atom_vector(char *, Tree **, Tree **, int &); int parse_args(char *, char **); + int parse_args_unlimited(char *, char **&); + void parse_vector(int, char *); char *find_next_comma(char *); void print_var_error(const std::string &, int, const std::string &, int, int global = 1); void print_tree(Tree *, int); From 42e090d945f756fb95ee854b4ce6a42d354f7e97 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 02:21:55 -0400 Subject: [PATCH 138/448] replace tabs and remove trailing whitespace --- bench/in.chain | 26 +++++++++++----------- bench/in.chain.scaled | 36 +++++++++++++++---------------- bench/in.chute | 44 ++++++++++++++++++------------------- bench/in.chute.scaled | 50 +++++++++++++++++++++---------------------- bench/in.eam | 40 +++++++++++++++++----------------- bench/in.lj | 40 +++++++++++++++++----------------- bench/in.rhodo | 28 ++++++++++++------------ bench/in.rhodo.scaled | 38 ++++++++++++++++---------------- 8 files changed, 151 insertions(+), 151 deletions(-) diff --git a/bench/in.chain b/bench/in.chain index 3993357140..d079f8d99f 100644 --- a/bench/in.chain +++ b/bench/in.chain @@ -1,25 +1,25 @@ # FENE beadspring benchmark -units lj -atom_style bond +units lj +atom_style bond special_bonds fene -read_data data.chain +read_data data.chain -neighbor 0.4 bin -neigh_modify every 1 delay 1 +neighbor 0.4 bin +neigh_modify every 1 delay 1 bond_style fene -bond_coeff 1 30.0 1.5 1.0 1.0 +bond_coeff 1 30.0 1.5 1.0 1.0 -pair_style lj/cut 1.12 -pair_modify shift yes -pair_coeff 1 1 1.0 1.0 1.12 +pair_style lj/cut 1.12 +pair_modify shift yes +pair_coeff 1 1 1.0 1.0 1.12 -fix 1 all nve -fix 2 all langevin 1.0 1.0 10.0 904297 +fix 1 all nve +fix 2 all langevin 1.0 1.0 10.0 904297 thermo 100 -timestep 0.012 +timestep 0.012 -run 100 +run 100 diff --git a/bench/in.chain.scaled b/bench/in.chain.scaled index c2648cc0e8..a56a2788ef 100644 --- a/bench/in.chain.scaled +++ b/bench/in.chain.scaled @@ -1,32 +1,32 @@ # FENE beadspring benchmark -variable x index 1 -variable y index 1 -variable z index 1 +variable x index 1 +variable y index 1 +variable z index 1 -units lj -atom_style bond -atom_modify map hash +units lj +atom_style bond +atom_modify map hash special_bonds fene -read_data data.chain +read_data data.chain -replicate $x $y $z +replicate $x $y $z -neighbor 0.4 bin -neigh_modify every 1 delay 1 +neighbor 0.4 bin +neigh_modify every 1 delay 1 bond_style fene -bond_coeff 1 30.0 1.5 1.0 1.0 +bond_coeff 1 30.0 1.5 1.0 1.0 -pair_style lj/cut 1.12 -pair_modify shift yes -pair_coeff 1 1 1.0 1.0 1.12 +pair_style lj/cut 1.12 +pair_modify shift yes +pair_coeff 1 1 1.0 1.0 1.12 -fix 1 all nve -fix 2 all langevin 1.0 1.0 10.0 904297 +fix 1 all nve +fix 2 all langevin 1.0 1.0 10.0 904297 thermo 100 -timestep 0.012 +timestep 0.012 -run 100 +run 100 diff --git a/bench/in.chute b/bench/in.chute index 9f7c28ada3..2478e98c96 100644 --- a/bench/in.chute +++ b/bench/in.chute @@ -1,33 +1,33 @@ # LAMMPS benchmark of granular flow # chute flow of 32000 atoms with frozen base at 26 degrees -units lj -atom_style sphere -boundary p p fs -newton off -comm_modify vel yes +units lj +atom_style sphere +boundary p p fs +newton off +comm_modify vel yes -read_data data.chute +read_data data.chute -pair_style gran/hooke/history 200000.0 NULL 50.0 NULL 0.5 0 -pair_coeff * * +pair_style gran/hooke/history 200000.0 NULL 50.0 NULL 0.5 0 +pair_coeff * * -neighbor 0.1 bin -neigh_modify every 1 delay 0 +neighbor 0.1 bin +neigh_modify every 1 delay 0 -timestep 0.0001 +timestep 0.0001 -group bottom type 2 -group active subtract all bottom -neigh_modify exclude group bottom bottom +group bottom type 2 +group active subtract all bottom +neigh_modify exclude group bottom bottom -fix 1 all gravity 1.0 chute 26.0 -fix 2 bottom freeze -fix 3 active nve/sphere +fix 1 all gravity 1.0 chute 26.0 +fix 2 bottom freeze +fix 3 active nve/sphere -compute 1 all erotate/sphere -thermo_style custom step atoms ke c_1 vol -thermo_modify norm no -thermo 100 +compute 1 all erotate/sphere +thermo_style custom step atoms ke c_1 vol +thermo_modify norm no +thermo 100 -run 100 +run 100 diff --git a/bench/in.chute.scaled b/bench/in.chute.scaled index 7bac8fe12d..09a6921145 100644 --- a/bench/in.chute.scaled +++ b/bench/in.chute.scaled @@ -1,38 +1,38 @@ # LAMMPS benchmark of granular flow # chute flow of 32000 atoms with frozen base at 26 degrees -variable x index 1 -variable y index 1 +variable x index 1 +variable y index 1 -units lj -atom_style sphere -boundary p p fs -newton off -comm_modify vel yes +units lj +atom_style sphere +boundary p p fs +newton off +comm_modify vel yes -read_data data.chute +read_data data.chute -replicate $x $y 1 +replicate $x $y 1 -pair_style gran/hooke/history 200000.0 NULL 50.0 NULL 0.5 0 -pair_coeff * * +pair_style gran/hooke/history 200000.0 NULL 50.0 NULL 0.5 0 +pair_coeff * * -neighbor 0.1 bin -neigh_modify every 1 delay 0 +neighbor 0.1 bin +neigh_modify every 1 delay 0 -timestep 0.0001 +timestep 0.0001 -group bottom type 2 -group active subtract all bottom -neigh_modify exclude group bottom bottom +group bottom type 2 +group active subtract all bottom +neigh_modify exclude group bottom bottom -fix 1 all gravity 1.0 chute 26.0 -fix 2 bottom freeze -fix 3 active nve/sphere +fix 1 all gravity 1.0 chute 26.0 +fix 2 bottom freeze +fix 3 active nve/sphere -compute 1 all erotate/sphere -thermo_style custom step atoms ke c_1 vol -thermo_modify norm no -thermo 100 +compute 1 all erotate/sphere +thermo_style custom step atoms ke c_1 vol +thermo_modify norm no +thermo 100 -run 100 +run 100 diff --git a/bench/in.eam b/bench/in.eam index 1dc0e1a646..b681ab9163 100644 --- a/bench/in.eam +++ b/bench/in.eam @@ -1,32 +1,32 @@ # bulk Cu lattice -variable x index 1 -variable y index 1 -variable z index 1 +variable x index 1 +variable y index 1 +variable z index 1 -variable xx equal 20*$x -variable yy equal 20*$y -variable zz equal 20*$z +variable xx equal 20*$x +variable yy equal 20*$y +variable zz equal 20*$z -units metal -atom_style atomic +units metal +atom_style atomic -lattice fcc 3.615 -region box block 0 ${xx} 0 ${yy} 0 ${zz} -create_box 1 box -create_atoms 1 box +lattice fcc 3.615 +region box block 0 ${xx} 0 ${yy} 0 ${zz} +create_box 1 box +create_atoms 1 box -pair_style eam -pair_coeff 1 1 Cu_u3.eam +pair_style eam +pair_coeff 1 1 Cu_u3.eam -velocity all create 1600.0 376847 loop geom +velocity all create 1600.0 376847 loop geom -neighbor 1.0 bin +neighbor 1.0 bin neigh_modify every 1 delay 5 check yes -fix 1 all nve +fix 1 all nve -timestep 0.005 -thermo 50 +timestep 0.005 +thermo 50 -run 100 +run 100 diff --git a/bench/in.lj b/bench/in.lj index 01e12ef8a9..7945e67fa5 100644 --- a/bench/in.lj +++ b/bench/in.lj @@ -1,30 +1,30 @@ # 3d Lennard-Jones melt -variable x index 1 -variable y index 1 -variable z index 1 +variable x index 1 +variable y index 1 +variable z index 1 -variable xx equal 20*$x -variable yy equal 20*$y -variable zz equal 20*$z +variable xx equal 20*$x +variable yy equal 20*$y +variable zz equal 20*$z -units lj -atom_style atomic +units lj +atom_style atomic -lattice fcc 0.8442 -region box block 0 ${xx} 0 ${yy} 0 ${zz} -create_box 1 box -create_atoms 1 box -mass 1 1.0 +lattice fcc 0.8442 +region box block 0 ${xx} 0 ${yy} 0 ${zz} +create_box 1 box +create_atoms 1 box +mass 1 1.0 -velocity all create 1.44 87287 loop geom +velocity all create 1.44 87287 loop geom -pair_style lj/cut 2.5 -pair_coeff 1 1 1.0 1.0 2.5 +pair_style lj/cut 2.5 +pair_coeff 1 1 1.0 1.0 2.5 -neighbor 0.3 bin -neigh_modify delay 0 every 20 check no +neighbor 0.3 bin +neigh_modify delay 0 every 20 check no -fix 1 all nve +fix 1 all nve -run 100 +run 100 diff --git a/bench/in.rhodo b/bench/in.rhodo index bd7e3df7f5..2f34b2721b 100644 --- a/bench/in.rhodo +++ b/bench/in.rhodo @@ -1,27 +1,27 @@ # Rhodopsin model -units real -neigh_modify delay 5 every 1 +units real +neigh_modify delay 5 every 1 -atom_style full -bond_style harmonic -angle_style charmm -dihedral_style charmm -improper_style harmonic -pair_style lj/charmm/coul/long 8.0 10.0 -pair_modify mix arithmetic -kspace_style pppm 1e-4 +atom_style full +bond_style harmonic +angle_style charmm +dihedral_style charmm +improper_style harmonic +pair_style lj/charmm/coul/long 8.0 10.0 +pair_modify mix arithmetic +kspace_style pppm 1e-4 read_data data.rhodo fix 1 all shake 0.0001 5 0 m 1.0 a 232 fix 2 all npt temp 300.0 300.0 100.0 & - z 0.0 0.0 1000.0 mtk no pchain 0 tchain 1 + z 0.0 0.0 1000.0 mtk no pchain 0 tchain 1 special_bonds charmm - + thermo 50 -thermo_style multi +thermo_style multi timestep 2.0 -run 100 +run 100 diff --git a/bench/in.rhodo.scaled b/bench/in.rhodo.scaled index 3debe44867..49a0864fb9 100644 --- a/bench/in.rhodo.scaled +++ b/bench/in.rhodo.scaled @@ -1,34 +1,34 @@ # Rhodopsin model -variable x index 1 -variable y index 1 -variable z index 1 +variable x index 1 +variable y index 1 +variable z index 1 -units real -neigh_modify delay 5 every 1 +units real +neigh_modify delay 5 every 1 -atom_style full -atom_modify map hash -bond_style harmonic -angle_style charmm -dihedral_style charmm -improper_style harmonic -pair_style lj/charmm/coul/long 8.0 10.0 -pair_modify mix arithmetic -kspace_style pppm 1e-4 +atom_style full +atom_modify map hash +bond_style harmonic +angle_style charmm +dihedral_style charmm +improper_style harmonic +pair_style lj/charmm/coul/long 8.0 10.0 +pair_modify mix arithmetic +kspace_style pppm 1e-4 read_data data.rhodo -replicate $x $y $z +replicate $x $y $z fix 1 all shake 0.0001 5 0 m 1.0 a 232 fix 2 all npt temp 300.0 300.0 100.0 & - z 0.0 0.0 1000.0 mtk no pchain 0 tchain 1 + z 0.0 0.0 1000.0 mtk no pchain 0 tchain 1 special_bonds charmm - + thermo 50 -thermo_style multi +thermo_style multi timestep 2.0 -run 100 +run 100 From b61e06a40f47b5022acee761376961de54676ee9 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 03:32:39 -0400 Subject: [PATCH 139/448] must initialize fp to avoid crash in destructor --- src/REPLICA/neb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp index 94b1f860bd..7a8a0039a4 100644 --- a/src/REPLICA/neb.cpp +++ b/src/REPLICA/neb.cpp @@ -44,7 +44,7 @@ enum { DEFAULT, TERSE, VERBOSE }; /* ---------------------------------------------------------------------- */ -NEB::NEB(LAMMPS *lmp) : Command(lmp), all(nullptr), rdist(nullptr) {} +NEB::NEB(LAMMPS *lmp) : Command(lmp), fp(nullptr), all(nullptr), rdist(nullptr) {} /* ---------------------------------------------------------------------- internal NEB constructor, called from TAD From de45437cc9b2e6d048c49c6d91245543520d5832 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 03:32:59 -0400 Subject: [PATCH 140/448] apply clang-format --- src/REPLICA/neb.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/REPLICA/neb.cpp b/src/REPLICA/neb.cpp index 7a8a0039a4..630427b690 100644 --- a/src/REPLICA/neb.cpp +++ b/src/REPLICA/neb.cpp @@ -52,7 +52,8 @@ NEB::NEB(LAMMPS *lmp) : Command(lmp), fp(nullptr), all(nullptr), rdist(nullptr) NEB::NEB(LAMMPS *lmp, double etol_in, double ftol_in, int n1steps_in, int n2steps_in, int nevery_in, double *buf_init, double *buf_final) : - Command(lmp), fp(nullptr), all(nullptr), rdist(nullptr) + Command(lmp), + fp(nullptr), all(nullptr), rdist(nullptr) { double delx, dely, delz; @@ -170,14 +171,14 @@ void NEB::command(int narg, char **arg) } else if (strcmp(arg[iarg], "verbosity") == 0) { if (iarg + 2 > narg) error->universe_all(FLERR, "Illegal NEB verbosity command: missing arguments"); - if (strcmp(arg[iarg+1], "verbose") == 0) + if (strcmp(arg[iarg + 1], "verbose") == 0) print_mode = VERBOSE; - else if (strcmp(arg[iarg+1], "default") == 0) + else if (strcmp(arg[iarg + 1], "default") == 0) print_mode = DEFAULT; - else if (strcmp(arg[iarg+1], "terse") == 0) + else if (strcmp(arg[iarg + 1], "terse") == 0) print_mode = TERSE; else - error->universe_all(FLERR, fmt::format("Unknown NEB verbosity option {}", arg[iarg+1])); + error->universe_all(FLERR, fmt::format("Unknown NEB verbosity option {}", arg[iarg + 1])); iarg += 2; } else error->universe_all(FLERR, fmt::format("Unknown NEB command keyword: {}", arg[iarg])); From a0d9854e1139b2b24d544a2d8a5ceba6175505d2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 03:46:18 -0400 Subject: [PATCH 141/448] more thorough tests and PBC handling for compute stress/cartesian --- doc/src/compute_stress_profile.rst | 12 ++-- .../compute_stress_cartesian.cpp | 62 ++++++++++++++++--- 2 files changed, 60 insertions(+), 14 deletions(-) diff --git a/doc/src/compute_stress_profile.rst b/doc/src/compute_stress_profile.rst index cb4628bd5d..7a4b6a38e6 100644 --- a/doc/src/compute_stress_profile.rst +++ b/doc/src/compute_stress_profile.rst @@ -136,12 +136,12 @@ More information on the similarities and differences can be found in Restrictions """""""""""" -These computes calculate the stress tensor contributions for pair -styles only (i.e., no bond, angle, dihedral, etc. contributions, and in -the presence of bonded interactions, the result will be incorrect due to -exclusions for special bonds) and requires pairwise force calculations -not available for most many-body pair styles. -Note that :math:`k`-space calculations are also excluded. +These computes calculate the stress tensor contributions for pair styles +only (i.e., no bond, angle, dihedral, etc. contributions, and in the +presence of bonded interactions, the result may be incorrect due to +exclusions for :doc:`special bonds ` excluding pairs of atoms +completely). It requires pairwise force calculations not available for most +many-body pair styles. Note that :math:`k`-space calculations are also excluded. These computes are part of the EXTRA-COMPUTE package. They are only enabled if LAMMPS was built with that package. See the :doc:`Build diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index 90405640fd..53ff70c561 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -18,8 +18,10 @@ #include "comm.h" #include "domain.h" #include "error.h" +#include "fix.h" #include "force.h" #include "memory.h" +#include "modify.h" #include "neigh_list.h" #include "neighbor.h" #include "pair.h" @@ -57,7 +59,6 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg pcxx(nullptr), pcyy(nullptr), pczz(nullptr), tdens(nullptr), tpkxx(nullptr), tpkyy(nullptr), tpkzz(nullptr), tpcxx(nullptr), tpcyy(nullptr), tpczz(nullptr), list(nullptr) { - if (lmp->citeme) lmp->citeme->add(cite_compute_stress_cartesian); // narg == 5 for one-dimensional and narg == 7 for two-dimensional @@ -75,7 +76,7 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg else if (strcmp(arg[3], "z") == 0) dir1 = 2; else - error->all(FLERR, "Illegal compute stress/cartesian command."); + error->all(FLERR, "Illegal compute stress/cartesian direction: {}", arg[3]); dir2 = 0; bin_width1 = utils::numeric(FLERR, arg[4], false, lmp); @@ -83,17 +84,20 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg nbins1 = (int) ((domain->boxhi[dir1] - domain->boxlo[dir1]) / bin_width1); nbins2 = 1; + // no triclinic boxes + if (domain->triclinic) error->all(FLERR, "Compute stress/cartesian requires an orthogonal box"); + // adjust bin width if not a perfect match double tmp_binwidth = (domain->boxhi[dir1] - domain->boxlo[dir1]) / nbins1; if ((fabs(tmp_binwidth - bin_width1) > SMALL) && (comm->me == 0)) - utils::logmesg(lmp, "Adjusting second bin width for compute {} from {:.6f} to {:.6f}\n", style, + utils::logmesg(lmp, "Adjusting first bin width for compute {} from {:.6f} to {:.6f}\n", style, bin_width1, tmp_binwidth); bin_width1 = tmp_binwidth; if (bin_width1 <= 0.0) - error->all(FLERR, "Illegal compute stress/cartesian command. Bin width must be > 0"); + error->all(FLERR, "Illegal compute stress/cartesian command. First bin width must be > 0"); else if (bin_width1 > domain->boxhi[dir1] - domain->boxlo[dir1]) - error->all(FLERR, "Illegal compute stress/cartesian command. Bin width larger than box."); + error->all(FLERR, "Illegal compute stress/cartesian command. First bin width > box."); invV = bin_width1; if (dims == 2) { @@ -104,7 +108,7 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg else if (strcmp(arg[5], "z") == 0) dir2 = 2; else - error->all(FLERR, "Illegal compute stress/cartesian command."); + error->all(FLERR, "Illegal compute stress/cartesian direction {}", arg[5]); bin_width2 = utils::numeric(FLERR, arg[6], false, lmp); nbins2 = (int) ((domain->boxhi[dir2] - domain->boxlo[dir2]) / bin_width2); @@ -119,11 +123,32 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg invV *= bin_width2; if (bin_width2 <= 0.0) - error->all(FLERR, "Illegal compute stress/cartesian command. Bin width must be > 0"); + error->all(FLERR, "Illegal compute stress/cartesian command. Second bin width must be > 0"); else if (bin_width2 > domain->boxhi[dir2] - domain->boxlo[dir2]) - error->all(FLERR, "Illegal compute stress/cartesian command. Bin width larger than box"); + error->all(FLERR, "Illegal compute stress/cartesian command. Second bin width > box"); } + // check for overflow + if (((bigint) nbins1 * nbins2) > MAXSMALLINT) + error->all(FLERR, "Too many bins in compute stress/cartesian"); + + // check for variable box dimension + int box_incompatible = 0; + for (auto ifix : modify->get_fix_list()) { + if (((dir1 == 0) && (ifix->box_change & Fix::BOX_CHANGE_X)) || + ((dir1 == 1) && (ifix->box_change & Fix::BOX_CHANGE_Y)) || + ((dir1 == 2) && (ifix->box_change & Fix::BOX_CHANGE_Z))) + box_incompatible = 1; + if (dims == 2) { + if (((dir2 == 0) && (ifix->box_change & Fix::BOX_CHANGE_X)) || + ((dir2 == 1) && (ifix->box_change & Fix::BOX_CHANGE_Y)) || + ((dir2 == 2) && (ifix->box_change & Fix::BOX_CHANGE_Z))) + box_incompatible = 1; + } + } + if (box_incompatible) + error->all(FLERR, "Must not use compute stress/cartesian on variable box dimension"); + for (int i = 0; i < 3; i++) if ((dims == 1 && i != dir1) || (dims == 2 && (i != dir1 && i != dir2))) invV *= domain->boxhi[i] - domain->boxlo[i]; @@ -248,6 +273,27 @@ void ComputeStressCartesian::compute_array() bin2 = 0; if (dims == 2) bin2 = (int) ((x[i][dir2] - boxlo[dir2]) / bin_width2) % nbins2; + // Apply periodic boundary conditions and avoid out of range access + if (domain->periodicity[dir1] == 1) { + if (bin1 < 0) + bin1 = (bin1 + nbins1) % nbins1; + else if (bin1 >= nbins1) + bin1 = (bin1 - nbins1) % nbins1; + } else if (bin1 < 0) + bin1 = 0; + else if (bin1 >= nbins1) + bin1 = nbins1 - 1; + + if (domain->periodicity[dir2] == 1) { + if (bin2 < 0) + bin2 = (bin2 + nbins2) % nbins2; + else if (bin2 >= nbins2) + bin2 = (bin2 - nbins2) % nbins2; + } else if (bin2 < 0) + bin2 = 0; + else if (bin2 >= nbins2) + bin2 = nbins2 - 1; + j = bin1 + bin2 * nbins1; tdens[j] += 1; tpkxx[j] += mass[type[i]] * v[i][0] * v[i][0]; From ccc1b200c0b09222abe1fd7d962f8da26fd7c5a3 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 4 May 2023 12:52:11 -0600 Subject: [PATCH 142/448] add output option for vector-style vars --- src/variable.cpp | 55 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 600f0a56ff..b4cf2f3ed6 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -38,6 +38,8 @@ #include "universe.h" #include "update.h" +#include "fmt/ranges.h" + #include #include #include @@ -72,10 +74,10 @@ enum{DONE,ADD,SUBTRACT,MULTIPLY,DIVIDE,CARAT,MODULO,UNARY, enum{SUM,XMIN,XMAX,AVE,TRAP,SLOPE}; - static constexpr double BIG = 1.0e20; -// INT64_MAX cannot be represented with a double. reduce to avoid overflow when casting back. +// INT64_MAX cannot be represented with a double. reduce to avoid overflow when casting back + #if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG) static constexpr double MAXBIGINT_DOUBLE = (double) (MAXBIGINT-512); #else @@ -477,8 +479,8 @@ void Variable::set(int narg, char **arg) // VECTOR // replace pre-existing var if also style VECTOR (allows it to be reset) - // num = 1, which = 1st value - // data = 1 value, string to eval + // num = 2, which = 1st value + // data = 2 values, 1st is string to eval, 2nd is formatted output string [1,2,3] // if formula string is [value,value,...] then // immediately store it as N-length vector and set dynamic flag to 0 @@ -489,24 +491,36 @@ void Variable::set(int narg, char **arg) if (style[ivar] != VECTOR) error->all(FLERR,"Cannot redefine variable as a different style"); delete[] data[ivar][0]; + delete[] data[ivar][1]; data[ivar][0] = utils::strdup(arg[2]); - if (data[ivar][0][0] == '[') { - parse_vector(ivar,data[ivar][0]); + if (data[ivar][0][0] != '[') + vecs[ivar].dynamic = 1; + else { vecs[ivar].dynamic = 0; - } else vecs[ivar].dynamic = 1; + parse_vector(ivar,data[ivar][0]); + std::vector vec(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n); + std::string str = fmt::format("[{}]", fmt::join(vec,",")); + data[ivar][1] = utils::strdup(str); + } replaceflag = 1; + } else { if (nvar == maxvar) grow(); style[nvar] = VECTOR; - num[nvar] = 1; + num[nvar] = 2; which[nvar] = 0; pad[nvar] = 0; data[nvar] = new char*[num[nvar]]; data[nvar][0] = utils::strdup(arg[2]); - if (data[nvar][0][0] == '[') { - parse_vector(nvar,data[nvar][0]); + if (data[nvar][0][0] != '[') + vecs[nvar].dynamic = 1; + else { vecs[nvar].dynamic = 0; - } else vecs[nvar].dynamic = 1; + parse_vector(nvar,data[nvar][0]); + std::vector vec(vecs[nvar].values,vecs[nvar].values + vecs[nvar].n); + std::string str = fmt::format("[{}]", fmt::join(vec,",")); + data[nvar][1] = utils::strdup(str); + } } // PYTHON @@ -945,8 +959,9 @@ int Variable::internalstyle(int ivar) if GETENV, query environment and put result in str if PYTHON, evaluate Python function, it will put result in str if INTERNAL, convert dvalue and put result in str - if ATOM or ATOMFILE or VECTOR, return nullptr - return nullptr if no variable with name, or which value is bad, + if VECTOR, return ptr to str = [value,value,...] + if ATOM or ATOMFILE, return nullptr + return nullptr if no variable with name or if which value is bad, caller must respond ------------------------------------------------------------------------- */ @@ -1019,8 +1034,10 @@ char *Variable::retrieve(const char *name) delete[] data[ivar][0]; data[ivar][0] = utils::strdup(fmt::format("{:.15g}",dvalue[ivar])); str = data[ivar][0]; - } else if (style[ivar] == ATOM || style[ivar] == ATOMFILE || - style[ivar] == VECTOR) return nullptr; + } else if (style[ivar] == VECTOR) { + str = data[ivar][1]; + } else if (style[ivar] == ATOM || style[ivar] == ATOMFILE) + return nullptr; eval_in_progress[ivar] = 0; @@ -1203,6 +1220,14 @@ int Variable::compute_vector(int ivar, double **result) free_tree(tree); eval_in_progress[ivar] = 0; + // convert numeric vector to formatted string in data[ivar][1] + // this is so that retrieve() on the vector variable will work + + delete[] data[ivar][1]; + std::vector vectmp(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n); + std::string str = fmt::format("[{}]", fmt::join(vectmp,",")); + data[ivar][1] = utils::strdup(str); + *result = vec; return nlen; } From 40f7c9047499ab3a0c432b81ffeb5e75c01fef0d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 15:56:31 -0400 Subject: [PATCH 143/448] correct underline --- doc/src/compute_count_type.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index 73e9d50f73..81fffb4f28 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -1,7 +1,7 @@ .. index:: compute count/type compute count/type command -==================== +========================== Syntax """""" From 042829c40de5e1efeb07ff169145a70bac4f3ca5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 15:57:11 -0400 Subject: [PATCH 144/448] Start document about per-atom properties and atom data access --- doc/src/Developer.rst | 1 + doc/src/Developer_atom.rst | 88 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 doc/src/Developer_atom.rst diff --git a/doc/src/Developer.rst b/doc/src/Developer.rst index 406dd26f59..b0cfcc14fc 100644 --- a/doc/src/Developer.rst +++ b/doc/src/Developer.rst @@ -13,6 +13,7 @@ of time and requests from the LAMMPS user community. Developer_org Developer_code_design Developer_parallel + Developer_atom Developer_comm_ops Developer_flow Developer_write diff --git a/doc/src/Developer_atom.rst b/doc/src/Developer_atom.rst new file mode 100644 index 0000000000..704e4a8961 --- /dev/null +++ b/doc/src/Developer_atom.rst @@ -0,0 +1,88 @@ +Accessing per-atom data +----------------------- + +This page discusses how per-atom data is managed in LAMMPS, how it can +be accessed, what communication patters apply, and some of the utility +functions that exist for a variety of purposes. + + +Owned and ghost atoms +^^^^^^^^^^^^^^^^^^^^^ + +As described on the :doc:`parallel partitioning algorithms +` page, LAMMPS uses a domain decomposition of the +simulation domain, either in a *brick* or *tiled* manner. Each MPI +process *owns* exactly one subdomain and the atoms within it. To compute +forces for tuples of atoms that are spread across sub-domain boundaries, +also a "halo" of *ghost* atoms are maintained within a the communication +cutoff distance of its subdomain. + +The total number of atoms is stored in `Atom::natoms` (within any +typical class this can be referred to at `atom->natoms`. The number of +*owned* (or "local" atoms) are stored in `Atom::nlocal`; the number of +*ghost* atoms is stored in `Atom::nghost`. The sum of `Atom::nlocal` +over all MPI processes should be `Atom::natoms`. This is by default +regularly checked by the Thermo class, and if the sum does not match, +LAMMPS stops with a "lost atoms" error. For convenience also the +property `Atom::nmax` is available, this is the maximum of +`Atom::nlocal + Atom::nghost` across all MPI processes. + +Per-atom properties are either managed by the atom style, or individual +classes. or as custom arrays by the individual classes. If only access +to *owned* atoms is needed, they are usually allocated to be of size +`Atom::nlocal`, otherwise of size `Atom::nmax`. Please note that not all +per-atom properties are available or updated on *ghost* atoms. For +example, per-atom velocities are only updated with :doc:`comm_modify vel +yes `. + + +Atom indexing +^^^^^^^^^^^^^ + +When referring to individual atoms, they may be indexed by their local +*index*, their index in their `Atom::x` array. This is densely populated +containing first all *owned* atoms (index < `Atom::nlocal`) and then all +*ghost* atoms. The order of atoms in these arrays can change due to +atoms migrating between between subdomains, atoms being added or +deleted, or atoms being sorted for better cach efficiency. Atoms are +globally uniquely identified by their *atom ID*. There may be multiple +atoms with the same atom ID present, but only one of them may be an +*owned* atom. + +To find the local *index* of an atom, when the *atom ID* is known, the +`Atom::map()` function may be used. It will return the local atom index +or -1. If the returned value is between 0 (inclusive) and `Atom::nlocal` +(exclusive) it is an *owned* or "local" atom; for larger values the atom +is present as a ghost atom; for a value of -1, the atom is not present +on the current subdomain at all. + +If multiple atoms with the same tag exist in the same subdomain, they +can be found via the `Atom::sametag` array. It points to the next atom +index with the same tag or -1 if there are no more atoms with the same +tag. The list will be exhaustive when starting with an index of an +*owned* atom, since the atom IDs are unique, so there can only be one +such atom. Example code to count atoms with same atom ID in subdomain: + +.. code-block:: c++ + + for (int i = 0; i < atom->nlocal; ++i) { + int count = 0; + while (sametag[i] >= 0) { + i = sametag[i]; + ++count; + } + printf("Atom ID: %ld is present %d times\n", atom->tag[i], count); + } + +Atom class versus AtomVec classes +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The `Atom` class contains all kinds of flags and counters about atoms in +the system and that includes pointers to **all** per-atom properties +availabel for atoms. However, only a subset of these pointers are +non-NULL and which those are depends on the atom style. For each atom +style there is a corresponding `AtomVecXXX` class derived from the +`AtomVec` base class, where the XXX indicates the atom style. This +`AtomVecXXX` class will update the counters and per-atom pointers if +atoms are added or removed to the system or migrate between subdomains. + From 8fe4394adaff1e294eab2ea125042f8678042ce3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 16:04:08 -0400 Subject: [PATCH 145/448] spelling --- doc/src/Developer_atom.rst | 4 ++-- doc/src/Howto_broken_bonds.rst | 2 +- doc/src/package.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/Developer_atom.rst b/doc/src/Developer_atom.rst index 704e4a8961..8bc187ae7f 100644 --- a/doc/src/Developer_atom.rst +++ b/doc/src/Developer_atom.rst @@ -44,7 +44,7 @@ When referring to individual atoms, they may be indexed by their local containing first all *owned* atoms (index < `Atom::nlocal`) and then all *ghost* atoms. The order of atoms in these arrays can change due to atoms migrating between between subdomains, atoms being added or -deleted, or atoms being sorted for better cach efficiency. Atoms are +deleted, or atoms being sorted for better cache efficiency. Atoms are globally uniquely identified by their *atom ID*. There may be multiple atoms with the same atom ID present, but only one of them may be an *owned* atom. @@ -79,7 +79,7 @@ Atom class versus AtomVec classes The `Atom` class contains all kinds of flags and counters about atoms in the system and that includes pointers to **all** per-atom properties -availabel for atoms. However, only a subset of these pointers are +available for atoms. However, only a subset of these pointers are non-NULL and which those are depends on the atom style. For each atom style there is a corresponding `AtomVecXXX` class derived from the `AtomVec` base class, where the XXX indicates the atom style. This diff --git a/doc/src/Howto_broken_bonds.rst b/doc/src/Howto_broken_bonds.rst index 9fcd676c36..2eb9f4bdf4 100644 --- a/doc/src/Howto_broken_bonds.rst +++ b/doc/src/Howto_broken_bonds.rst @@ -31,7 +31,7 @@ The :doc:`fix bond/break ` and :doc:`fix bond/react ` commands allow breaking of bonds within a molecular topology with may also define angles, dihedrals, etc. These commands update internal topology data structures to remove broken bonds, as -well as the appropriate angle, dihederal, etc interactions which +well as the appropriate angle, dihedral, etc interactions which include the bond. They also trigger a rebuild of the neighbor list when this occurs, to turn on the appropriate pairwise forces. diff --git a/doc/src/package.rst b/doc/src/package.rst index 14d978c3c9..6d425b63dd 100644 --- a/doc/src/package.rst +++ b/doc/src/package.rst @@ -561,7 +561,7 @@ The *sort* keyword determines whether the host or device performs atom sorting, see the :doc:`atom_modify sort ` command. The value options for the *sort* keyword are *no* or *device* similar to the *comm* keywords above. If a value of *host* is used it will be -automatically be changed to *no* since the *sort* keyword doesn't +automatically be changed to *no* since the *sort* keyword does not support *host* mode. The value of *no* will also always be used when running on the CPU, i.e. setting the value to *device* will have no effect if the simulation is running on the CPU. Not all fix styles with From 77ea3ed215fb0cdeff24e1150574d3ffcad03af1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 16:35:49 -0400 Subject: [PATCH 146/448] reduce sphinx warnings --- doc/src/Modify.rst | 14 +++++++++----- doc/src/Modify_requirements.rst | 7 ++++--- doc/src/Modify_style.rst | 9 ++++----- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/doc/src/Modify.rst b/doc/src/Modify.rst index 31e67a66ca..38cf58cbf5 100644 --- a/doc/src/Modify.rst +++ b/doc/src/Modify.rst @@ -1,18 +1,22 @@ Modifying & extending LAMMPS **************************** -LAMMPS is designed in a modular fashion and to be easy to modify or -extend with new functionality. In fact, about 95% of its source code +LAMMPS is designed in a modular fashion and easy to be modified or +extended with new functionality. In fact, about 95% of its source code is optional. The following pages give basic instructions on adding new -features to LAMMPS. +features to LAMMPS. More in-depth explanations and documentation of +individual functions and classes are given in :doc:`Developer`. If you add a new feature to LAMMPS and think it will be of general interest to other users, we encourage you to submit it for inclusion in LAMMPS. This process is explained in the following three pages: :doc:`how to prepare and submit your code `, :doc:`requirements for submissions `, and -:doc:`style guidelines `. A discussion of the various -types of styles in LAMMPS is then provided. +:doc:`style guidelines `. + +A summary description of various types of styles in LAMMPS follows. +A discussion of implementing specific styles from scratch is given +in :doc:`Developer_write`. .. toctree:: diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 8c5869c929..8c50bea94e 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -1,7 +1,6 @@ Requirements for contributions to LAMMPS =========================================================== - The following is a summary of the current requirements and recommendations for including contributed source code or documentation into the LAMMPS software distribution. @@ -41,6 +40,7 @@ include: .. _License: + Licensing requirements (strict) ------------------------------- @@ -69,8 +69,8 @@ that use code with a conflicting license can be split into two parts: Please note, that this split licensed mode may complicate including the contribution in binary packages. +.. _IntegrationTesting: -.. _IntegrationTesting Integration testing (strict) ---------------------------- @@ -95,7 +95,8 @@ testing tools or scripts or tests themselves. This is rare. If in doubt, contact the LAMMPS developer that is assigned to the pull request. -.. _Documentation +.. _Documentation: + Documentation (strict) ---------------------- diff --git a/doc/src/Modify_style.rst b/doc/src/Modify_style.rst index 2603df8242..41f7748e9f 100644 --- a/doc/src/Modify_style.rst +++ b/doc/src/Modify_style.rst @@ -1,5 +1,5 @@ LAMMPS programming style -=========================================================== +======================== The LAMMPS developers aim to employ a consistent programming style and @@ -15,7 +15,7 @@ may serve as representative examples. Include files (varied) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^ - system headers or from installed libraries are include with angular brackets (example: ``#include ``), while local include file @@ -141,8 +141,7 @@ Miscellaneous standards (varied) scripts for interpreted script languages. Whitespace (preferred) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - +^^^^^^^^^^^^^^^^^^^^^^ LAMMPS uses 2 characters per indentation level and lines should be kept within 100 characters wide. @@ -165,7 +164,7 @@ issues. Placement of braces (strongly preferred) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ On new lines for methods, when to use, etc. From 269f07a13784ce5d100fe4b3df91a1d1cd17d40d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 16:42:39 -0400 Subject: [PATCH 147/448] fix a few more sphinx issues and inconsistencies --- doc/src/Modify_contribute.rst | 26 +++++++------- doc/src/Modify_requirements.rst | 60 +++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/doc/src/Modify_contribute.rst b/doc/src/Modify_contribute.rst index 51692248a3..0d3c17c9a6 100644 --- a/doc/src/Modify_contribute.rst +++ b/doc/src/Modify_contribute.rst @@ -92,21 +92,21 @@ packages that do not have the USER- prefix. Location of files: individual files and packages --------------------------------- +------------------------------------------------ -We rarely accept new styles in the core src folder. Thus please -review the list of :doc:`available Packages ` to see -if your contribution could be added to be added to one of them. It -should fit into the general purposed of that package. If it does not -fit well, it may be added to one of the EXTRA- packages or the MISC -package. +We rarely accept new styles in the core src folder. Thus please review +the list of :doc:`available Packages ` to see if your +contribution could be added to be added to one of them. It should fit +into the general purposed of that package. If it does not fit well, it +may be added to one of the EXTRA- packages or the MISC package. -However if your project includes many related features that are not covered -by one of the existing packages or is dependent on a library (bundled or -external), it is best to create a package with its own directory (labelled -with a name like FOO). In addition to your new files, the directory should -contain a README text file containing your name and contact information and -a brief description of what your new package does. +However if your project includes many related features that are not +covered by one of the existing packages or is dependent on a library +(bundled or external), it is best to create a package with its own +directory (labeled with a name like FOO). In addition to your new +files, the directory should contain a README text file containing your +name and contact information and a brief description of what your new +package does. Changes to core LAMMPS files diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 8c50bea94e..837e2a3360 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -1,5 +1,5 @@ Requirements for contributions to LAMMPS -=========================================================== +======================================== The following is a summary of the current requirements and recommendations for including contributed source code or documentation @@ -21,11 +21,12 @@ necessity to be more discriminating with new contributions while also working at the same time to improve the existing code. The following requirements and recommendations are provided to help -maintaining or improving that status. It is indicated which requirements are strict, and which represent a preference and thus are negotiable or optional. -Please feel free to contact the LAMMPS core developers in case you need -additional explanations or clarifications or in case you need assistance -in realizing the (strict) requirements for your contributions. Requirements -include: +maintaining or improving that status. It is indicated which +requirements are strict, and which represent a preference and thus are +negotiable or optional. Please feel free to contact the LAMMPS core +developers in case you need additional explanations or clarifications or +in case you need assistance in realizing the (strict) requirements for +your contributions. Requirements include: * :ref:`Licensing requirements ` (strict) * :ref:`Integration testing ` (strict) * :ref:`Documentation ` (strict) @@ -36,7 +37,7 @@ include: * :ref:`Examples ` (preferred) * :ref:`Error or warning messages and explanations ` (preferred) * :ref:`Citation reminder ` (optional) -* :ref:`Testing ` (optional) +* :ref:`Testing ` (optional) .. _License: @@ -156,7 +157,8 @@ it for people to get started, the more likely it is that users will try out your new feature. -.. _ProgrammingStandards +.. _ProgrammingStandards: + Programming language standards (strict) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -187,9 +189,10 @@ required to use those older tools for access to advanced hardware features or not have the option to install newer compilers or libraries. -.. _BuildSystem +.. _BuildSystem: + Build system (strict) ---------------------------------- +--------------------- LAMMPS currently supports two build systems: one that is based on :doc:`traditional Makefiles ` and one that is based on @@ -214,9 +217,10 @@ cmake/Modules/Packages/. Please check out how this is handled for existing packages and ask the LAMMPS developers if you need assistance. -.. _Naming +.. _Naming: + Command or Style names, file names, and keywords (strict) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------------------------------------- All user-visible command or style names should be all lower case and should only use letters, numbers, or forward slashes. They should be @@ -227,18 +231,21 @@ established (e.g. lj for Lennard-Jones). For a compute style `LMP_COMPUTE_SOME_NAME_H` and the class name `ComputeSomeName`. -.. _ProgrammingStyle +.. _ProgrammingStyle: + Programming style requirements (varied) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +--------------------------------------- -To maintain a consistency, there are various programming style -requirements for contributions to LAMMPS. Some of these requirements -are strict while some are only preferred. An indepth discussion of -the style guidelines are provided in the :doc:`programming style -doc page `. +To maintain consistency across contributions from many people, there are +various programming style requirements for contributions to LAMMPS. +Some of these requirements are strict and must be followed while some +are only preferred and thus may be skipped. An in-depth discussion of +the style guidelines are provided in the :doc:`programming style doc +page `. -.. _Examples +.. _Examples: + Examples (preferred) -------------------- @@ -246,7 +253,7 @@ In most cases, it is preferred that example scripts (simple, small, fast to complete on 1 CPU) are included that demonstrate the use of new or extended functionality. These are typically under the examples or examples/PACKAGES directory are are further described on the -:doc:`examples page `. Guidlines for input scripts include: +:doc:`examples page `. Guidelines for input scripts include: - commands that generate output should be commented out (except when the output is the sole purpose or the feature, e.g. for a new compute) @@ -271,9 +278,10 @@ examples/PACKAGES directory are are further described on the file from other folders should be re-used through symbolic links -.. _ErrorMessages +.. _ErrorMessages: + Error or warning messages and explanations (preferred) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +------------------------------------------------------ .. versionchanged:: 4May2022 @@ -319,7 +327,8 @@ scheme will make it easier for LAMMPS users, developers, and maintainers. -.. _Citation +.. _Citation: + Citation reminder (optional) ----------------------------- @@ -348,7 +357,8 @@ documentation page you provide describing your contribution. If you are not sure what the best option would be, please contact the LAMMPS developers for advice. -.. _Testing +.. _UnitTesting: + Testing (optional) ------------------ From 93100adbe0f6a19bc70a22c3b96563fa188e54f0 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 4 May 2023 16:24:15 -0600 Subject: [PATCH 148/448] debugging and doc pages --- doc/src/fix_print.rst | 19 ++- doc/src/print.rst | 36 ++-- doc/src/variable.rst | 372 ++++++++++++++++++++++++------------------ src/variable.cpp | 47 ++++-- 4 files changed, 273 insertions(+), 201 deletions(-) diff --git a/doc/src/fix_print.rst b/doc/src/fix_print.rst index 545283b4ef..0594c8d421 100644 --- a/doc/src/fix_print.rst +++ b/doc/src/fix_print.rst @@ -44,6 +44,16 @@ one word. If it contains variables it must be enclosed in double quotes to ensure they are not evaluated when the input script line is read, but will instead be evaluated each time the string is printed. +See the :doc:`variable ` command for a description of +*equal* and *vector* style variables which are typically the most +useful ones to use with the print command. Equal- and vector-style +variables can calculate formulas involving mathematical operations, +atom properties, group properties, thermodynamic properties, global +values calculated by a :doc:`compute ` or :doc:`fix `, +or references to other :doc:`variables `. Vector-style +variables are printed in a bracketed, comma-separated format, +e.g. [1,2,3,4] or [12.5,2,4.6,10.1]. + .. note:: As discussed on the :doc:`Commands parse ` doc @@ -77,15 +87,6 @@ timesteps 10,20,30,100,200,300,1000,2000,etc: The specified group-ID is ignored by this fix. -See the :doc:`variable ` command for a description of -*equal* style variables which are the most useful ones to use with the -fix print command, since they are evaluated afresh each timestep that -the fix print line is output. Equal-style variables calculate -formulas involving mathematical operations, atom properties, group -properties, thermodynamic properties, global values calculated by a -:doc:`compute ` or :doc:`fix `, or references to other -:doc:`variables `. - If the *file* or *append* keyword is used, a filename is specified to which the output generated by this fix will be written. If *file* is used, then the filename is overwritten if it already exists. If diff --git a/doc/src/print.rst b/doc/src/print.rst index 1211fdd569..68fe8416dd 100644 --- a/doc/src/print.rst +++ b/doc/src/print.rst @@ -46,6 +46,16 @@ lines of output, the string can be enclosed in triple quotes, as in the last example above. If the text string contains variables, they will be evaluated and their current values printed. +See the :doc:`variable ` command for a description of +*equal* and *vector* style variables which are typically the most +useful ones to use with the print command. Equal- and vector-style +variables can calculate formulas involving mathematical operations, +atom properties, group properties, thermodynamic properties, global +values calculated by a :doc:`compute ` or :doc:`fix `, +or references to other :doc:`variables `. Vector-style +variables are printed in a bracketed, comma-separated format, +e.g. [1,2,3,4] or [12.5,2,4.6,10.1]. + .. note:: As discussed on the :doc:`Commands parse ` doc @@ -60,6 +70,15 @@ will be evaluated and their current values printed. This is also explained on the :doc:`Commands parse ` doc page. +If you want the print command to be executed multiple times (with +changing variable values), there are 3 options. First, consider using +the :doc:`fix print ` command, which will print a string +periodically during a simulation. Second, the print command can be +used as an argument to the *every* option of the :doc:`run ` +command. Third, the print command could appear in a section of the +input script that is looped over (see the :doc:`jump ` and +:doc:`next ` commands). + If the *file* or *append* keyword is used, a filename is specified to which the output will be written. If *file* is used, then the filename is overwritten if it already exists. If *append* is used, @@ -74,23 +93,6 @@ logfile can be turned on or off as desired. In multi-partition calculations, the *screen* option and the corresponding output only apply to the screen and logfile of the individual partition. -If you want the print command to be executed multiple times (with -changing variable values), there are 3 options. First, consider using -the :doc:`fix print ` command, which will print a string -periodically during a simulation. Second, the print command can be -used as an argument to the *every* option of the :doc:`run ` -command. Third, the print command could appear in a section of the -input script that is looped over (see the :doc:`jump ` and -:doc:`next ` commands). - -See the :doc:`variable ` command for a description of *equal* -style variables which are typically the most useful ones to use with -the print command. Equal-style variables can calculate formulas -involving mathematical operations, atom properties, group properties, -thermodynamic properties, global values calculated by a -:doc:`compute ` or :doc:`fix `, or references to other -:doc:`variables `. - Restrictions """""""""""" none diff --git a/doc/src/variable.rst b/doc/src/variable.rst index e892ece1b4..e7c7cdcb44 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -11,12 +11,19 @@ Syntax variable name style args ... * name = name of variable to define -* style = *delete* or *index* or *loop* or *world* or *universe* or *uloop* or *string* or *format* or *getenv* or *file* or *atomfile* or *python* or *timer* or *internal* or *equal* or *vector* or *atom* +* style = *delete* or *atomfile* or *file* or *format* or *getenv* or *index* or *internal* or *loop* or *python* or *string* or *timer* or *uloop* or *universe* or *world* or *equal* or *vector* or *atom* .. parsed-literal:: *delete* = no args + *atomfile* arg = filename + *file* arg = filename + *format* args = vname fstr + vname = name of equal-style variable to evaluate + fstr = C-style format string + *getenv* arg = one string *index* args = one or more strings + *internal* arg = numeric value *loop* args = N N = integer size of loop, loop from 1 to N inclusive *loop* args = N pad @@ -27,24 +34,18 @@ Syntax *loop* args = N1 N2 pad N1,N2 = loop from N1 to N2 inclusive pad = all values will be same length, e.g. 050, 051, ..., 100 - *world* args = one string for each partition of processors - *universe* args = one or more strings + *python* arg = function + *string* arg = one string + *timer* arg = no arguments *uloop* args = N N = integer size of loop *uloop* args = N pad N = integer size of loop pad = all values will be same length, e.g. 001, 002, ..., 100 - *string* arg = one string - *format* args = vname fstr - vname = name of equal-style variable to evaluate - fstr = C-style format string - *getenv* arg = one string - *file* arg = filename - *atomfile* arg = filename - *python* arg = function - *timer* arg = no arguments - *internal* arg = numeric value - *equal* or *vector* or *atom* args = one formula containing numbers, thermo keywords, math operations, group functions, atom values and vectors, compute/fix/variable references + *universe* args = one or more strings + *world* args = one string for each partition of processors + + *equal* or *vector* or *atom* args = one formula containing numbers, thermo keywords, math operations, built-in functions, atom values and vectors, compute/fix/variable references numbers = 0.0, 100, -5.4, 2.8e-4, etc constants = PI, version, on, off, true, false, yes, no thermo keywords = vol, ke, press, etc from :doc:`thermo_style ` @@ -73,6 +74,7 @@ Syntax compute references = c_ID, c_ID[i], c_ID[i][j], C_ID, C_ID[i] fix references = f_ID, f_ID[i], f_ID[i][j], F_ID, F_ID[i] variable references = v_name, v_name[i] + vector initialization = [1,3,7,10] (for *vector* variables only) Examples """""""" @@ -95,6 +97,7 @@ Examples variable x universe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 variable x uloop 15 pad variable str format x %.6g + variable myvec vector [1,3,7,10] variable x delete .. code-block:: LAMMPS @@ -252,9 +255,10 @@ commands before the variable would become exhausted. For example, ---------- -This section describes how all the various variable styles are defined -and what they store. Except for the *equal* and *vector* and *atom* -styles, which are explained in the next section. +The next sections describe in how all the various variable styles are +defined and what they store. The styles are listed alphabetcally, +except for the *equal* and *vector* and *atom* styles, which are +explained together after all the others. Many of the styles store one or more strings. Note that a single string can contain spaces (multiple words), if it is enclosed in @@ -262,111 +266,7 @@ quotes in the variable command. When the variable is substituted for in another input script command, its returned string will then be interpreted as multiple arguments in the expanded command. -For the *index* style, one or more strings are specified. Initially, -the first string is assigned to the variable. Each time a -:doc:`next ` command is used with the variable name, the next -string is assigned. All processors assign the same string to the -variable. - -Index-style variables with a single string value can also be set by -using the :doc:`command-line switch -var `. - -The *loop* style is identical to the *index* style except that the -strings are the integers from 1 to N inclusive, if only one argument N -is specified. This allows generation of a long list of runs -(e.g. 1000) without having to list N strings in the input script. -Initially, the string "1" is assigned to the variable. Each time a -:doc:`next ` command is used with the variable name, the next -string ("2", "3", etc) is assigned. All processors assign the same -string to the variable. The *loop* style can also be specified with -two arguments N1 and N2. In this case the loop runs from N1 to N2 -inclusive, and the string N1 is initially assigned to the variable. -N1 <= N2 and N2 >= 0 is required. - -For the *world* style, one or more strings are specified. There must -be one string for each processor partition or "world". LAMMPS can be -run with multiple partitions via the :doc:`-partition command-line -switch `. This variable command assigns one string to -each world. All processors in the world are assigned the same string. -The next command cannot be used with equal-style variables, since -there is only one value per world. This style of variable is useful -when you wish to run different simulations on different partitions, or -when performing a parallel tempering simulation (see the :doc:`temper -` command), to assign different temperatures to different -partitions. - -For the *universe* style, one or more strings are specified. There -must be at least as many strings as there are processor partitions or -"worlds". LAMMPS can be run with multiple partitions via the -:doc:`-partition command-line switch `. This variable -command initially assigns one string to each world. When a -:doc:`next ` command is encountered using this variable, the first -processor partition to encounter it, is assigned the next available -string. This continues until all the variable strings are consumed. -Thus, this command can be used to run 50 simulations on 8 processor -partitions. The simulations will be run one after the other on -whatever partition becomes available, until they are all finished. -Universe-style variables are incremented using the files -"tmp.lammps.variable" and "tmp.lammps.variable.lock" which you will -see in your directory during such a LAMMPS run. - -The *uloop* style is identical to the *universe* style except that the -strings are the integers from 1 to N. This allows generation of long -list of runs (e.g. 1000) without having to list N strings in the input -script. - -For the *string* style, a single string is assigned to the variable. -Two differences between this style and using the *index* style exist: -a variable with *string* style can be redefined, e.g. by another command later -in the input script, or if the script is read again in a loop. The other -difference is that *string* performs variable substitution even if the -string parameter is quoted. - -For the *format* style, an equal-style or compatible variable is -specified along with a C-style format string, e.g. "%f" or "%.10g", -which must be appropriate for formatting a double-precision -floating-point value and may not have extra characters. The default -format is "%.15g". This variable style allows an equal-style variable -to be formatted precisely when it is evaluated. - -Note that if you simply wish to print a variable value with desired -precision to the screen or logfile via the :doc:`print ` or -:doc:`fix print ` commands, you can also do this by -specifying an "immediate" variable with a trailing colon and format -string, as part of the string argument of those commands. This is -explained on the :doc:`Commands parse ` doc page. - -For the *getenv* style, a single string is assigned to the variable -which should be the name of an environment variable. When the -variable is evaluated, it returns the value of the environment -variable, or an empty string if it not defined. This style of -variable can be used to adapt the behavior of LAMMPS input scripts via -environment variable settings, or to retrieve information that has -been previously stored with the :doc:`shell putenv ` command. -Note that because environment variable settings are stored by the -operating systems, they persist even if the corresponding *getenv* -style variable is deleted, and also are set for sub-shells executed -by the :doc:`shell ` command. - -For the *file* style, a filename is provided which contains a list of -strings to assign to the variable, one per line. The strings can be -numeric values if desired. See the discussion of the next() function -below for equal-style variables, which will convert the string of a -file-style variable into a numeric value in a formula. - -When a file-style variable is defined, the file is opened and the -string on the first line is read and stored with the variable. This -means the variable can then be evaluated as many times as desired and -will return that string. There are two ways to cause the next string -from the file to be read: use the :doc:`next ` command or the -next() function in an equal- or atom-style variable, as discussed -below. - -The rules for formatting the file are as follows. A comment character -"#" can be used anywhere on a line; text starting with the comment -character is stripped. Blank lines are skipped. The first "word" of -a non-blank line, delimited by white-space, is the "string" assigned -to the variable. +---------- For the *atomfile* style, a filename is provided which contains one or more sets of values, to assign on a per-atom basis to the variable. @@ -406,6 +306,97 @@ will be assigned to that atom. IDs can be listed in any order. atoms is first set to 0.0. Thus values for atoms whose ID does not appear in the set, will remain 0.0. +---------- + +For the *file* style, a filename is provided which contains a list of +strings to assign to the variable, one per line. The strings can be +numeric values if desired. See the discussion of the next() function +below for equal-style variables, which will convert the string of a +file-style variable into a numeric value in a formula. + +When a file-style variable is defined, the file is opened and the +string on the first line is read and stored with the variable. This +means the variable can then be evaluated as many times as desired and +will return that string. There are two ways to cause the next string +from the file to be read: use the :doc:`next ` command or the +next() function in an equal- or atom-style variable, as discussed +below. + +The rules for formatting the file are as follows. A comment character +"#" can be used anywhere on a line; text starting with the comment +character is stripped. Blank lines are skipped. The first "word" of +a non-blank line, delimited by white-space, is the "string" assigned +to the variable. + +---------- + +For the *format* style, an equal-style or compatible variable is +specified along with a C-style format string, e.g. "%f" or "%.10g", +which must be appropriate for formatting a double-precision +floating-point value and may not have extra characters. The default +format is "%.15g". This variable style allows an equal-style variable +to be formatted precisely when it is evaluated. + +Note that if you simply wish to print a variable value with desired +precision to the screen or logfile via the :doc:`print ` or +:doc:`fix print ` commands, you can also do this by +specifying an "immediate" variable with a trailing colon and format +string, as part of the string argument of those commands. This is +explained on the :doc:`Commands parse ` doc page. + +---------- + +For the *getenv* style, a single string is assigned to the variable +which should be the name of an environment variable. When the +variable is evaluated, it returns the value of the environment +variable, or an empty string if it not defined. This style of +variable can be used to adapt the behavior of LAMMPS input scripts via +environment variable settings, or to retrieve information that has +been previously stored with the :doc:`shell putenv ` command. +Note that because environment variable settings are stored by the +operating systems, they persist even if the corresponding *getenv* +style variable is deleted, and also are set for sub-shells executed +by the :doc:`shell ` command. + +---------- + +For the *index* style, one or more strings are specified. Initially, +the first string is assigned to the variable. Each time a +:doc:`next ` command is used with the variable name, the next +string is assigned. All processors assign the same string to the +variable. + +Index-style variables with a single string value can also be set by +using the :doc:`command-line switch -var `. + +---------- + +For the *internal* style a numeric value is provided. This value will +be assigned to the variable until a LAMMPS command sets it to a new +value. There are currently only two LAMMPS commands that require +*internal* variables as inputs, because they reset them: +:doc:`create_atoms ` and :doc:`fix controller +`. As mentioned above, an internal-style variable can +be used in place of an equal-style variable anywhere else in an input +script, e.g. as an argument to another command that allows for +equal-style variables. + +---------- + +The *loop* style is identical to the *index* style except that the +strings are the integers from 1 to N inclusive, if only one argument N +is specified. This allows generation of a long list of runs +(e.g. 1000) without having to list N strings in the input script. +Initially, the string "1" is assigned to the variable. Each time a +:doc:`next ` command is used with the variable name, the next +string ("2", "3", etc) is assigned. All processors assign the same +string to the variable. The *loop* style can also be specified with +two arguments N1 and N2. In this case the loop runs from N1 to N2 +inclusive, and the string N1 is initially assigned to the variable. +N1 <= N2 and N2 >= 0 is required. + +---------- + For the *python* style a Python function name is provided. This needs to match a function name specified in a :doc:`python ` command which returns a value to this variable as defined by its *return* @@ -433,25 +424,52 @@ python-style variable can be used in place of an equal-style variable anywhere in an input script, e.g. as an argument to another command that allows for equal-style variables. -For the *timer* style no additional argument is specified. The value of -the variable is set by querying the current elapsed wall time of the -simulation. This is done at the point in time when the variable is -defined in the input script. If a second timer-style variable is also -defined, then a simple formula can be used to calculate the elapsed time -between the two timers, as in the example at the top of this manual -entry. As mentioned above, timer-style variables can be redefined -elsewhere in the input script, so the same pair of variables can be used -in a loop or to time a series of operations. +---------- -For the *internal* style a numeric value is provided. This value will -be assigned to the variable until a LAMMPS command sets it to a new -value. There are currently only two LAMMPS commands that require -*internal* variables as inputs, because they reset them: -:doc:`create_atoms ` and :doc:`fix controller -`. As mentioned above, an internal-style variable can -be used in place of an equal-style variable anywhere else in an input -script, e.g. as an argument to another command that allows for -equal-style variables. +For the *string* style, a single string is assigned to the variable. +Two differences between this style and using the *index* style exist: +a variable with *string* style can be redefined, e.g. by another command later +in the input script, or if the script is read again in a loop. The other +difference is that *string* performs variable substitution even if the +string parameter is quoted. + +---------- + +The *uloop* style is identical to the *universe* style except that the +strings are the integers from 1 to N. This allows generation of long +list of runs (e.g. 1000) without having to list N strings in the input +script. + +---------- + +For the *universe* style, one or more strings are specified. There +must be at least as many strings as there are processor partitions or +"worlds". LAMMPS can be run with multiple partitions via the +:doc:`-partition command-line switch `. This variable +command initially assigns one string to each world. When a +:doc:`next ` command is encountered using this variable, the first +processor partition to encounter it, is assigned the next available +string. This continues until all the variable strings are consumed. +Thus, this command can be used to run 50 simulations on 8 processor +partitions. The simulations will be run one after the other on +whatever partition becomes available, until they are all finished. +Universe-style variables are incremented using the files +"tmp.lammps.variable" and "tmp.lammps.variable.lock" which you will +see in your directory during such a LAMMPS run. + +---------- + +For the *world* style, one or more strings are specified. There must +be one string for each processor partition or "world". LAMMPS can be +run with multiple partitions via the :doc:`-partition command-line +switch `. This variable command assigns one string to +each world. All processors in the world are assigned the same string. +The next command cannot be used with equal-style variables, since +there is only one value per world. This style of variable is useful +when you wish to run different simulations on different partitions, or +when performing a parallel tempering simulation (see the :doc:`temper +` command), to assign different temperatures to different +partitions. ---------- @@ -577,9 +595,9 @@ will not work, since the *version* has been introduced more recently): if $(version<20140513) then "communicate vel yes" else "comm_modify vel yes" The thermo keywords allowed in a formula are those defined by the -:doc:`thermo_style custom ` command. Thermo keywords that -require a :doc:`compute ` to calculate their values such as -"temp" or "press", use computes stored and invoked by the +:doc:`thermo_style custom ` command. Thermo keywords +that require a :doc:`compute ` to calculate their values such +as "temp" or "press", use computes stored and invoked by the :doc:`thermo_style ` command. This means that you can only use those keywords in a variable if the style you are using with the thermo_style command (and the thermo keywords associated with that @@ -717,10 +735,12 @@ new timestep. X,y,z > 0 and y < z are required. The generated timesteps are on a base-z logarithmic scale, starting with x, and the y value is how many of the z-1 possible timesteps within one logarithmic interval are generated. I.e. the timesteps follow the -sequence x,2x,3x,...y\*x,x\*z,2x\*z,3x\*z,...y\*x\*z,x\*z\^2,2x\*z\^2,etc. For +sequence +x,2x,3x,...y\*x,x\*z,2x\*z,3x\*z,...y\*x\*z,x\*z\^2,2x\*z\^2,etc. For any current timestep, the next timestep in the sequence is returned. -Thus if logfreq(100,4,10) is used in a variable by the :doc:`dump_modify every ` command, it will generate this sequence of -output timesteps: +Thus if logfreq(100,4,10) is used in a variable by the +:doc:`dump_modify every ` command, it will generate this +sequence of output timesteps: .. parsed-literal:: @@ -729,9 +749,10 @@ output timesteps: The logfreq2(x,y,z) function is similar to logfreq, except a single logarithmic interval is divided into y equally-spaced timesteps and all of them are output. Y < z is not required. Thus, if -logfreq2(100,18,10) is used in a variable by the :doc:`dump_modify every ` command, then the interval between 100 and -1000 is divided as 900/18 = 50 steps, and it will generate the -sequence of output timesteps: +logfreq2(100,18,10) is used in a variable by the :doc:`dump_modify +every ` command, then the interval between 100 and 1000 +is divided as 900/18 = 50 steps, and it will generate the sequence of +output timesteps: .. parsed-literal:: @@ -1289,6 +1310,33 @@ Vectors" discussion above. ---------- +Vector Initialization +--------------------- + +*Vector*-style variables only can be initialized with a special +syntax, instead of using a formula. The syntax is a bracketed, +comma-separated syntax like the following: + +.. code-block:: LAMMPS + + variable myvec vector [1,3.5,7,10.2] + +The 3rd argument formula is replaced by the vector values in brackets, +separated by commas. This example creates a 4-length vector with +specific numeric values, each of which can be specified as an integer +or floating point value. Note that while whitespace can be added +before or after individual values, no other mathematical operations +can be specified. E.g. "3*10" or "3*v_abc" are not valid vector +elements, nor is "10*[1,2,3,4]" valid for the entire vector. + +Unlike vector variables specified with formulas, this vector variable +is static; its length and values never changes. Its values can be +used in other commands (including vector-style variables specified +with formulas) via the usual syntax for accessing individual vector +elements or the entire vector. + +---------- + Immediate Evaluation of Variables """"""""""""""""""""""""""""""""" @@ -1306,18 +1354,19 @@ with a leading $ sign (e.g. $x or ${abc}) versus with a leading "v\_" (e.g. v_x or v_abc). The former can be used in any input script command, including a variable command. The input script parser evaluates the reference variable immediately and substitutes its value -into the command. As explained on the :doc:`Commands parse ` doc page, you can also use un-named -"immediate" variables for this purpose. For example, a string like -this $((xlo+xhi)/2+sqrt(v_area)) in an input script command evaluates -the string between the parenthesis as an equal-style variable formula. +into the command. As explained on the :doc:`Commands parse +` doc page, you can also use un-named "immediate" +variables for this purpose. For example, a string like this +$((xlo+xhi)/2+sqrt(v_area)) in an input script command evaluates the +string between the parenthesis as an equal-style variable formula. Referencing a variable with a leading "v\_" is an optional or required -kind of argument for some commands (e.g. the :doc:`fix ave/chunk ` or :doc:`dump custom ` or -:doc:`thermo_style ` commands) if you wish it to evaluate -a variable periodically during a run. It can also be used in a -variable formula if you wish to reference a second variable. The -second variable will be evaluated whenever the first variable is -evaluated. +kind of argument for some commands (e.g. the :doc:`fix ave/chunk +` or :doc:`dump custom ` or :doc:`thermo_style +` commands) if you wish it to evaluate a variable +periodically during a run. It can also be used in a variable formula +if you wish to reference a second variable. The second variable will +be evaluated whenever the first variable is evaluated. As an example, suppose you use this command in your input script to define the variable "v" as @@ -1330,8 +1379,9 @@ before a run where the simulation box size changes. You might think this will assign the initial volume to the variable "v". That is not the case. Rather it assigns a formula which evaluates the volume (using the thermo_style keyword "vol") to the variable "v". If you -use the variable "v" in some other command like :doc:`fix ave/time ` then the current volume of the box will be -evaluated continuously during the run. +use the variable "v" in some other command like :doc:`fix ave/time +` then the current volume of the box will be evaluated +continuously during the run. If you want to store the initial volume of the system, you can do it this way: diff --git a/src/variable.cpp b/src/variable.cpp index b4cf2f3ed6..afc1898a0d 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -503,7 +503,6 @@ void Variable::set(int narg, char **arg) data[ivar][1] = utils::strdup(str); } replaceflag = 1; - } else { if (nvar == maxvar) grow(); style[nvar] = VECTOR; @@ -512,9 +511,10 @@ void Variable::set(int narg, char **arg) pad[nvar] = 0; data[nvar] = new char*[num[nvar]]; data[nvar][0] = utils::strdup(arg[2]); - if (data[nvar][0][0] != '[') + if (data[nvar][0][0] != '[') { vecs[nvar].dynamic = 1; - else { + data[nvar][1] = nullptr; + } else { vecs[nvar].dynamic = 0; parse_vector(nvar,data[nvar][0]); std::vector vec(vecs[nvar].values,vecs[nvar].values + vecs[nvar].n); @@ -959,7 +959,7 @@ int Variable::internalstyle(int ivar) if GETENV, query environment and put result in str if PYTHON, evaluate Python function, it will put result in str if INTERNAL, convert dvalue and put result in str - if VECTOR, return ptr to str = [value,value,...] + if VECTOR, return str = [value,value,...] if ATOM or ATOMFILE, return nullptr return nullptr if no variable with name or if which value is bad, caller must respond @@ -981,17 +981,21 @@ char *Variable::retrieve(const char *name) style[ivar] == UNIVERSE || style[ivar] == STRING || style[ivar] == SCALARFILE) { str = data[ivar][which[ivar]]; + } else if (style[ivar] == LOOP || style[ivar] == ULOOP) { + std::string result; if (pad[ivar] == 0) result = std::to_string(which[ivar]+1); else result = fmt::format("{:0>{}d}",which[ivar]+1, pad[ivar]); delete[] data[ivar][0]; str = data[ivar][0] = utils::strdup(result); + } else if (style[ivar] == EQUAL) { double answer = evaluate(data[ivar][0],nullptr,ivar); delete[] data[ivar][1]; data[ivar][1] = utils::strdup(fmt::format("{:.15g}",answer)); str = data[ivar][1]; + } else if (style[ivar] == FORMAT) { int jvar = find(data[ivar][0]); if (jvar < 0) @@ -1002,11 +1006,13 @@ char *Variable::retrieve(const char *name) double answer = compute_equal(jvar); sprintf(data[ivar][2],data[ivar][1],answer); str = data[ivar][2]; + } else if (style[ivar] == GETENV) { const char *result = getenv(data[ivar][0]); if (result == nullptr) result = (const char *) ""; delete[] data[ivar][1]; str = data[ivar][1] = utils::strdup(result); + } else if (style[ivar] == PYTHON) { int ifunc = python->variable_match(data[ivar][0],name,0); if (ifunc < 0) { @@ -1026,16 +1032,37 @@ char *Variable::retrieve(const char *name) } python->invoke_function(ifunc,data[ivar][1]); str = data[ivar][1]; + // if Python func returns a string longer than VALUELENGTH // then the Python class stores the result, query it via long_string() + char *strlong = python->long_string(ifunc); if (strlong) str = strlong; + } else if (style[ivar] == TIMER || style[ivar] == INTERNAL) { delete[] data[ivar][0]; data[ivar][0] = utils::strdup(fmt::format("{:.15g}",dvalue[ivar])); str = data[ivar][0]; + } else if (style[ivar] == VECTOR) { + + // check if vector variable needs to be re-computed + // if no, just return previously formatted string in data[ivar][1] + // if yes, invoke compute_vector() and convert vector to formatted string + // must also turn off eval_in_progress b/c compute_vector() checks it + + if (vecs[ivar].dynamic || vecs[ivar].currentstep != update->ntimestep) { + eval_in_progress[ivar] = 0; + double *result; + int nvec = compute_vector(ivar,&result); + delete[] data[ivar][1]; + std::vector vectmp(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n); + std::string str = fmt::format("[{}]", fmt::join(vectmp,",")); + data[ivar][1] = utils::strdup(str); + } + str = data[ivar][1]; + } else if (style[ivar] == ATOM || style[ivar] == ATOMFILE) return nullptr; @@ -1186,7 +1213,7 @@ int Variable::compute_vector(int ivar, double **result) return vecs[ivar].n; } - // evaluate vector afresh + // evaluate vector variable afresh if (eval_in_progress[ivar]) print_var_error(FLERR,"has a circular dependency",ivar); @@ -1220,14 +1247,6 @@ int Variable::compute_vector(int ivar, double **result) free_tree(tree); eval_in_progress[ivar] = 0; - // convert numeric vector to formatted string in data[ivar][1] - // this is so that retrieve() on the vector variable will work - - delete[] data[ivar][1]; - std::vector vectmp(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n); - std::string str = fmt::format("[{}]", fmt::join(vectmp,",")); - data[ivar][1] = utils::strdup(str); - *result = vec; return nlen; } @@ -2296,7 +2315,7 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) if (nopstack) print_var_error(FLERR,"Invalid syntax in variable formula",ivar); - // for atom-style variable, return remaining tree + // for atom-style and vector-style variable, return remaining tree // for equal-style variable, return remaining arg if (tree) { From 5da1df5004b464abbaf8a9b19d4a75a4df401eb5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 20:08:36 -0400 Subject: [PATCH 149/448] add versionadded tag --- doc/src/fix_print.rst | 4 ++++ doc/src/print.rst | 4 ++++ doc/src/variable.rst | 4 +++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/src/fix_print.rst b/doc/src/fix_print.rst index 0594c8d421..938b40d1f9 100644 --- a/doc/src/fix_print.rst +++ b/doc/src/fix_print.rst @@ -44,6 +44,10 @@ one word. If it contains variables it must be enclosed in double quotes to ensure they are not evaluated when the input script line is read, but will instead be evaluated each time the string is printed. +.. versionadded:: TBD + + support for vector style variables + See the :doc:`variable ` command for a description of *equal* and *vector* style variables which are typically the most useful ones to use with the print command. Equal- and vector-style diff --git a/doc/src/print.rst b/doc/src/print.rst index 68fe8416dd..f5a872e768 100644 --- a/doc/src/print.rst +++ b/doc/src/print.rst @@ -46,6 +46,10 @@ lines of output, the string can be enclosed in triple quotes, as in the last example above. If the text string contains variables, they will be evaluated and their current values printed. +.. versionadded:: TBD + + support for vector style variables + See the :doc:`variable ` command for a description of *equal* and *vector* style variables which are typically the most useful ones to use with the print command. Equal- and vector-style diff --git a/doc/src/variable.rst b/doc/src/variable.rst index e7c7cdcb44..83ef6f4ac4 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -44,7 +44,7 @@ Syntax pad = all values will be same length, e.g. 001, 002, ..., 100 *universe* args = one or more strings *world* args = one string for each partition of processors - + *equal* or *vector* or *atom* args = one formula containing numbers, thermo keywords, math operations, built-in functions, atom values and vectors, compute/fix/variable references numbers = 0.0, 100, -5.4, 2.8e-4, etc constants = PI, version, on, off, true, false, yes, no @@ -1313,6 +1313,8 @@ Vectors" discussion above. Vector Initialization --------------------- +.. versionadded:: TBD + *Vector*-style variables only can be initialized with a special syntax, instead of using a formula. The syntax is a bracketed, comma-separated syntax like the following: From 0c10184a69450d754cfa7c25e4a2cec071187d27 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 20:09:45 -0400 Subject: [PATCH 150/448] whitespace, simplify --- src/variable.cpp | 55 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index afc1898a0d..12be445128 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -499,9 +499,8 @@ void Variable::set(int narg, char **arg) vecs[ivar].dynamic = 0; parse_vector(ivar,data[ivar][0]); std::vector vec(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n); - std::string str = fmt::format("[{}]", fmt::join(vec,",")); - data[ivar][1] = utils::strdup(str); - } + data[ivar][1] = utils::strdup(fmt::format("[{}]", fmt::join(vec,","))); + } replaceflag = 1; } else { if (nvar == maxvar) grow(); @@ -518,9 +517,8 @@ void Variable::set(int narg, char **arg) vecs[nvar].dynamic = 0; parse_vector(nvar,data[nvar][0]); std::vector vec(vecs[nvar].values,vecs[nvar].values + vecs[nvar].n); - std::string str = fmt::format("[{}]", fmt::join(vec,",")); - data[nvar][1] = utils::strdup(str); - } + data[nvar][1] = utils::strdup(fmt::format("[{}]", fmt::join(vec,","))); + } } // PYTHON @@ -981,21 +979,21 @@ char *Variable::retrieve(const char *name) style[ivar] == UNIVERSE || style[ivar] == STRING || style[ivar] == SCALARFILE) { str = data[ivar][which[ivar]]; - + } else if (style[ivar] == LOOP || style[ivar] == ULOOP) { - + std::string result; if (pad[ivar] == 0) result = std::to_string(which[ivar]+1); else result = fmt::format("{:0>{}d}",which[ivar]+1, pad[ivar]); delete[] data[ivar][0]; str = data[ivar][0] = utils::strdup(result); - + } else if (style[ivar] == EQUAL) { double answer = evaluate(data[ivar][0],nullptr,ivar); delete[] data[ivar][1]; data[ivar][1] = utils::strdup(fmt::format("{:.15g}",answer)); str = data[ivar][1]; - + } else if (style[ivar] == FORMAT) { int jvar = find(data[ivar][0]); if (jvar < 0) @@ -1006,13 +1004,13 @@ char *Variable::retrieve(const char *name) double answer = compute_equal(jvar); sprintf(data[ivar][2],data[ivar][1],answer); str = data[ivar][2]; - + } else if (style[ivar] == GETENV) { const char *result = getenv(data[ivar][0]); if (result == nullptr) result = (const char *) ""; delete[] data[ivar][1]; str = data[ivar][1] = utils::strdup(result); - + } else if (style[ivar] == PYTHON) { int ifunc = python->variable_match(data[ivar][0],name,0); if (ifunc < 0) { @@ -1032,25 +1030,25 @@ char *Variable::retrieve(const char *name) } python->invoke_function(ifunc,data[ivar][1]); str = data[ivar][1]; - + // if Python func returns a string longer than VALUELENGTH // then the Python class stores the result, query it via long_string() - + char *strlong = python->long_string(ifunc); if (strlong) str = strlong; - + } else if (style[ivar] == TIMER || style[ivar] == INTERNAL) { delete[] data[ivar][0]; data[ivar][0] = utils::strdup(fmt::format("{:.15g}",dvalue[ivar])); str = data[ivar][0]; - + } else if (style[ivar] == VECTOR) { // check if vector variable needs to be re-computed // if no, just return previously formatted string in data[ivar][1] // if yes, invoke compute_vector() and convert vector to formatted string // must also turn off eval_in_progress b/c compute_vector() checks it - + if (vecs[ivar].dynamic || vecs[ivar].currentstep != update->ntimestep) { eval_in_progress[ivar] = 0; double *result; @@ -1060,9 +1058,9 @@ char *Variable::retrieve(const char *name) std::string str = fmt::format("[{}]", fmt::join(vectmp,",")); data[ivar][1] = utils::strdup(str); } - + str = data[ivar][1]; - + } else if (style[ivar] == ATOM || style[ivar] == ATOMFILE) return nullptr; @@ -1214,7 +1212,7 @@ int Variable::compute_vector(int ivar, double **result) } // evaluate vector variable afresh - + if (eval_in_progress[ivar]) print_var_error(FLERR,"has a circular dependency",ivar); @@ -4063,14 +4061,15 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t // word is not a match to any special function - if (strcmp(word,"sum") != 0 && strcmp(word,"min") && strcmp(word,"max") != 0 && strcmp(word,"ave") != 0 && - strcmp(word,"trap") != 0 && strcmp(word,"slope") != 0 && strcmp(word,"gmask") != 0 && strcmp(word,"rmask") != 0 && - strcmp(word,"grmask") != 0 && strcmp(word,"next") != 0 && strcmp(word,"is_file") != 0 && - strcmp(word,"is_os") != 0 && strcmp(word,"extract_setting") != 0 && strcmp(word,"label2type") != 0) + if (strcmp(word,"sum") != 0 && strcmp(word,"min") && strcmp(word,"max") != 0 && + strcmp(word,"ave") != 0 && strcmp(word,"trap") != 0 && strcmp(word,"slope") != 0 && + strcmp(word,"gmask") != 0 && strcmp(word,"rmask") != 0 && strcmp(word,"grmask") != 0 && + strcmp(word,"next") != 0 && strcmp(word,"is_file") != 0 && strcmp(word,"is_os") != 0 && + strcmp(word,"extract_setting") != 0 && strcmp(word,"label2type") != 0) return 0; // process label2type() separately b/c its label arg can have commas in it - + if (strcmp(word,"label2type") == 0) { if (!atom->labelmapflag) print_var_error(FLERR,"Cannot use label2type() function without a labelmap",ivar); @@ -4772,13 +4771,13 @@ void Variable::atom_vector(char *word, Tree **tree, Tree **treestack, int &ntree void Variable::parse_vector(int ivar, char *str) { // unlimited allows for any vector length - + char **args; int nvec = parse_args_unlimited(str,args); if (args[nvec-1][strlen(args[nvec-1])-1] != ']') error->all(FLERR,"Vector variable formula lacks closing brace: {}",str); - + vecs[ivar].n = nvec; vecs[ivar].nmax = nvec; vecs[ivar].currentstep = -1; @@ -4849,7 +4848,7 @@ int Variable::parse_args_unlimited(char *str, char **&args) int maxarg = 0; args = nullptr; - + while (ptr) { ptrnext = find_next_comma(ptr); if (ptrnext) *ptrnext = '\0'; From 67b6a1de705a32923def69a72b9aa637d6cae845 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 20:09:57 -0400 Subject: [PATCH 151/448] fixup broken unit tests --- src/variable.cpp | 4 ++-- unittest/commands/test_variables.cpp | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 12be445128..af0d33449a 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4094,11 +4094,11 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t } else if (kind == "improper") { value = atom->lmap->find(typestr,Atom::IMPROPER); } else { - print_var_error(FLERR, fmt::format("Invalid kind {} in label2type in variable",kind), ivar); + print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() in variable",kind),ivar); } if (value == -1) - print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type in variable", + print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable", kind, typestr), ivar); // save value in tree or on argstack diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index 8debb95b6a..fbb2beb220 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -402,7 +402,7 @@ TEST_F(VariableTest, Functions) command("print \"$(extract_setting()\"");); TEST_FAILURE(".*ERROR on proc 0: Invalid immediate variable.*", command("print \"$(extract_setting()\"");); - TEST_FAILURE(".*ERROR: Invalid extract_setting.. function syntax in variable formula.*", + TEST_FAILURE(".*ERROR: Invalid extract_setting.. function in variable formula.*", command("print \"$(extract_setting(one,two))\"");); TEST_FAILURE( ".*ERROR: Unknown setting nprocs for extract_setting.. function in variable formula.*", @@ -599,9 +599,9 @@ TEST_F(VariableTest, Label2TypeAtomic) ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,O1)"), 3.0); ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,H1)"), 4.0); - TEST_FAILURE(".*ERROR: Variable t1: Invalid atom type label C1 in variable formula.*", + TEST_FAILURE(".*ERROR: Variable t1: Invalid atom type label C1 in label2type.. in variable.*", command("print \"${t1}\"");); - TEST_FAILURE(".*ERROR: Invalid bond type label H1 in variable formula.*", + TEST_FAILURE(".*ERROR: Invalid bond type label H1 in label2type.. in variable.*", variable->compute_equal("label2type(bond,H1)");); } From 0b71371597a1ae237d600f13ce592a26fb78393c Mon Sep 17 00:00:00 2001 From: jrgissing Date: Thu, 4 May 2023 20:10:13 -0400 Subject: [PATCH 152/448] reax/species: variable input for Nlimit keyword --- doc/src/fix_reaxff_species.rst | 3 ++- src/REAXFF/fix_reaxff_species.cpp | 23 +++++++++++++++++------ src/REAXFF/fix_reaxff_species.h | 3 ++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/doc/src/fix_reaxff_species.rst b/doc/src/fix_reaxff_species.rst index 383b8212f9..f57132f08b 100644 --- a/doc/src/fix_reaxff_species.rst +++ b/doc/src/fix_reaxff_species.rst @@ -148,7 +148,8 @@ formulae). The *specieslist* and *masslimit* keywords cannot both be used in the same *reaxff/species* fix. The *delete_rate_limit* keyword can enforce an upper limit on the overall rate of molecule deletion. The number of deletion occurrences is limited to Nlimit -within an interval of Nsteps timesteps. When using the +within an interval of Nsteps timesteps. Nlimit can be specified with +an equal-style :doc:`variable `. When using the *delete_rate_limit* keyword, no deletions are permitted to occur within the first Nsteps timesteps of the first run (after reading a either a data or restart file). diff --git a/src/REAXFF/fix_reaxff_species.cpp b/src/REAXFF/fix_reaxff_species.cpp index 29441cd4b3..725c1370d1 100644 --- a/src/REAXFF/fix_reaxff_species.cpp +++ b/src/REAXFF/fix_reaxff_species.cpp @@ -28,11 +28,13 @@ #include "fix_ave_atom.h" #include "force.h" #include "group.h" +#include "input.h" #include "memory.h" #include "modify.h" #include "neigh_list.h" #include "neighbor.h" #include "update.h" +#include "variable.h" #include "pair_reaxff.h" #include "reaxff_defs.h" @@ -239,7 +241,14 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : // rate limit when deleting molecules } else if (strcmp(arg[iarg], "delete_rate_limit") == 0) { if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix reaxff/species delete_rate_limit", error); - delete_Nlimit = utils::numeric(FLERR, arg[iarg+1], false, lmp); + delete_Nlimit_varid = -1; + if (strncmp(arg[iarg+1],"v_",2) == 0) { + delete_Nlimit_varid = input->variable->find(&arg[iarg+1][2]); + if (delete_Nlimit_varid < 0) + error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",&arg[iarg+1][2]); + if (!input->variable->equalstyle(delete_Nlimit_varid)) + error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",&arg[iarg+1][2]); + } else delete_Nlimit = utils::numeric(FLERR, arg[iarg+1], false, lmp); delete_Nsteps = utils::numeric(FLERR, arg[iarg+2], false, lmp); iarg += 3; // position of molecules @@ -280,7 +289,7 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : if (delflag && specieslistflag && masslimitflag) error->all(FLERR, "Incompatible combination fix reaxff/species command options"); - if (delete_Nlimit > 0) { + if (delete_Nsteps > 0) { if (lmp->citeme) lmp->citeme->add(cite_reaxff_species_delete); memory->create(delete_Tcount,delete_Nsteps,"reaxff/species:delete_Tcount"); @@ -407,7 +416,7 @@ void FixReaxFFSpecies::Output_ReaxFF_Bonds(bigint ntimestep, FILE * /*fp*/) if (ntimestep != nvalid) { // push back delete_Tcount on every step - if (delete_Nlimit > 0) + if (delete_Nsteps > 0) for (int i = delete_Nsteps-1; i > 0; i--) delete_Tcount[i] = delete_Tcount[i-1]; return; @@ -864,9 +873,11 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) { int ndeletions; int headroom = -1; - if (delete_Nlimit > 0) { + if (delete_Nsteps > 0) { if (delete_Tcount[delete_Nsteps-1] == -1) return; ndeletions = delete_Tcount[0] - delete_Tcount[delete_Nsteps-1]; + if (delete_Nlimit_varid > -1) + delete_Nlimit = input->variable->compute_equal(delete_Nlimit_varid); headroom = MAX(0, delete_Nlimit - ndeletions); if (headroom == 0) return; } @@ -907,7 +918,7 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) memory->create(molrange,Nmole,"reaxff/species:molrange"); for (m = 0; m < Nmole; m++) molrange[m] = m + 1; - if (delete_Nlimit > 0) { + if (delete_Nsteps > 0) { // shuffle index when using rate_limit, in case order is biased if (comm->me == 0) std::shuffle(&molrange[0],&molrange[Nmole], park_rng); @@ -1041,7 +1052,7 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) // push back delete_Tcount on every step - if (delete_Nlimit > 0) { + if (delete_Nsteps > 0) { for (i = delete_Nsteps-1; i > 0; i--) delete_Tcount[i] = delete_Tcount[i-1]; delete_Tcount[0] += this_delete_Tcount; diff --git a/src/REAXFF/fix_reaxff_species.h b/src/REAXFF/fix_reaxff_species.h index 329e17145b..c1a93d0584 100644 --- a/src/REAXFF/fix_reaxff_species.h +++ b/src/REAXFF/fix_reaxff_species.h @@ -60,7 +60,8 @@ class FixReaxFFSpecies : public Fix { FILE *fp, *pos, *fdel; int eleflag, posflag, multipos, padflag, setupflag; int delflag, specieslistflag, masslimitflag; - int delete_Nlimit, delete_Nsteps, *delete_Tcount; + int delete_Nlimit, delete_Nlimit_varid; + int delete_Nsteps, *delete_Tcount; double massmin, massmax; int singlepos_opened, multipos_opened, del_opened; char *ele, **eletype, *filepos, *filedel; From 0de35dee295195bcf9fd91fc822a7e8459a679ac Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 20:34:41 -0400 Subject: [PATCH 153/448] spelling --- doc/src/variable.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/variable.rst b/doc/src/variable.rst index 83ef6f4ac4..f923e548c4 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -256,7 +256,7 @@ commands before the variable would become exhausted. For example, ---------- The next sections describe in how all the various variable styles are -defined and what they store. The styles are listed alphabetcally, +defined and what they store. The styles are listed alphabetically, except for the *equal* and *vector* and *atom* styles, which are explained together after all the others. @@ -1093,9 +1093,9 @@ the pair keyword and reducing the outer time step. The *is_defined(category,id)* function checks whether an instance of a style or variable with a specific ID or name is currently defined -within LAMMPS. The suppported categories are *compute*, *dump*, +within LAMMPS. The supported categories are *compute*, *dump*, *fix*, *group*, *region*, and *variable*. Each of these styles (as -well as the variable command) can be speficied multiple times within +well as the variable command) can be specified multiple times within LAMMPS, each with a unique *id*. This function checks whether the specified *id* exists. For category *variable", the *id* is the variable name. From 366b64571d14b01ebc091219ced48a0ac9f9ddd8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 20:44:46 -0400 Subject: [PATCH 154/448] add a few unit tests for static vector style variables --- unittest/commands/test_variables.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index fbb2beb220..a09ebaa538 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -140,16 +140,18 @@ TEST_F(VariableTest, CreateDelete) command("variable ten1 universe 1 2 3 4"); command("variable ten2 uloop 4"); command("variable ten3 uloop 4 pad"); + command("variable ten4 vector [0,1,2,3,5,7,11]"); + command("variable ten5 vector [0.5,1.25]"); command("variable dummy index 0"); command("variable file equal is_file(MYFILE)"); command("variable iswin equal is_os(^Windows)"); command("variable islin equal is_os(^Linux)"); END_HIDE_OUTPUT(); - ASSERT_EQ(variable->nvar, 20); + ASSERT_EQ(variable->nvar, 22); BEGIN_HIDE_OUTPUT(); command("variable dummy delete"); END_HIDE_OUTPUT(); - ASSERT_EQ(variable->nvar, 19); + ASSERT_EQ(variable->nvar, 21); ASSERT_THAT(variable->retrieve("three"), StrEq("three")); variable->set_string("three", "four"); ASSERT_THAT(variable->retrieve("three"), StrEq("four")); @@ -160,6 +162,8 @@ TEST_F(VariableTest, CreateDelete) ASSERT_THAT(variable->retrieve("eight"), StrEq("")); variable->internal_set(variable->find("ten"), 2.5); ASSERT_THAT(variable->retrieve("ten"), StrEq("2.5")); + EXPECT_THAT(variable->retrieve("ten4"), StrEq("[0,1,2,3,5,7,11]")); + EXPECT_THAT(variable->retrieve("ten5"), StrEq("[0.5,1.25]")); ASSERT_THAT(variable->retrieve("file"), StrEq("0")); FILE *fp = fopen("MYFILE", "w"); fputs(" ", fp); @@ -217,7 +221,7 @@ TEST_F(VariableTest, CreateDelete) TEST_FAILURE(".*ERROR: World variable count doesn't match # of partitions.*", command("variable ten10 world xxx xxx");); TEST_FAILURE(".*ERROR: All universe/uloop variables must have same # of values.*", - command("variable ten4 uloop 2");); + command("variable ten6 uloop 2");); TEST_FAILURE(".*ERROR: Incorrect conversion in format string.*", command("variable ten11 format two \"%08x\"");); TEST_FAILURE(".*ERROR: Variable name 'ten@12' must have only letters, numbers, or undersc.*", @@ -321,6 +325,9 @@ TEST_F(VariableTest, Expressions) command("variable err1 equal v_one/v_ten7"); command("variable err2 equal v_one%v_ten7"); command("variable err3 equal v_ten7^-v_one"); + command("variable vec1 vector [-2,0,1,2,3,5,7]"); + command("variable vec2 vector v_vec1*0.5"); + command("variable vec3 equal v_vec2[3]"); variable->set("dummy index 1 2"); END_HIDE_OUTPUT(); @@ -347,6 +354,9 @@ TEST_F(VariableTest, Expressions) ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten10"), 100); ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten11"), 1); ASSERT_DOUBLE_EQ(variable->compute_equal("v_ten12"), 3); + EXPECT_THAT(variable->retrieve("vec1"), StrEq("[-2,0,1,2,3,5,7]")); + EXPECT_THAT(variable->retrieve("vec2"), StrEq("[-1,0,0.5,1,1.5,2.5,3.5]")); + ASSERT_DOUBLE_EQ(variable->compute_equal("v_vec3"), 0.5); TEST_FAILURE(".*ERROR: Variable six: Invalid thermo keyword 'XXX' in variable formula.*", command("print \"${six}\"");); From 1b7f9439adab0d5f41a6dd04763f5849b9a8331a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 4 May 2023 21:14:25 -0400 Subject: [PATCH 155/448] simplify parse_vector() method by using Tokenizer class --- src/variable.cpp | 69 ++++++------------------------------------------ src/variable.h | 1 - 2 files changed, 8 insertions(+), 62 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index af0d33449a..091e221b1d 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4770,43 +4770,21 @@ void Variable::atom_vector(char *word, Tree **tree, Tree **treestack, int &ntree void Variable::parse_vector(int ivar, char *str) { - // unlimited allows for any vector length - - char **args; - int nvec = parse_args_unlimited(str,args); - - if (args[nvec-1][strlen(args[nvec-1])-1] != ']') - error->all(FLERR,"Vector variable formula lacks closing brace: {}",str); + // check for square brackets, remove them, and split into vector + int nstr = strlen(str)-1; + if ((str[0] != '[') || (str[nstr] != ']')) + error->all(FLERR,"Vector variable formula lacks opening or closing brace: {}", str); + std::vector args = Tokenizer(std::string(str+1, str+nstr), ",").as_vector(); + int nvec = args.size(); vecs[ivar].n = nvec; vecs[ivar].nmax = nvec; vecs[ivar].currentstep = -1; memory->destroy(vecs[ivar].values); memory->create(vecs[ivar].values,vecs[ivar].nmax,"variable:values"); - char *onearg,*copy; - for (int i = 0; i < nvec; i++) { - onearg = utils::strdup(args[i]); - if (onearg[0] == '[') { - copy = utils::strdup(utils::trim(&onearg[1])); - delete[] onearg; - onearg = copy; - } - if (onearg[strlen(onearg)-1] == ']') { - onearg[strlen(onearg)-1] = '\0'; - copy = utils::strdup(utils::trim(onearg)); - delete[] onearg; - onearg = copy; - } - - vecs[ivar].values[i] = utils::numeric(FLERR, onearg, false, lmp); - delete[] onearg; - } - - // delete stored args - - for (int i = 0; i < nvec; i++) delete[] args[i]; - memory->sfree(args); + for (int i = 0; i < nvec; i++) + vecs[ivar].values[i] = utils::numeric(FLERR, args[i], false, lmp); } /* ---------------------------------------------------------------------- @@ -4834,37 +4812,6 @@ int Variable::parse_args(char *str, char **args) return narg; } -/* ---------------------------------------------------------------------- - parse string for comma-separated args - store copy of each arg in args array - grow args array as large as needed -------------------------------------------------------------------------- */ - -int Variable::parse_args_unlimited(char *str, char **&args) -{ - char *ptrnext; - int narg = 0; - char *ptr = str; - - int maxarg = 0; - args = nullptr; - - while (ptr) { - ptrnext = find_next_comma(ptr); - if (ptrnext) *ptrnext = '\0'; - if (narg == maxarg) { - maxarg += CHUNK; - args = (char **) memory->srealloc(args,maxarg*sizeof(char *),"variable:args"); - } - args[narg] = utils::strdup(utils::trim(ptr)); - narg++; - ptr = ptrnext; - if (ptr) ptr++; - } - - return narg; -} - /* ---------------------------------------------------------------------- find next comma in str skip commas inside one or more nested parenthesis diff --git a/src/variable.h b/src/variable.h index eccb58e526..c0aeaebd37 100644 --- a/src/variable.h +++ b/src/variable.h @@ -147,7 +147,6 @@ class Variable : protected Pointers { int is_atom_vector(char *); void atom_vector(char *, Tree **, Tree **, int &); int parse_args(char *, char **); - int parse_args_unlimited(char *, char **&); void parse_vector(int, char *); char *find_next_comma(char *); void print_var_error(const std::string &, int, const std::string &, int, int global = 1); From 0facd4cf66463ba68de831ca5f0fe49b067a7c59 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 5 May 2023 01:06:55 -0400 Subject: [PATCH 156/448] support vector variable definitions with embedded blanks --- src/variable.cpp | 2 +- unittest/commands/test_variables.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 091e221b1d..1de95090cf 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4784,7 +4784,7 @@ void Variable::parse_vector(int ivar, char *str) memory->create(vecs[ivar].values,vecs[ivar].nmax,"variable:values"); for (int i = 0; i < nvec; i++) - vecs[ivar].values[i] = utils::numeric(FLERR, args[i], false, lmp); + vecs[ivar].values[i] = utils::numeric(FLERR, utils::trim(args[i]), false, lmp); } /* ---------------------------------------------------------------------- diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index a09ebaa538..3939c9b71b 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -325,7 +325,7 @@ TEST_F(VariableTest, Expressions) command("variable err1 equal v_one/v_ten7"); command("variable err2 equal v_one%v_ten7"); command("variable err3 equal v_ten7^-v_one"); - command("variable vec1 vector [-2,0,1,2,3,5,7]"); + command("variable vec1 vector \"[-2, 0, 1,2 ,3, 5 , 7\n]\""); command("variable vec2 vector v_vec1*0.5"); command("variable vec3 equal v_vec2[3]"); variable->set("dummy index 1 2"); From 56f06bc9e090a3cb58acec75383a3a7cd8bb6f15 Mon Sep 17 00:00:00 2001 From: Joel Thomas Clemmer Date: Fri, 5 May 2023 09:41:54 -0600 Subject: [PATCH 157/448] Reordering styles by priority, misc clean ups --- doc/src/Modify_requirements.rst | 44 +++++------ doc/src/Modify_style.rst | 136 +++++++++++++++----------------- 2 files changed, 86 insertions(+), 94 deletions(-) diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 837e2a3360..91a17789b6 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -27,20 +27,20 @@ negotiable or optional. Please feel free to contact the LAMMPS core developers in case you need additional explanations or clarifications or in case you need assistance in realizing the (strict) requirements for your contributions. Requirements include: -* :ref:`Licensing requirements ` (strict) -* :ref:`Integration testing ` (strict) -* :ref:`Documentation ` (strict) -* :ref:`Programming language standards ` (strict) -* :ref:`Build system ` (strict) -* :ref:`Command or style names ` (strict) -* :ref:`Programming style requirements ` (varied) -* :ref:`Examples ` (preferred) -* :ref:`Error or warning messages and explanations ` (preferred) -* :ref:`Citation reminder ` (optional) -* :ref:`Testing ` (optional) +* :ref:`Licensing requirements ` (strict) +* :ref:`Integration testing ` (strict) +* :ref:`Documentation ` (strict) +* :ref:`Programming language standards ` (strict) +* :ref:`Build system ` (strict) +* :ref:`Command or style names ` (strict) +* :ref:`Programming style requirements ` (varied) +* :ref:`Examples ` (preferred) +* :ref:`Error or warning messages and explanations ` (preferred) +* :ref:`Citation reminder ` (optional) +* :ref:`Testing ` (optional) -.. _License: +.. _ReqLicense: Licensing requirements (strict) ------------------------------- @@ -70,7 +70,7 @@ that use code with a conflicting license can be split into two parts: Please note, that this split licensed mode may complicate including the contribution in binary packages. -.. _IntegrationTesting: +.. _ReqIntegrationTesting: Integration testing (strict) ---------------------------- @@ -96,7 +96,7 @@ testing tools or scripts or tests themselves. This is rare. If in doubt, contact the LAMMPS developer that is assigned to the pull request. -.. _Documentation: +.. _ReqDocumentation: Documentation (strict) ---------------------- @@ -157,7 +157,7 @@ it for people to get started, the more likely it is that users will try out your new feature. -.. _ProgrammingStandards: +.. _ReqProgrammingStandards: Programming language standards (strict) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -189,7 +189,7 @@ required to use those older tools for access to advanced hardware features or not have the option to install newer compilers or libraries. -.. _BuildSystem: +.. _ReqBuildSystem: Build system (strict) --------------------- @@ -217,7 +217,7 @@ cmake/Modules/Packages/. Please check out how this is handled for existing packages and ask the LAMMPS developers if you need assistance. -.. _Naming: +.. _ReqNaming: Command or Style names, file names, and keywords (strict) --------------------------------------------------------- @@ -231,7 +231,7 @@ established (e.g. lj for Lennard-Jones). For a compute style `LMP_COMPUTE_SOME_NAME_H` and the class name `ComputeSomeName`. -.. _ProgrammingStyle: +.. _ReqProgrammingStyle: Programming style requirements (varied) --------------------------------------- @@ -244,7 +244,7 @@ the style guidelines are provided in the :doc:`programming style doc page `. -.. _Examples: +.. _ReqExamples: Examples (preferred) -------------------- @@ -278,7 +278,7 @@ examples/PACKAGES directory are are further described on the file from other folders should be re-used through symbolic links -.. _ErrorMessages: +.. _ReqErrorMessages: Error or warning messages and explanations (preferred) ------------------------------------------------------ @@ -327,7 +327,7 @@ scheme will make it easier for LAMMPS users, developers, and maintainers. -.. _Citation: +.. _ReqCitation: Citation reminder (optional) ----------------------------- @@ -357,7 +357,7 @@ documentation page you provide describing your contribution. If you are not sure what the best option would be, please contact the LAMMPS developers for advice. -.. _UnitTesting: +.. _ReqUnitTesting: Testing (optional) ------------------ diff --git a/doc/src/Modify_style.rst b/doc/src/Modify_style.rst index 41f7748e9f..a42bdd0d1f 100644 --- a/doc/src/Modify_style.rst +++ b/doc/src/Modify_style.rst @@ -17,27 +17,16 @@ may serve as representative examples. Include files (varied) ^^^^^^^^^^^^^^^^^^^^^^ -- system headers or from installed libraries are include with angular - brackets (example: ``#include ``), while local include file - use double quotes (example: ``#include "atom.h"``) - -- when including system header files from the C library use the - C++-style names (```` or ````) instead of the - C-style names (```` or ````) - -- the order of ``#include`` statements in a file ``some_name.cpp`` that - implements a class ``SomeName`` defined in a header file - ``some_name.h`` should be as follows: - - - ``#include "some_name.h"`` followed by an empty line - - - LAMMPS include files e.g. ``#include "comm.h"`` or ``#include - "modify.h"`` in alphabetical order followed by an empty line - - - system header files from the C++ or C standard library followed by - an empty line - - - ``using namespace LAMMPS_NS`` or other namespace imports. +- Header files that define a new LAMMPS style (i.e. that have a + ``SomeStyle(some/name,SomeName);`` macro in them) should only use the + include file for the base class and otherwise use forward declarations + and pointers; when interfacing to a library use the PIMPL (pointer + to implementation) approach where you have a pointer to a struct + that contains all library specific data (and thus requires the library + header) but use a forward declaration and define the struct only in + the implementation file. This is a **strict** requirement since this + is where type clashes between packages and hard to find bugs have + regularly manifested in the past. - Header files, especially those defining a "style", should only use the absolute minimum number of include files and **must not** contain @@ -54,16 +43,60 @@ Include files (varied) This also means any such file can assume that `FILE`, `NULL`, and `INT_MAX` are defined. -- Header files that define a new LAMMPS style (i.e. that have a - ``SomeStyle(some/name,SomeName);`` macro in them) should only use the - include file for the base class and otherwise use forward declarations - and pointers; when interfacing to a library use the PIMPL (pointer - to implementation) approach where you have a pointer to a struct - that contains all library specific data (and thus requires the library - header) but use a forward declaration and define the struct only in - the implementation file. This is a **strict** requirement since this - is where type clashes between packages and hard to find bugs have - regularly manifested in the past. +- System headers or from installed libraries are include with angular + brackets (example: ``#include ``), while local include file + use double quotes (example: ``#include "atom.h"``) + +- When including system header files from the C library use the + C++-style names (```` or ````) instead of the + C-style names (```` or ````) + +- The order of ``#include`` statements in a file ``some_name.cpp`` that + implements a class ``SomeName`` defined in a header file + ``some_name.h`` should be as follows: + + - ``#include "some_name.h"`` followed by an empty line + + - LAMMPS include files e.g. ``#include "comm.h"`` or ``#include + "modify.h"`` in alphabetical order followed by an empty line + + - System header files from the C++ or C standard library followed by + an empty line + + - ``using namespace LAMMPS_NS`` or other namespace imports. + + +Whitespace (preferred) +^^^^^^^^^^^^^^^^^^^^^^ + +Source files should not contain TAB characters unless required by the +syntax (e.g. in makefiles) and no trailing whitespace. Text files +should be added with Unix-style line endings (LF-only). Git will +automatically convert those in both directions when running on Windows; +use dos2unix on Linux machines to convert files. Text files should have +a line ending on the last line. + +You can check for these issues with the python scripts in the +:ref:`"tools/coding_standard" ` folder. When run +normally with a source file or a source folder as argument, they will +list all non-conforming lines. By adding the `-f` flag to the command +line, they will modify the flagged files to try removing the detected +issues. + + +Placement of braces (strongly preferred) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +For new files added to the "src" tree, a `clang-format +`_ configuration file is +provided under the name `.clang-format`. This file is compatible with +clang-format version 8 and later. With that file present, files can be +reformatted according to the configuration with a command like: +`clang-format -i new-file.cpp`. Ideally, this is done while writing the +code or before a pull request is submitted. Blocks of code where the +reformatting from clang-format yields undesirable output may be +protected with placing a pair `// clang-format off` and `// clang-format +on` comments around that block. Miscellaneous standards (varied) @@ -139,44 +172,3 @@ Miscellaneous standards (varied) and readable by all and no executable permissions. Executable permissions (0755) should only be on shell scripts or python or similar scripts for interpreted script languages. - -Whitespace (preferred) -^^^^^^^^^^^^^^^^^^^^^^ - -LAMMPS uses 2 characters per indentation level and lines should be -kept within 100 characters wide. - -Spacing before brackets, after commas, etc. - -Source files should not contain TAB characters unless required by the -syntax (e.g. in makefiles) and no trailing whitespace. Text files -should be added with Unix-style line endings (LF-only). Git will -automatically convert those in both directions when running on Windows; -use dos2unix on Linux machines to convert files. Text files should have -a line ending on the last line. - -You can check for these issues with the python scripts in the -:ref:`"tools/coding_standard" ` folder. When run -normally with a source file or a source folder as argument, they will -list all non-conforming lines. By adding the `-f` flag to the command -line, they will modify the flagged files to try removing the detected -issues. - - -Placement of braces (strongly preferred) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -On new lines for methods, when to use, etc. - -For new files added to the "src" tree, a `clang-format -`_ configuration file is -provided under the name `.clang-format`. This file is compatible with -clang-format version 8 and later. With that file present, files can be -reformatted according to the configuration with a command like: -`clang-format -i new-file.cpp`. Ideally, this is done while writing the -code or before a pull request is submitted. Blocks of code where the -reformatting from clang-format yields undesirable output may be -protected with placing a pair `// clang-format off` and `// clang-format -on` comments around that block. - - From b9161843dc1437e7c5ab468e0211abdbb4153cf8 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Fri, 5 May 2023 17:41:42 -0400 Subject: [PATCH 158/448] more robust variable error checks --- src/REAXFF/fix_reaxff_species.cpp | 16 +++++++++++++--- src/REAXFF/fix_reaxff_species.h | 1 + 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/REAXFF/fix_reaxff_species.cpp b/src/REAXFF/fix_reaxff_species.cpp index 725c1370d1..92bca99ae0 100644 --- a/src/REAXFF/fix_reaxff_species.cpp +++ b/src/REAXFF/fix_reaxff_species.cpp @@ -243,11 +243,12 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix reaxff/species delete_rate_limit", error); delete_Nlimit_varid = -1; if (strncmp(arg[iarg+1],"v_",2) == 0) { - delete_Nlimit_varid = input->variable->find(&arg[iarg+1][2]); + delete_Nlimit_varname = &arg[iarg+1][2]; + delete_Nlimit_varid = input->variable->find(delete_Nlimit_varname.c_str()); if (delete_Nlimit_varid < 0) - error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",&arg[iarg+1][2]); + error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",delete_Nlimit_varname); if (!input->variable->equalstyle(delete_Nlimit_varid)) - error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",&arg[iarg+1][2]); + error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",delete_Nlimit_varname); } else delete_Nlimit = utils::numeric(FLERR, arg[iarg+1], false, lmp); delete_Nsteps = utils::numeric(FLERR, arg[iarg+2], false, lmp); iarg += 3; @@ -387,6 +388,15 @@ void FixReaxFFSpecies::init() f_SPECBOND = dynamic_cast(modify->add_fix(fixcmd)); setupflag = 1; } + + // check for valid variable name for delete Nlimit keyword + if (delete_Nsteps > 0) { + delete_Nlimit_varid = input->variable->find(delete_Nlimit_varname.c_str()); + if (delete_Nlimit_varid < 0) + error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",delete_Nlimit_varname); + if (!input->variable->equalstyle(delete_Nlimit_varid)) + error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",delete_Nlimit_varname); + } } /* ---------------------------------------------------------------------- */ diff --git a/src/REAXFF/fix_reaxff_species.h b/src/REAXFF/fix_reaxff_species.h index c1a93d0584..27efa0f915 100644 --- a/src/REAXFF/fix_reaxff_species.h +++ b/src/REAXFF/fix_reaxff_species.h @@ -61,6 +61,7 @@ class FixReaxFFSpecies : public Fix { int eleflag, posflag, multipos, padflag, setupflag; int delflag, specieslistflag, masslimitflag; int delete_Nlimit, delete_Nlimit_varid; + std::string delete_Nlimit_varname; int delete_Nsteps, *delete_Tcount; double massmin, massmax; int singlepos_opened, multipos_opened, del_opened; From 806af5322e2493d8c4a8ca725c574805bf093d84 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 5 May 2023 19:08:02 -0600 Subject: [PATCH 159/448] Kokkos package optimizations --- src/KOKKOS/angle_cosine_kokkos.cpp | 22 +- src/KOKKOS/atom_kokkos.h | 16 +- src/KOKKOS/atom_map_kokkos.cpp | 346 ++++++++++++++++------------- src/KOKKOS/atom_vec_kokkos.cpp | 2 +- src/KOKKOS/bond_fene_kokkos.cpp | 60 +++-- src/KOKKOS/bond_fene_kokkos.h | 9 +- src/KOKKOS/comm_kokkos.cpp | 9 +- src/KOKKOS/fix_langevin_kokkos.cpp | 10 +- src/KOKKOS/fix_shake_kokkos.cpp | 3 + src/KOKKOS/kokkos_type.h | 51 +++++ src/KOKKOS/neigh_bond_kokkos.cpp | 128 +++-------- src/KOKKOS/neigh_bond_kokkos.h | 5 +- src/KOKKOS/pair_kokkos.h | 18 +- src/atom.h | 6 +- src/fix_langevin.cpp | 4 +- 15 files changed, 362 insertions(+), 327 deletions(-) diff --git a/src/KOKKOS/angle_cosine_kokkos.cpp b/src/KOKKOS/angle_cosine_kokkos.cpp index 24d1b5caea..189a156866 100644 --- a/src/KOKKOS/angle_cosine_kokkos.cpp +++ b/src/KOKKOS/angle_cosine_kokkos.cpp @@ -150,20 +150,26 @@ void AngleCosineKokkos::operator()(TagAngleCosineCompute::operator()(TagAngleCosineCompute KOKKOS_INLINE_FUNCTION static int map_kokkos(tagint global, int map_style, const DAT::tdual_int_1d &k_map_array, const dual_hash_type &k_map_hash) diff --git a/src/KOKKOS/atom_map_kokkos.cpp b/src/KOKKOS/atom_map_kokkos.cpp index f8cc5ab2c4..b30f0eabc0 100644 --- a/src/KOKKOS/atom_map_kokkos.cpp +++ b/src/KOKKOS/atom_map_kokkos.cpp @@ -21,6 +21,8 @@ #include "modify.h" #include "neighbor_kokkos.h" +#include + #include using namespace LAMMPS_NS; @@ -34,8 +36,6 @@ using namespace LAMMPS_NS; set entire array to -1 as initial values for hash option: map_nhash = length of hash table - map_nbucket = # of hash buckets, prime larger than map_nhash * 2 - so buckets will only be filled with 0 or 1 atoms on average ------------------------------------------------------------------------- */ void AtomKokkos::map_init(int check) @@ -58,15 +58,7 @@ void AtomKokkos::map_init(int check) // for hash, set all buckets to empty, put all entries in free list if (!recreate) { - if (map_style == MAP_ARRAY) { - for (int i = 0; i <= map_tag_max; i++) map_array[i] = -1; - } else { - for (int i = 0; i < map_nbucket; i++) map_bucket[i] = -1; - map_nused = 0; - map_free = 0; - for (int i = 0; i < map_nhash; i++) map_hash[i].next = i + 1; - if (map_nhash > 0) map_hash[map_nhash - 1].next = -1; - } + map_clear(); // recreating: delete old map and create new one for array or hash @@ -76,7 +68,8 @@ void AtomKokkos::map_init(int check) if (map_style == MAP_ARRAY) { map_maxarray = map_tag_max; memoryKK->create_kokkos(k_map_array, map_array, map_maxarray + 1, "atom:map_array"); - for (int i = 0; i <= map_tag_max; i++) map_array[i] = -1; + Kokkos::deep_copy(k_map_array.d_view,-1); + k_map_array.modify_device(); } else { @@ -90,35 +83,26 @@ void AtomKokkos::map_init(int check) map_nhash *= 2; map_nhash = MAX(map_nhash, 1000); - // map_nbucket = prime just larger than map_nhash - // next_prime() should be fast enough, - // about 10% of odd integers are prime above 1M - - map_nbucket = next_prime(map_nhash); - - // set all buckets to empty - // set hash to map_nhash in length - // put all hash entries in free list and point them to each other - - map_bucket = new int[map_nbucket]; - for (int i = 0; i < map_nbucket; i++) map_bucket[i] = -1; - - map_hash = new HashElem[map_nhash]; - map_nused = 0; - map_free = 0; - for (int i = 0; i < map_nhash; i++) map_hash[i].next = i + 1; - map_hash[map_nhash - 1].next = -1; - - // use "view" template method to avoid unnecessary deep_copy - - auto h_map_hash = k_map_hash.view(); // get type - h_map_hash = decltype(h_map_hash)(map_nhash); - k_map_hash.view() = h_map_hash; + k_map_hash = dual_hash_type(map_nhash); } } +} - k_sametag.modify_host(); - if (map_style == Atom::MAP_ARRAY) k_map_array.modify_host(); +/* ---------------------------------------------------------------------- + clear global -> local map for all of my own and ghost atoms + for hash table option: + global ID may not be in table if image atom was already cleared +------------------------------------------------------------------------- */ + +void AtomKokkos::map_clear() +{ + if (map_style == Atom::MAP_ARRAY) { + Kokkos::deep_copy(k_map_array.d_view,-1); + k_map_array.modify_device(); + } else { + k_map_hash.d_view.clear(); + k_map_hash.modify_device(); + } } /* ---------------------------------------------------------------------- @@ -135,28 +119,16 @@ void AtomKokkos::map_set() { int nall = nlocal + nghost; - atomKK->sync(Host, TAG_MASK); + // possible reallocation of sametag must come before loop over atoms + // since loop sets sametag - k_sametag.sync_host(); - if (map_style == Atom::MAP_ARRAY) k_map_array.sync_host(); + if (nall > max_same) { + max_same = nall + EXTRA; + memoryKK->destroy_kokkos(k_sametag, sametag); + memoryKK->create_kokkos(k_sametag, sametag, max_same, "atom:sametag"); + } - if (map_style == MAP_ARRAY) { - - // possible reallocation of sametag must come before loop over atoms - // since loop sets sametag - - if (nall > max_same) { - max_same = nall + EXTRA; - memoryKK->destroy_kokkos(k_sametag, sametag); - memoryKK->create_kokkos(k_sametag, sametag, max_same, "atom:sametag"); - } - - for (int i = nall - 1; i >= 0; i--) { - sametag[i] = map_array[tag[i]]; - map_array[tag[i]] = i; - } - - } else { + if (map_style == MAP_HASH) { // if this proc has more atoms than hash table size, call map_init() // call with 0 since max atomID in system has not changed @@ -164,109 +136,179 @@ void AtomKokkos::map_set() // b/c map_init() may invoke map_delete(), whacking sametag if (nall > map_nhash) map_init(0); - if (nall > max_same) { - max_same = nall + EXTRA; - memoryKK->destroy_kokkos(k_sametag, sametag); - memoryKK->create_kokkos(k_sametag, sametag, max_same, "atom:sametag"); - } - - int previous, ibucket, index; - tagint global; - - for (int i = nall - 1; i >= 0; i--) { - sametag[i] = map_find_hash(tag[i]); - - // search for key - // if found it, just overwrite local value with index - - previous = -1; - global = tag[i]; - ibucket = global % map_nbucket; - index = map_bucket[ibucket]; - while (index > -1) { - if (map_hash[index].global == global) break; - previous = index; - index = map_hash[index].next; - } - if (index > -1) { - map_hash[index].local = i; - continue; - } - - // take one entry from free list - // add the new global/local pair as entry at end of bucket list - // special logic if this entry is 1st in bucket - - index = map_free; - map_free = map_hash[map_free].next; - if (previous == -1) - map_bucket[ibucket] = index; - else - map_hash[previous].next = index; - map_hash[index].global = global; - map_hash[index].local = i; - map_hash[index].next = -1; - map_nused++; - } - - // Copy to Kokkos hash - - // use "view" template method to avoid unnecessary deep_copy - - auto h_map_hash = k_map_hash.view(); - h_map_hash.clear(); - - for (int i = nall - 1; i >= 0; i--) { - - // search for key - // if don't find it, done - - previous = -1; - global = tag[i]; - ibucket = global % map_nbucket; - index = map_bucket[ibucket]; - while (index > -1) { - if (map_hash[index].global == global) break; - previous = index; - index = map_hash[index].next; - } - if (index == -1) continue; - - int local = map_hash[index].local; - - auto insert_result = h_map_hash.insert(global, local); - if (insert_result.failed()) error->one(FLERR, "Kokkos::UnorderedMap insertion failed"); - } } - k_sametag.modify_host(); - if (map_style == Atom::MAP_ARRAY) - k_map_array.modify_host(); - else if (map_style == Atom::MAP_HASH) { + atomKK->sync(Device, TAG_MASK); - // use "view" template method to avoid unnecessary deep_copy + auto d_tag = atomKK->k_tag.d_view; + auto d_sametag = k_sametag.d_view; - auto h_map_hash = k_map_hash.view(); - auto d_map_hash = k_map_hash.view(); + // sort by tag - // check if fix shake or neigh bond needs a device hash + auto d_tag_sorted = DAT::t_tagint_1d(Kokkos::NoInit("atom:tag_sorted"),nall); + auto d_i_sorted = DAT::t_int_1d(Kokkos::NoInit("atom:i_sorted"),nall); - int device_hash_flag = 0; + typedef Kokkos::DualView tdual_tagint_2; + typedef tdual_tagint_2::t_dev t_tagint_2; + typedef tdual_tagint_2::t_host t_host_tagint_2; - auto neighborKK = (NeighborKokkos *) neighbor; - if (neighborKK->device_flag) device_hash_flag = 1; + auto d_tag_min_max = t_tagint_2(Kokkos::NoInit("atom:tag_min_max")); + auto h_tag_min_max = t_host_tagint_2(Kokkos::NoInit("atom:tag_min_max")); - for (int n = 0; n < modify->nfix; n++) - if (utils::strmatch(modify->fix[n]->style, "^shake")) - if (modify->fix[n]->execution_space == Device) device_hash_flag = 1; + auto d_tag_min = Kokkos::subview(d_tag_min_max,0); + auto d_tag_max = Kokkos::subview(d_tag_min_max,1); - if (device_hash_flag) { - Kokkos::deep_copy(d_map_hash, h_map_hash); - k_map_hash.view() = d_map_hash; + auto h_tag_min = Kokkos::subview(h_tag_min_max,0); + auto h_tag_max = Kokkos::subview(h_tag_min_max,1); + + h_tag_min() = MAXTAGINT; + h_tag_max() = 0; + + Kokkos::deep_copy(d_tag_min_max,h_tag_min_max); + + Kokkos::parallel_for(nall, LAMMPS_LAMBDA(int i) { + d_i_sorted(i) = i; + tagint tag_i = d_tag(i); + d_tag_sorted(i) = tag_i; + Kokkos::atomic_min(&d_tag_min(),tag_i); + Kokkos::atomic_max(&d_tag_max(),tag_i); + }); + + Kokkos::deep_copy(h_tag_min_max,d_tag_min_max); + + tagint min = h_tag_min(); + tagint max = h_tag_max(); + + using KeyViewType = decltype(d_tag_sorted); + using BinOp = Kokkos::BinOp1D; + + BinOp binner(nall, min, max); + + Kokkos::BinSort Sorter(d_tag_sorted, 0, nall, binner, true); + Sorter.create_permute_vector(LMPDeviceType()); + Sorter.sort(LMPDeviceType(), d_tag_sorted, 0, nall); + Sorter.sort(LMPDeviceType(), d_i_sorted, 0, nall); + + auto d_map_array = k_map_array.d_view; + auto d_map_hash = k_map_hash.d_view; + d_map_hash.clear(); + + auto d_error_flag = k_error_flag.d_view; + Kokkos::deep_copy(d_error_flag,0); + + // for each tag find: + // neighboring atoms with closest local id for sametag + // atom with smallest local id for atom map + + Kokkos::parallel_for(nall, LAMMPS_LAMBDA(int ii) { + const int i = d_i_sorted(ii); + const tagint tag_i = d_tag_sorted(ii); + + int i_min = i; + int i_closest = MAXTAGINT; + + // search atoms with same tag in the forward direction + + int jj = ii+1; + int closest_flag = 0; + + while (jj < nall) { + const tagint tag_j = d_tag_sorted(jj); + if (tag_j != tag_i) break; + const int j = d_i_sorted(jj); + i_min = MIN(i_min,j); + if (j > i) { + i_closest = MIN(i_closest,j); + closest_flag = 1; + } + jj++; } + + // search atoms with same tag in the reverse direction + + jj = ii-1; + + while (jj >= 0) { + const tagint tag_j = d_tag_sorted(jj); + if (tag_j != tag_i) break; + const int j = d_i_sorted(jj); + i_min = MIN(i_min,j); + if (j > i) { + i_closest = MIN(i_closest,j); + closest_flag = 1; + } + jj--; + } + + if (!closest_flag) + i_closest = -1; + + d_sametag(i) = i_closest; + + if (i == i_min) { + if (map_style == MAP_ARRAY) + d_map_array(tag_i) = i_min; + else { + auto insert_result = d_map_hash.insert(tag_i, i_min); + if (insert_result.failed()) d_error_flag() = 1; + } + } + + }); + + auto h_error_flag = Kokkos::create_mirror_view_and_copy(LMPHostType(),d_error_flag); + if (h_error_flag()) + error->one(FLERR,"Failed to insert into Kokkos hash atom map"); + + k_sametag.modify_device(); + + if (map_style == MAP_ARRAY) + k_map_array.modify_device(); + else + k_map_hash.modify_device(); +} + +/* ---------------------------------------------------------------------- + set global to local map for one atom + for hash table option: + global ID may already be in table if atom was already set + called by Special class +------------------------------------------------------------------------- */ + +void AtomKokkos::map_one(tagint global, int local) +{ + if (map_style == MAP_ARRAY) { + k_map_array.sync_host(); + k_map_array.h_view[global] = local; + } else { + k_map_hash.sync_host(); + auto& h_map_hash = k_map_hash.h_view; + + auto insert_result = h_map_hash.insert(global, local); + if (insert_result.existing()) + h_map_hash.value_at(h_map_hash.find(global)) = local; + else if (insert_result.failed()) + error->one(FLERR,"Failed to insert into Kokkos hash atom map"); } } +/* ---------------------------------------------------------------------- + lookup global ID in hash table, return local index + called by map() in atom.h +------------------------------------------------------------------------- */ + +int AtomKokkos::map_find_hash(tagint global) +{ + k_map_hash.sync_host(); + auto& h_map_hash = k_map_hash.h_view; + + int local = -1; + auto index = h_map_hash.find(global); + if (h_map_hash.valid_at(index)) + local = h_map_hash.value_at(index); + return local; +} + /* ---------------------------------------------------------------------- free the array or hash table for global to local mapping ------------------------------------------------------------------------- */ @@ -279,10 +321,6 @@ void AtomKokkos::map_delete() if (map_style == MAP_ARRAY) { memoryKK->destroy_kokkos(k_map_array, map_array); map_array = nullptr; - } else { - k_map_hash.h_view = host_hash_type(); - k_map_hash.d_view = hash_type(); - } - - Atom::map_delete(); + } else + k_map_hash = dual_hash_type(); } diff --git a/src/KOKKOS/atom_vec_kokkos.cpp b/src/KOKKOS/atom_vec_kokkos.cpp index b23222e684..93393e9e09 100644 --- a/src/KOKKOS/atom_vec_kokkos.cpp +++ b/src/KOKKOS/atom_vec_kokkos.cpp @@ -35,7 +35,7 @@ AtomVecKokkos::AtomVecKokkos(LAMMPS *lmp) : AtomVec(lmp) unpack_exchange_indices_flag = 0; size_exchange = 0; - k_count = DAT::tdual_int_1d("atom::k_count",1); + k_count = DAT::tdual_int_1d("atom:k_count",1); atomKK = (AtomKokkos *) atom; commKK = (CommKokkos *) comm; } diff --git a/src/KOKKOS/bond_fene_kokkos.cpp b/src/KOKKOS/bond_fene_kokkos.cpp index 0a294bde36..a6bbb1edde 100644 --- a/src/KOKKOS/bond_fene_kokkos.cpp +++ b/src/KOKKOS/bond_fene_kokkos.cpp @@ -43,13 +43,8 @@ BondFENEKokkos::BondFENEKokkos(LAMMPS *lmp) : BondFENE(lmp) datamask_read = X_MASK | F_MASK | ENERGY_MASK | VIRIAL_MASK; datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; - k_warning_flag = DAT::tdual_int_scalar("Bond:warning_flag"); - d_warning_flag = k_warning_flag.view(); - h_warning_flag = k_warning_flag.h_view; - - k_error_flag = DAT::tdual_int_scalar("Bond:error_flag"); - d_error_flag = k_error_flag.view(); - h_error_flag = k_error_flag.h_view; + d_flag = typename AT::t_int_scalar("bond:flag"); + h_flag = HAT::t_int_scalar("bond:flag_mirror"); } /* ---------------------------------------------------------------------- */ @@ -99,13 +94,7 @@ void BondFENEKokkos::compute(int eflag_in, int vflag_in) nlocal = atom->nlocal; newton_bond = force->newton_bond; - h_warning_flag() = 0; - k_warning_flag.template modify(); - k_warning_flag.template sync(); - - h_error_flag() = 0; - k_error_flag.template modify(); - k_error_flag.template sync(); + Kokkos::deep_copy(d_flag,0); copymode = 1; @@ -127,14 +116,11 @@ void BondFENEKokkos::compute(int eflag_in, int vflag_in) } } - k_warning_flag.template modify(); - k_warning_flag.template sync(); - if (h_warning_flag()) - error->warning(FLERR,"FENE bond too long"); + Kokkos::deep_copy(h_flag,d_flag); - k_error_flag.template modify(); - k_error_flag.template sync(); - if (h_error_flag()) + if (h_flag() == 1) + error->warning(FLERR,"FENE bond too long"); + else if (h_flag() == 2) error->one(FLERR,"Bad FENE bond"); if (eflag_global) energy += ev.evdwl; @@ -165,8 +151,6 @@ template KOKKOS_INLINE_FUNCTION void BondFENEKokkos::operator()(TagBondFENECompute, const int &n, EV_FLOAT& ev) const { - if (d_error_flag()) return; - // The f array is atomic Kokkos::View::value,Kokkos::MemoryTraits > a_f = f; @@ -178,10 +162,15 @@ void BondFENEKokkos::operator()(TagBondFENECompute r0, then rlogarg < 0.0 which is an error @@ -189,31 +178,32 @@ void BondFENEKokkos::operator()(TagBondFENECompute 2*r0 something serious is wrong, abort if (rlogarg < 0.1) { - if (!d_warning_flag()) - d_warning_flag() = 1; - if (rlogarg <= -3.0 && !d_error_flag()) - d_error_flag() = 1; + if (rlogarg <= -3.0) + d_flag() = 2; + else + d_flag() = 1; rlogarg = 0.1; } - F_FLOAT fbond = -d_k[type]/rlogarg; + F_FLOAT fbond = -k/rlogarg; // force from LJ term F_FLOAT sr6 = 0.0; - if (rsq < MY_CUBEROOT2*d_sigma[type]*d_sigma[type]) { - const F_FLOAT sr2 = d_sigma[type]*d_sigma[type]/rsq; + F_FLOAT sigma2 = sigma*sigma; + if (rsq < MY_CUBEROOT2*sigma2) { + const F_FLOAT sr2 = sigma2/rsq; sr6 = sr2*sr2*sr2; - fbond += 48.0*d_epsilon[type]*sr6*(sr6-0.5)/rsq; + fbond += 48.0*epsilon*sr6*(sr6-0.5)/rsq; } // energy F_FLOAT ebond = 0.0; if (eflag) { - ebond = -0.5 * d_k[type]*r0sq*log(rlogarg); - if (rsq < MY_CUBEROOT2*d_sigma[type]*d_sigma[type]) - ebond += 4.0*d_epsilon[type]*sr6*(sr6-1.0) + d_epsilon[type]; + ebond = -0.5 * k*r0sq*log(rlogarg); + if (rsq < MY_CUBEROOT2*sigma2) + ebond += 4.0*epsilon*sr6*(sr6-1.0) + epsilon; } // apply force to each of 2 atoms diff --git a/src/KOKKOS/bond_fene_kokkos.h b/src/KOKKOS/bond_fene_kokkos.h index e2ba64a114..18f8d87b6a 100644 --- a/src/KOKKOS/bond_fene_kokkos.h +++ b/src/KOKKOS/bond_fene_kokkos.h @@ -71,13 +71,8 @@ class BondFENEKokkos : public BondFENE { typename ArrayTypes::t_efloat_1d d_eatom; typename ArrayTypes::t_virial_array d_vatom; - DAT::tdual_int_scalar k_warning_flag; - typename AT::t_int_scalar d_warning_flag; - HAT::t_int_scalar h_warning_flag; - - DAT::tdual_int_scalar k_error_flag; - typename AT::t_int_scalar d_error_flag; - HAT::t_int_scalar h_error_flag; + typename AT::t_int_scalar d_flag; + HAT::t_int_scalar h_flag; int nlocal,newton_bond; int eflag,vflag; diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 3687216bf9..7d007a666c 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -729,13 +729,8 @@ void CommKokkos::exchange_device() double lo,hi; MPI_Request request; - // clear global->local map for owned and ghost atoms - // b/c atoms migrate to new procs in exchange() and - // new ghosts are created in borders() - // map_set() is done at end of borders() // clear ghost count and any ghost bonus data internal to AtomVec - if (map_style != Atom::MAP_NONE) atom->map_clear(); atom->nghost = 0; atom->avec->clear_bonus(); @@ -1275,10 +1270,8 @@ void CommKokkos::borders_device() { // reset global->local map - if (map_style != Atom::MAP_NONE) { - atomKK->sync(Host,TAG_MASK); + if (map_style != Atom::MAP_NONE) atom->map_set(); - } } /* ---------------------------------------------------------------------- diff --git a/src/KOKKOS/fix_langevin_kokkos.cpp b/src/KOKKOS/fix_langevin_kokkos.cpp index 4d7a3e8820..437dd9daef 100644 --- a/src/KOKKOS/fix_langevin_kokkos.cpp +++ b/src/KOKKOS/fix_langevin_kokkos.cpp @@ -684,8 +684,6 @@ void FixLangevinKokkos::zero_force_item(int i) const template void FixLangevinKokkos::compute_target() { - atomKK->sync(Host, MASK_MASK); - mask = atomKK->k_mask.template view(); int nlocal = atomKK->nlocal; double delta = update->ntimestep - update->beginstep; @@ -710,12 +708,14 @@ void FixLangevinKokkos::compute_target() memoryKK->destroy_kokkos(k_tforce,tforce); memoryKK->create_kokkos(k_tforce,tforce,maxatom2,"langevin:tforce"); d_tforce = k_tforce.template view(); - h_tforce = k_tforce.template view(); + h_tforce = k_tforce.h_view; } input->variable->compute_atom(tvar,igroup,tforce,1,0); // tforce is modified on host - k_tforce.template modify(); + k_tforce.modify_host(); + atomKK->sync(Host, MASK_MASK); + auto h_mask = atomKK->k_mask.h_view; for (int i = 0; i < nlocal; i++) - if (mask[i] & groupbit) + if (h_mask[i] & groupbit) if (h_tforce[i] < 0.0) error->one(FLERR, "Fix langevin variable returned negative temperature"); diff --git a/src/KOKKOS/fix_shake_kokkos.cpp b/src/KOKKOS/fix_shake_kokkos.cpp index 1ea3ed1c5a..3e88860622 100644 --- a/src/KOKKOS/fix_shake_kokkos.cpp +++ b/src/KOKKOS/fix_shake_kokkos.cpp @@ -221,6 +221,7 @@ void FixShakeKokkos::pre_neighbor() k_map_array.template sync(); } else if (map_style == Atom::MAP_HASH) { k_map_hash = atomKK->k_map_hash; + k_map_hash.template sync(); } k_shake_flag.sync(); @@ -248,6 +249,7 @@ void FixShakeKokkos::pre_neighbor() k_map_array.template sync(); } else if (map_style == Atom::MAP_HASH) { k_map_hash = atomKK->k_map_hash; + k_map_hash.template sync(); } atomKK->k_sametag.sync(); @@ -357,6 +359,7 @@ void FixShakeKokkos::post_force(int vflag) k_map_array.template sync(); } else if (map_style == Atom::MAP_HASH) { k_map_hash = atomKK->k_map_hash; + k_map_hash.template sync(); } if (d_rmass.data()) diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index 555c7fa9ae..f8d2b4947a 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -570,6 +570,21 @@ struct dual_hash_type { hash_type d_view; host_hash_type h_view; + bool modified_device; + bool modified_host; + + dual_hash_type() { + modified_device = modified_host = false; + d_view = hash_type(); + h_view = host_hash_type(); + } + + dual_hash_type(int capacity) { + modified_device = modified_host = false; + d_view = hash_type(capacity); + h_view = host_hash_type(capacity); + } + template std::enable_if_t<(std::is_same::value || Kokkos::SpaceAccessibility::accessible),hash_type&> view() {return d_view;} @@ -584,6 +599,42 @@ struct dual_hash_type { KOKKOS_INLINE_FUNCTION std::enable_if_t::value || Kokkos::SpaceAccessibility::accessible),const host_hash_type&> const_view() const {return h_view;} + void modify_device() + { + modified_device = true; + if (modified_device && modified_host) + Kokkos::abort("Concurrent modification of host and device hashes"); + } + + void modify_host() + { + modified_host = true; + if (modified_device && modified_host) + Kokkos::abort("Concurrent modification of host and device hashes"); + } + + void sync_device() + { + if (modified_host) { + Kokkos::deep_copy(d_view,h_view); + modified_host = false; + } + } + + void sync_host() + { + if (modified_device) { + Kokkos::deep_copy(h_view,d_view); + modified_device = false; + } + } + + template + std::enable_if_t<(std::is_same::value || Kokkos::SpaceAccessibility::accessible),void> sync() {sync_device();} + + template + std::enable_if_t::value || Kokkos::SpaceAccessibility::accessible),void> sync() {sync_host();} + }; template diff --git a/src/KOKKOS/neigh_bond_kokkos.cpp b/src/KOKKOS/neigh_bond_kokkos.cpp index 5a250b6d23..9067284426 100644 --- a/src/KOKKOS/neigh_bond_kokkos.cpp +++ b/src/KOKKOS/neigh_bond_kokkos.cpp @@ -50,13 +50,16 @@ NeighBondKokkos::NeighBondKokkos(LAMMPS *lmp) : Pointers(lmp) datamask_read = EMPTY_MASK; datamask_modify = EMPTY_MASK; - k_nlist = DAT::tdual_int_scalar("NeighBond:nlist"); - d_nlist = k_nlist.view(); - h_nlist = k_nlist.h_view; + // use 1D view for scalars to reduce GPU memory operations - k_fail_flag = DAT::tdual_int_scalar("NeighBond:fail_flag"); - d_fail_flag = k_fail_flag.view(); - h_fail_flag = k_fail_flag.h_view; + d_scalars = typename AT::t_int_1d("NeighBond:scalars",2); + h_scalars = HAT::t_int_1d("NeighBond:scalars_mirror",2); + + d_nlist = Kokkos::subview(d_scalars,0); + d_fail_flag = Kokkos::subview(d_scalars,1); + + h_nlist = Kokkos::subview(h_scalars,0); + h_fail_flag = Kokkos::subview(h_scalars,1); maxbond = 0; maxangle = 0; @@ -240,22 +243,14 @@ void NeighBondKokkos::bond_all() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->nbondlist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maxbond = neighbor->nbondlist + BONDDELTA; memoryKK->grow_kokkos(k_bondlist,neighbor->bondlist,maxbond,3,"neighbor:neighbor->bondlist"); @@ -327,22 +322,14 @@ void NeighBondKokkos::bond_partial() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->nbondlist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maxbond = neighbor->nbondlist + BONDDELTA; memoryKK->grow_kokkos(k_bondlist,neighbor->bondlist,maxbond,3,"neighbor:neighbor->bondlist"); @@ -440,22 +427,14 @@ void NeighBondKokkos::angle_all() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->nanglelist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maxangle = neighbor->nanglelist + BONDDELTA; memoryKK->grow_kokkos(k_anglelist,neighbor->anglelist,maxangle,4,"neighbor:neighbor->anglelist"); @@ -534,22 +513,14 @@ void NeighBondKokkos::angle_partial() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->nanglelist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maxangle = neighbor->nanglelist + BONDDELTA; memoryKK->grow_kokkos(k_anglelist,neighbor->anglelist,maxangle,4,"neighbor:neighbor->anglelist"); @@ -667,22 +638,14 @@ void NeighBondKokkos::dihedral_all() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->ndihedrallist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maxdihedral = neighbor->ndihedrallist + BONDDELTA; memoryKK->grow_kokkos(k_dihedrallist,neighbor->dihedrallist,maxdihedral,5,"neighbor:neighbor->dihedrallist"); @@ -766,22 +729,14 @@ void NeighBondKokkos::dihedral_partial() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->ndihedrallist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maxdihedral = neighbor->ndihedrallist + BONDDELTA; memoryKK->grow_kokkos(k_dihedrallist,neighbor->dihedrallist,maxdihedral,5,"neighbor:neighbor->dihedrallist"); @@ -921,22 +876,14 @@ void NeighBondKokkos::improper_all() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->nimproperlist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maximproper = neighbor->nimproperlist + BONDDELTA; memoryKK->grow_kokkos(k_improperlist,neighbor->improperlist,maximproper,5,"neighbor:neighbor->improperlist"); @@ -1020,22 +967,14 @@ void NeighBondKokkos::improper_partial() do { nmissing = 0; - h_nlist() = 0; - k_nlist.template modify(); - k_nlist.template sync(); - - h_fail_flag() = 0; - k_fail_flag.template modify(); - k_fail_flag.template sync(); + Kokkos::deep_copy(d_scalars,0); Kokkos::parallel_reduce(Kokkos::RangePolicy(0,nlocal),*this,nmissing); - k_nlist.template modify(); - k_nlist.template sync(); + Kokkos::deep_copy(h_scalars,d_scalars); + neighbor->nimproperlist = h_nlist(); - k_fail_flag.template modify(); - k_fail_flag.template sync(); if (h_fail_flag()) { maximproper = neighbor->nimproperlist + BONDDELTA; memoryKK->grow_kokkos(k_improperlist,neighbor->improperlist,maximproper,5,"neighbor:neighbor->improperlist"); @@ -1221,6 +1160,7 @@ void NeighBondKokkos::update_class_variables() k_map_array.template sync(); } else if (map_style == Atom::MAP_HASH) { k_map_hash = atomKK->k_map_hash; + k_map_hash.template sync(); } } diff --git a/src/KOKKOS/neigh_bond_kokkos.h b/src/KOKKOS/neigh_bond_kokkos.h index e4be1aeee3..480726c602 100644 --- a/src/KOKKOS/neigh_bond_kokkos.h +++ b/src/KOKKOS/neigh_bond_kokkos.h @@ -115,11 +115,10 @@ class NeighBondKokkos : protected Pointers { typename AT::t_tagint_2d improper_atom1,improper_atom2, improper_atom3,improper_atom4; - DAT::tdual_int_scalar k_nlist; + typename AT::t_int_1d d_scalars; + HAT::t_int_1d h_scalars; typename AT::t_int_scalar d_nlist; HAT::t_int_scalar h_nlist; - - DAT::tdual_int_scalar k_fail_flag; typename AT::t_int_scalar d_fail_flag; HAT::t_int_scalar h_fail_flag; diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index c244d6a8f9..f6925a376d 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -137,6 +137,12 @@ struct PairComputeFunctor { F_FLOAT fytmp = 0.0; F_FLOAT fztmp = 0.0; + if (NEIGHFLAG == FULL) { + f(i,0) = 0.0; + f(i,1) = 0.0; + f(i,2) = 0.0; + } + for (int jj = 0; jj < jnum; jj++) { int j = neighbors_i(jj); const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; @@ -205,6 +211,12 @@ struct PairComputeFunctor { F_FLOAT fytmp = 0.0; F_FLOAT fztmp = 0.0; + if (NEIGHFLAG == FULL) { + f(i,0) = 0.0; + f(i,1) = 0.0; + f(i,2) = 0.0; + } + for (int jj = 0; jj < jnum; jj++) { int j = neighbors_i(jj); const F_FLOAT factor_lj = c.special_lj[sbmask(j)]; @@ -767,7 +779,6 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename std::enable_if<(NEIG fpair->lmp->kokkos->neigh_thread = 1; if (fpair->lmp->kokkos->neigh_thread) { - fpair->fuse_force_clear_flag = 1; int vector_length = 8; int atoms_per_team = 32; @@ -805,6 +816,7 @@ template EV_FLOAT pair_compute (PairStyle* fpair, NeighListKokkos* list) { EV_FLOAT ev; if (fpair->neighflag == FULL) { + fpair->fuse_force_clear_flag = 1; ev = pair_compute_neighlist (fpair,list); } else if (fpair->neighflag == HALFTHREAD) { ev = pair_compute_neighlist (fpair,list); @@ -860,11 +872,7 @@ void pair_virial_fdotr_compute(PairStyle* fpair) { fpair->virial[5] = virial.v[5]; } - - - } #endif #endif - diff --git a/src/atom.h b/src/atom.h index 810a2829ed..c8a8533e33 100644 --- a/src/atom.h +++ b/src/atom.h @@ -385,7 +385,7 @@ class Atom : protected Pointers { // map lookup function inlined for efficiency // return -1 if no map defined - inline int map(tagint global) + virtual inline int map(tagint global) { if (map_style == 1) return map_array[global]; @@ -398,10 +398,10 @@ class Atom : protected Pointers { virtual void map_init(int check = 1); virtual void map_clear(); virtual void map_set(); - void map_one(tagint, int); + virtual void map_one(tagint, int); int map_style_set(); virtual void map_delete(); - int map_find_hash(tagint); + virtual int map_find_hash(tagint); protected: // global to local ID mapping diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp index adfa651147..0e083ce012 100644 --- a/src/fix_langevin.cpp +++ b/src/fix_langevin.cpp @@ -215,7 +215,7 @@ int FixLangevin::setmask() if (gjfflag) mask |= INITIAL_INTEGRATE; mask |= POST_FORCE; mask |= POST_FORCE_RESPA; - mask |= END_OF_STEP; + if (tallyflag || gjfflag) mask |= END_OF_STEP; return mask; } @@ -915,8 +915,6 @@ void FixLangevin::angmom_thermostat() void FixLangevin::end_of_step() { - if (!tallyflag && !gjfflag) return; - double **v = atom->v; int *mask = atom->mask; int nlocal = atom->nlocal; From 6074303f4abcbf877b017b654c8f0ef15f6e78b0 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 5 May 2023 19:13:49 -0600 Subject: [PATCH 160/448] whitespace --- src/KOKKOS/atom_map_kokkos.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/atom_map_kokkos.cpp b/src/KOKKOS/atom_map_kokkos.cpp index b30f0eabc0..5a91b34f94 100644 --- a/src/KOKKOS/atom_map_kokkos.cpp +++ b/src/KOKKOS/atom_map_kokkos.cpp @@ -194,7 +194,7 @@ void AtomKokkos::map_set() d_map_hash.clear(); auto d_error_flag = k_error_flag.d_view; - Kokkos::deep_copy(d_error_flag,0); + Kokkos::deep_copy(d_error_flag,0); // for each tag find: // neighboring atoms with closest local id for sametag @@ -253,7 +253,7 @@ void AtomKokkos::map_set() if (insert_result.failed()) d_error_flag() = 1; } } - + }); auto h_error_flag = Kokkos::create_mirror_view_and_copy(LMPHostType(),d_error_flag); @@ -262,7 +262,7 @@ void AtomKokkos::map_set() k_sametag.modify_device(); - if (map_style == MAP_ARRAY) + if (map_style == MAP_ARRAY) k_map_array.modify_device(); else k_map_hash.modify_device(); From d8584bb15a98aba97846b97aef1b10925dfe1b96 Mon Sep 17 00:00:00 2001 From: ilia Nikiforov Date: Sat, 6 May 2023 16:31:30 -0500 Subject: [PATCH 161/448] Hacky first pass at kim scaling --- src/KIM/pair_kim.cpp | 61 ++++++++++++++++++++++++++++++++++++++++++++ src/KIM/pair_kim.h | 3 +++ 2 files changed, 64 insertions(+) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 14564162e2..26996091dc 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -138,6 +138,9 @@ PairKIM::PairKIM(LAMMPS *lmp) : kim_init_ok = false; kim_particle_codes_ok = false; + // scale parameter + scale = nullptr; + if (lmp->citeme) lmp->citeme->add(cite_openkim); } @@ -177,6 +180,7 @@ PairKIM::~PairKIM() memory->destroy(cutsq); delete[] lmps_map_species_to_unique; lmps_map_species_to_unique = nullptr; + memory->destroy(scale); } // clean up neighborlist pointers @@ -271,6 +275,49 @@ void PairKIM::compute(int eflag, int vflag) vatom[i][5] = -tmp; } } + + // sloppy hack for scale + for (int i = 1; i < atom->ntypes+1; i++) + { + for (int j = 1; j < atom->ntypes+1; j++) + { + // comparing equality between floats, bad bad + if (scale[i][j] != scale[1][1]) + { + error->all(FLERR,"Different scaling factors between different species pairs not supported"); + } + } + } + double scale_all = scale[1][1]; + if (eflag_global != 0) + { + eng_vdwl *= scale_all; + } + if (vflag_global != 0) + { + for (int i = 0; i < 6; i++) + { + virial[i] *= scale_all; + } + } + for (int i = 0; i < nall; i++) + { + if (eflag_atom != 0) + { + eatom[i] *= scale_all; + } + if (vflag_atom != 0) + { + for (int j = 0; j < 6; j++) + { + vatom[i][j] *= scale_all; + } + } + for (int j = 0; j < 3; j++) + { + atom->f[i][j] *= scale_all; + } + } } /* ---------------------------------------------------------------------- @@ -289,6 +336,8 @@ void PairKIM::allocate() memory->create(cutsq,n+1,n+1,"pair:cutsq"); + memory->create(scale,n+1,n+1,"pair:scale"); + // allocate mapping array lmps_map_species_to_unique = new int[n+1]; @@ -392,6 +441,7 @@ void PairKIM::coeff(int narg, char **arg) setflag[i][j] = 1; count++; } + scale[i][j] = 1.0; } } @@ -610,6 +660,9 @@ double PairKIM::init_one(int i, int j) // "run ...", "minimize ...", etc. read from input if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); + //no need to initialize scale[i][j] = 1 if setflag==0, because that + //raises an error anyway + scale[j][i] = scale[i][j]; return kim_global_influence_distance; } @@ -1135,3 +1188,11 @@ void PairKIM::set_kim_model_has_flags() KIM_Model *PairKIM::get_kim_model() { return pkim; } std::string PairKIM::get_atom_type_list() { return atom_type_list; } + +void *PairKIM::extract(const char *str, int &dim) +{ + dim = 2; + if (strcmp(str,"scale") == 0) return (void *) scale; + + return nullptr; +} diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 90adb863e2..4ce302e1a9 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -84,6 +84,7 @@ class PairKIM : public Pair { void init_style() override; void init_list(int id, NeighList *ptr) override; double init_one(int, int) override; + void *extract(const char *, int &) override; int pack_reverse_comm(int, int, double *) override; void unpack_reverse_comm(int, int *, double *) override; double memory_usage() override; @@ -100,6 +101,8 @@ class PairKIM : public Pair { int settings_call_count; int init_style_call_count; + double **scale; + // values set in settings() char *kim_modelname; From b1d0f4afabc8fb7b4c28e03a693e28f77e699ce5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 5 May 2023 14:08:47 -0400 Subject: [PATCH 162/448] correct timer time output format for timeouts > 24 hours --- src/timer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/timer.cpp b/src/timer.cpp index f97449e797..409135cbaf 100644 --- a/src/timer.cpp +++ b/src/timer.cpp @@ -249,8 +249,8 @@ void Timer::modify_params(int narg, char **arg) // format timeout setting std::string timeout = "off"; if (_timeout >= 0) { - std::time_t tv = _timeout; - timeout = fmt::format("{:%H:%M:%S}", fmt::gmtime(tv)); + std::tm tv = fmt::gmtime((std::time_t) _timeout); + timeout = fmt::format("{:02d}:{:%M:%S}", tv.tm_yday * 24 + tv.tm_hour, tv); } utils::logmesg(lmp, "New timer settings: style={} mode={} timeout={}\n", timer_style[_level], From 7b46f150688a86fbf7907bd3544134cb2876b597 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 6 May 2023 05:37:15 -0400 Subject: [PATCH 163/448] use macOS consistently (missed a few places in the last round) --- doc/src/Build_make.rst | 4 ++-- doc/src/Install_conda.rst | 12 ++++++------ doc/src/Install_mac.rst | 21 +++++++++++---------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/doc/src/Build_make.rst b/doc/src/Build_make.rst index f1e34bbc55..f6764100e0 100644 --- a/doc/src/Build_make.rst +++ b/doc/src/Build_make.rst @@ -117,8 +117,8 @@ their settings may become outdated, too: .. code-block:: bash - make mac # build serial LAMMPS on a Mac - make mac_mpi # build parallel LAMMPS on a Mac + make mac # build serial LAMMPS on macOS + make mac_mpi # build parallel LAMMPS on macOS make intel_cpu # build with the INTEL package optimized for CPUs make knl # build with the INTEL package optimized for KNLs make opt # build with the OPT package optimized for CPUs diff --git a/doc/src/Install_conda.rst b/doc/src/Install_conda.rst index 5140e4e17d..a1a7213609 100644 --- a/doc/src/Install_conda.rst +++ b/doc/src/Install_conda.rst @@ -1,13 +1,13 @@ -Download an executable for Linux or Mac via Conda -------------------------------------------------- +Download an executable for Linux or macOS via Conda +--------------------------------------------------- Pre-compiled LAMMPS binaries are available for macOS and Linux via the `Conda `_ package management system. -First, one must set up the Conda package manager on your system. Follow the -instructions to install `Miniconda `_, then create a conda -environment (named `my-lammps-env` or whatever you prefer) for your LAMMPS -install: +First, one must set up the Conda package manager on your system. Follow +the instructions to install `Miniconda `_, then +create a conda environment (named `my-lammps-env` or whatever you +prefer) for your LAMMPS install: .. code-block:: bash diff --git a/doc/src/Install_mac.rst b/doc/src/Install_mac.rst index 8228b5a4e5..880ddca7a2 100644 --- a/doc/src/Install_mac.rst +++ b/doc/src/Install_mac.rst @@ -1,12 +1,12 @@ -Download an executable for Mac ------------------------------- +Download an executable for macOS +-------------------------------- -LAMMPS can be downloaded, built, and configured for OS X on a Mac with -`Homebrew `_. (Alternatively, see the installation -instructions for :doc:`downloading an executable via Conda -`.) The following LAMMPS packages are unavailable at -this time because of additional requirements not yet met: GPU, KOKKOS, -MSCG, MPIIO, POEMS, VORONOI. +LAMMPS can be downloaded, built, and configured for macOS with `Homebrew +`_. (Alternatively, see the installation instructions for +:doc:`downloading an executable via Conda `.) The +following LAMMPS packages are unavailable at this time because of +additional requirements not yet met: GPU, KOKKOS, MSCG, MPIIO, POEMS, +VORONOI. After installing Homebrew, you can install LAMMPS on your system with the following commands: @@ -15,8 +15,9 @@ the following commands: brew install lammps -This will install the executables "lammps_serial" and "lammps_mpi", as well as -the LAMMPS "doc", "potentials", "tools", "bench", and "examples" directories. +This will install the executables "lammps_serial" and "lammps_mpi", as +well as the LAMMPS "doc", "potentials", "tools", "bench", and "examples" +directories. Once LAMMPS is installed, you can test the installation with the Lennard-Jones benchmark file: From 7342f27fb10d27945d090d76302e4aee7e084a0b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 6 May 2023 05:54:48 -0400 Subject: [PATCH 164/448] clarify download info --- doc/src/Install_tarball.rst | 17 +++++++++-------- doc/utils/sphinx-config/false_positives.txt | 1 + 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/doc/src/Install_tarball.rst b/doc/src/Install_tarball.rst index 64d73ee356..90dd27fa67 100644 --- a/doc/src/Install_tarball.rst +++ b/doc/src/Install_tarball.rst @@ -2,7 +2,7 @@ Download source and documentation as a tarball ---------------------------------------------- You can download a current LAMMPS tarball from the `download page `_ -of the `LAMMPS website `_. +of the `LAMMPS website `_ or from GitHub (see below). .. _download: https://www.lammps.org/download.html .. _bug: https://www.lammps.org/bug.html @@ -17,21 +17,21 @@ tarball occasionally updated. Feature releases occur every 4 to 8 weeks. The new contents in all feature releases are listed on the `bug and feature page `_ of the LAMMPS homepage. -Both tarballs include LAMMPS documentation (HTML and PDF files) -corresponding to that version. - Tarballs of older LAMMPS versions can also be downloaded from `this page `_. -Once you have a tarball, unzip and untar it with the following +Tarballs downloaded from the LAMMPS homepage include the pre-translated +LAMMPS documentation (HTML and PDF files) corresponding to that version. + +Once you have a tarball, uncompress and untar it with the following command: .. code-block:: bash tar -xzvf lammps*.tar.gz -This will create a LAMMPS directory with the version date -in its name, e.g. lammps-23Jun18. +This will create a LAMMPS directory with the version date in its name, +e.g. lammps-28Mar23. ---------- @@ -45,7 +45,8 @@ with the following command, to create a lammps- directory: unzip lammps*.zip This version corresponds to the selected LAMMPS feature or stable -release. +release (as indicated by the matching git tag) and will only contain the +source code and no pre-built documentation. .. _git: https://github.com/lammps/lammps/releases diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index ee3b582fd9..d2d15633af 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -3736,6 +3736,7 @@ Umin un unary uncomment +uncompress uncompute underprediction undump From 8ed42f6e4ba46de22b5714ccafbd2e64114baeed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 7 May 2023 21:36:29 -0400 Subject: [PATCH 165/448] remove unused communication API --- src/KOKKOS/comm_tiled_kokkos.cpp | 10 ------ src/KOKKOS/comm_tiled_kokkos.h | 6 ---- src/comm.h | 3 -- src/comm_brick.cpp | 52 -------------------------------- src/comm_brick.h | 1 - src/comm_tiled.cpp | 11 ------- src/comm_tiled.h | 1 - 7 files changed, 84 deletions(-) diff --git a/src/KOKKOS/comm_tiled_kokkos.cpp b/src/KOKKOS/comm_tiled_kokkos.cpp index 428b4c79d7..e3286a73f5 100644 --- a/src/KOKKOS/comm_tiled_kokkos.cpp +++ b/src/KOKKOS/comm_tiled_kokkos.cpp @@ -226,13 +226,3 @@ void CommTiledKokkos::forward_comm_array(int nsize, double **array) { CommTiled::forward_comm_array(nsize,array); } - -/* ---------------------------------------------------------------------- - exchange info provided with all 6 stencil neighbors - NOTE: this method is currently not used -------------------------------------------------------------------------- */ - -int CommTiledKokkos::exchange_variable(int n, double *inbuf, double *&outbuf) -{ - return CommTiled::exchange_variable(n,inbuf,outbuf); -} diff --git a/src/KOKKOS/comm_tiled_kokkos.h b/src/KOKKOS/comm_tiled_kokkos.h index 833dc38294..c80436b454 100644 --- a/src/KOKKOS/comm_tiled_kokkos.h +++ b/src/KOKKOS/comm_tiled_kokkos.h @@ -46,13 +46,7 @@ class CommTiledKokkos : public CommTiled { void reverse_comm(class Dump *) override; // reverse comm from a Dump void forward_comm_array(int, double **) override; // forward comm of array - int exchange_variable(int, double *, double *&) override; // exchange on neigh stencil - - private: - }; - } - #endif diff --git a/src/comm.h b/src/comm.h index 7bbf4a55b5..5d803c1afa 100644 --- a/src/comm.h +++ b/src/comm.h @@ -100,11 +100,8 @@ class Comm : protected Pointers { virtual void reverse_comm(class Dump *) = 0; // forward comm of an array - // exchange of info on neigh stencil - // set processor mapping options virtual void forward_comm_array(int, double **) = 0; - virtual int exchange_variable(int, double *, double *&) = 0; // map a point to a processor, based on current decomposition diff --git a/src/comm_brick.cpp b/src/comm_brick.cpp index 921286a3da..08d372187e 100644 --- a/src/comm_brick.cpp +++ b/src/comm_brick.cpp @@ -1455,58 +1455,6 @@ void CommBrick::forward_comm_array(int nsize, double **array) } } -/* ---------------------------------------------------------------------- - exchange info provided with all 6 stencil neighbors -------------------------------------------------------------------------- */ - -int CommBrick::exchange_variable(int n, double *inbuf, double *&outbuf) -{ - int nsend,nrecv,nrecv1,nrecv2; - MPI_Request request; - - nrecv = n; - if (nrecv > maxrecv) grow_recv(nrecv); - memcpy(buf_recv,inbuf,nrecv*sizeof(double)); - - // loop over dimensions - - for (int dim = 0; dim < 3; dim++) { - - // no exchange if only one proc in a dimension - - if (procgrid[dim] == 1) continue; - - // send/recv info in both directions using same buf_recv - // if 2 procs in dimension, single send/recv - // if more than 2 procs in dimension, send/recv to both neighbors - - nsend = nrecv; - MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][0],0, - &nrecv1,1,MPI_INT,procneigh[dim][1],0,world,MPI_STATUS_IGNORE); - nrecv += nrecv1; - if (procgrid[dim] > 2) { - MPI_Sendrecv(&nsend,1,MPI_INT,procneigh[dim][1],0, - &nrecv2,1,MPI_INT,procneigh[dim][0],0,world,MPI_STATUS_IGNORE); - nrecv += nrecv2; - } else nrecv2 = 0; - - if (nrecv > maxrecv) grow_recv(nrecv); - - MPI_Irecv(&buf_recv[nsend],nrecv1,MPI_DOUBLE,procneigh[dim][1],0,world,&request); - MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][0],0,world); - MPI_Wait(&request,MPI_STATUS_IGNORE); - - if (procgrid[dim] > 2) { - MPI_Irecv(&buf_recv[nsend+nrecv1],nrecv2,MPI_DOUBLE,procneigh[dim][0],0,world,&request); - MPI_Send(buf_recv,nsend,MPI_DOUBLE,procneigh[dim][1],0,world); - MPI_Wait(&request,MPI_STATUS_IGNORE); - } - } - - outbuf = buf_recv; - return nrecv; -} - /* ---------------------------------------------------------------------- realloc the size of the send buffer as needed with BUFFACTOR and bufextra flag = 0, don't need to realloc with copy, just free/malloc w/ BUFFACTOR diff --git a/src/comm_brick.h b/src/comm_brick.h index 38483af9de..518e290fa1 100644 --- a/src/comm_brick.h +++ b/src/comm_brick.h @@ -45,7 +45,6 @@ class CommBrick : public Comm { void reverse_comm(class Dump *) override; // reverse comm from a Dump void forward_comm_array(int, double **) override; // forward comm of array - int exchange_variable(int, double *, double *&) override; // exchange on neigh stencil void *extract(const char *, int &) override; double memory_usage() override; diff --git a/src/comm_tiled.cpp b/src/comm_tiled.cpp index 4f6dac2b5e..f2d91c07fa 100644 --- a/src/comm_tiled.cpp +++ b/src/comm_tiled.cpp @@ -1848,17 +1848,6 @@ void CommTiled::forward_comm_array(int nsize, double **array) } } -/* ---------------------------------------------------------------------- - exchange info provided with all 6 stencil neighbors - NOTE: this method is currently not used -------------------------------------------------------------------------- */ - -int CommTiled::exchange_variable(int n, double * /*inbuf*/, double *& /*outbuf*/) -{ - int nrecv = n; - return nrecv; -} - /* ---------------------------------------------------------------------- determine overlap list of Noverlap procs the lo/hi box overlaps overlap = non-zero area in common between box and proc sub-domain diff --git a/src/comm_tiled.h b/src/comm_tiled.h index 526c6166a8..c9434e6164 100644 --- a/src/comm_tiled.h +++ b/src/comm_tiled.h @@ -45,7 +45,6 @@ class CommTiled : public Comm { void reverse_comm(class Dump *) override; // reverse comm from a Dump void forward_comm_array(int, double **) override; // forward comm of array - int exchange_variable(int, double *, double *&) override; // exchange on neigh stencil void coord2proc_setup() override; int coord2proc(double *, int &, int &, int &) override; From 69f60c5222f055274766e5c50394ab176f2dedf9 Mon Sep 17 00:00:00 2001 From: "K.kawai" <31260712+kawai125@users.noreply.github.com> Date: Mon, 8 May 2023 10:36:29 +0900 Subject: [PATCH 166/448] bugfix in fix_ttm --- src/EXTRA-FIX/fix_ttm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-FIX/fix_ttm.cpp b/src/EXTRA-FIX/fix_ttm.cpp index fe0e982e80..16aafe2b15 100644 --- a/src/EXTRA-FIX/fix_ttm.cpp +++ b/src/EXTRA-FIX/fix_ttm.cpp @@ -463,7 +463,7 @@ void FixTTM::read_electron_temperatures(const std::string &filename) if (comm->me == 0) { int ***T_initial_set; - memory->create(T_initial_set,nxgrid,nygrid,nzgrid,"ttm:T_initial_set"); + memory->create(T_initial_set,nzgrid,nygrid,nxgrid,"ttm:T_initial_set"); memset(&T_initial_set[0][0][0],0,ngridtotal*sizeof(int)); // read initial electron temperature values from file From a6f60405b6c6c14cfe9c02551df4550028a62afa Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 8 May 2023 05:52:18 -0400 Subject: [PATCH 167/448] resolve formatting issues and add a few style tweaks from languagetool.org --- doc/src/Modify.rst | 12 ++--- doc/src/Modify_contribute.rst | 56 +++++++++++---------- doc/src/Modify_overview.rst | 32 ++++++------ doc/src/Modify_requirements.rst | 88 +++++++++++++++++---------------- doc/src/Modify_style.rst | 33 ++++++------- doc/src/kspace_modify.rst | 3 +- 6 files changed, 113 insertions(+), 111 deletions(-) diff --git a/doc/src/Modify.rst b/doc/src/Modify.rst index 38cf58cbf5..b10e307b14 100644 --- a/doc/src/Modify.rst +++ b/doc/src/Modify.rst @@ -1,11 +1,11 @@ Modifying & extending LAMMPS **************************** -LAMMPS is designed in a modular fashion and easy to be modified or -extended with new functionality. In fact, about 95% of its source code -is optional. The following pages give basic instructions on adding new -features to LAMMPS. More in-depth explanations and documentation of -individual functions and classes are given in :doc:`Developer`. +LAMMPS has a modular design, so that it is easy to modify or extend with +new functionality. In fact, about 95% of its source code is optional. +The following pages give basic instructions on adding new features to +LAMMPS. More in-depth explanations and documentation of individual +functions and classes are given in :doc:`Developer`. If you add a new feature to LAMMPS and think it will be of general interest to other users, we encourage you to submit it for inclusion in @@ -16,7 +16,7 @@ LAMMPS. This process is explained in the following three pages: A summary description of various types of styles in LAMMPS follows. A discussion of implementing specific styles from scratch is given -in :doc:`Developer_write`. +in :doc:`writing new styles `. .. toctree:: diff --git a/doc/src/Modify_contribute.rst b/doc/src/Modify_contribute.rst index 0d3c17c9a6..21bee1722b 100644 --- a/doc/src/Modify_contribute.rst +++ b/doc/src/Modify_contribute.rst @@ -10,8 +10,8 @@ be notified of releases, follow the ongoing development, and comment on topics of interest to you. This section contains general information regarding the preparation and submission of new features to LAMMPS. If you are new to development in LAMMPS, we recommend you read one of the -tutorials on developing a new :doc:`pair style ` or -:doc:`fix style ` which provide a friendly +tutorials on developing a new :doc:`pair style ` +or :doc:`fix style ` which provide a friendly introduction to what LAMMPS development entails and common vocabulary used in this chapter. @@ -27,9 +27,9 @@ search through the list of `open issues on GitHub `_ and submit a new issue for a planned feature, to avoid duplicating work (and possibly being scooped). -For informal communication with the LAMMPS developers you may ask to +For informal communication with the LAMMPS developers, you may ask to join the `LAMMPS developers on Slack `_. This -slack work space is by invitation only. Thus for access, please send an +slack work space is by invitation only. For access, please send an e-mail to ``slack@lammps.org`` explaining what part of LAMMPS you are working on. Only discussions related to LAMMPS development are tolerated in that work space, so this is **NOT** for people that look @@ -46,10 +46,11 @@ depends largely on how much effort it will cause the LAMMPS developers to integrate and test it, how many and what kind of changes to the core code are required, how quickly you can address them and of how much interest it is to the larger LAMMPS community. This process can be -streamlined by following the :doc:`requirements ` and :doc:`style guidelines`. A small, modular, well written -contribution may be integrated within hours, but a complex change that -requires a redesign of some core functionality in LAMMPS can take months -before inclusion (though this is rare). +streamlined by following the :doc:`requirements ` +and :doc:`style guidelines`. A small, modular, well +written contribution may be integrated within hours, but a complex +change that requires a redesign of some core functionality in LAMMPS can +take months before inclusion (though this is rare). Submission procedure @@ -58,22 +59,22 @@ Submission procedure All changes to LAMMPS (including those from LAMMPS developers) are integrated via pull requests on GitHub and cannot be merged without passing the automated testing and an approving review by a LAMMPS core -developer. Thus before submitting your contribution, you should first -make certain, that your added or modified code compiles and works +developer. Before submitting your contribution, you should therefore +first make certain, that your added or modified code compiles and works correctly with the latest development version of LAMMPS and contains all bug fixes from it. Once you have prepared everything, see the :doc:`LAMMPS GitHub Tutorial ` page for instructions on how to submit your changes or new files through a GitHub pull request. If you are unable or unwilling -to submit via GitHub yourself, you may also submit patch files -or full files to the LAMMPS developers and ask them to submit a pull -request on GitHub on your behalf. If this is the case, create a gzipped -tar file of all new or changed files or a corresponding patch file using -'diff -u' or 'diff -c' format and compress it with gzip. Please only -use gzip compression, as this works well and is available on all platforms. -This latter way of submission may delay the integration as it depends on -the LAMMPS developer having free time available. +to submit via GitHub yourself, you may also submit patch files or full +files to the LAMMPS developers and ask them to submit a pull request on +GitHub on your behalf. If this is the case, create a gzipped tar file +of all new or changed files or a corresponding patch file using 'diff +-u' or 'diff -c' format and compress it with gzip. Please only use gzip +compression, as this works well and is available on all platforms. This +latter way of submission may delay the integration as it depends on the +LAMMPS developer having free time available. External contributions @@ -86,7 +87,7 @@ LAMMPS packages and tools `_ page of the LAMMPS website for examples of groups that do this. We are happy to advertise your package and website from that page. Simply email the `developers `_ with info about your -package and we will post it there. We recommend to name external +package, and we will post it there. We recommend naming external packages USER-\ so they can be easily distinguished from bundled packages that do not have the USER- prefix. @@ -94,13 +95,13 @@ packages that do not have the USER- prefix. Location of files: individual files and packages ------------------------------------------------ -We rarely accept new styles in the core src folder. Thus please review +We rarely accept new styles in the core src folder. Thus, please review the list of :doc:`available Packages ` to see if your contribution could be added to be added to one of them. It should fit -into the general purposed of that package. If it does not fit well, it +into the general purpose of that package. If it does not fit well, it may be added to one of the EXTRA- packages or the MISC package. -However if your project includes many related features that are not +However, if your project includes many related features that are not covered by one of the existing packages or is dependent on a library (bundled or external), it is best to create a package with its own directory (labeled with a name like FOO). In addition to your new @@ -114,8 +115,9 @@ Changes to core LAMMPS files If designed correctly, many additions do not require any changes to the core code of LAMMPS; they are simply add-on files that are compiled with -the rest of LAMMPS. To make those styles work, you may need some trivial -changes to the core code; an example of a trivial change is making a -parent-class method "virtual" when you derive a new child class from it. -If your features involve changes to the core LAMMPS files, it is particularly -encouraged that you communicate with the LAMMPS developers early in development. +the rest of LAMMPS. To make those styles work, you may need some +trivial changes to the core code; an example of a trivial change is +making a parent-class method "virtual" when you derive a new child class +from it. If your features involve changes to the core LAMMPS files, it +is particularly encouraged that you communicate with the LAMMPS +developers early in development. diff --git a/doc/src/Modify_overview.rst b/doc/src/Modify_overview.rst index ed7ff1a8ac..a3d8e9737d 100644 --- a/doc/src/Modify_overview.rst +++ b/doc/src/Modify_overview.rst @@ -4,8 +4,8 @@ Overview The best way to add a new feature to LAMMPS is to find a similar feature and look at the corresponding source and header files to figure out what it does. You will need some knowledge of C++ to be able to understand -the high-level structure of LAMMPS and its class organization, but -functions (class methods) that do actual computations are mostly written +the high-level structure of LAMMPS and its class organization. +Functions (class methods) that do actual computations are mostly written in C-style code and operate on simple C-style data structures (vectors and arrays). A high-level overview of the programming style choices in LAMMPS is :doc:`given elsewhere `. @@ -21,22 +21,22 @@ itself, or from a derived class that already exists. Enabling LAMMPS to invoke the new class is as simple as putting the two source files in the src directory and re-building LAMMPS. -The advantage of C++ and its object-orientation is that all the code -and variables needed to define the new feature are in the 2 files you -write, and thus should not make the rest of LAMMPS more complex or -cause side-effect bugs. +The advantage of C++ and its object-orientation is that all the code and +variables needed to define the new feature are in the 2 files you write. +Thus, it should not make the rest of LAMMPS more complex or cause bugs +through unwanted side effects. -Here is a concrete example. Suppose you write 2 files pair_foo.cpp -and pair_foo.h that define a new class PairFoo that computes pairwise -potentials described in the classic 1997 :ref:`paper ` by Foo, et al. -If you wish to invoke those potentials in a LAMMPS input script with a -command like +Here is a concrete example. Suppose you write 2 files ``pair_foo.cpp`` +and ``pair_foo.h`` that define a new class ``PairFoo`` that computes +pairwise potentials described in the classic 1997 :ref:`paper ` by +Foo, *et al.* If you wish to invoke those potentials in a LAMMPS input +script with a command like: .. code-block:: LAMMPS pair_style foo 0.1 3.5 -then your pair_foo.h file should be structured as follows: +Then your ``pair_foo.h`` file should be structured as follows: .. code-block:: c++ @@ -51,8 +51,8 @@ then your pair_foo.h file should be structured as follows: #endif where "foo" is the style keyword in the pair_style command, and -PairFoo is the class name defined in your pair_foo.cpp and pair_foo.h -files. +``PairFoo`` is the class name defined in your ``pair_foo.cpp`` and +``pair_foo.h`` files. When you re-build LAMMPS, your new pairwise potential becomes part of the executable and can be invoked with a pair_style command like the @@ -66,7 +66,7 @@ command. The :doc:`Modify page ` lists all the common styles in LAMMPS, and discusses the header file for the base class that these styles are derived from. Public variables in that file are ones used and set by -the derived classes which are also used by the base class. Sometimes +the derived classes, which are also used by the base class. Sometimes they are also used by the rest of LAMMPS. Pure functions, which means functions declared as virtual in the base class header file which are also set to 0, are functions you **must** implement in your new derived @@ -85,7 +85,7 @@ functionality: post-processing step. Many computations are more easily and more quickly done that way. * Do not try to do anything within the timestepping of a run that is not - parallel. For example do not accumulate a bunch of data on a single + parallel. For example, do not accumulate a bunch of data on a single processor and analyze it. You run the risk of seriously degrading the parallel efficiency this way. * If your new feature reads arguments or writes output, make sure you diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 91a17789b6..9d5ffd38b2 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -8,7 +8,7 @@ into the LAMMPS software distribution. Motivation ---------- -The LAMMPS developers are committed to providing a software package that +The LAMMPS developers are committed to provide a software package that is versatile, reliable, high-quality, efficient, portable, and easy to maintain and modify. Achieving all of these goals is challenging since a large part of LAMMPS consists of contributed code from many different @@ -20,13 +20,14 @@ grow and more features and functionality are added, it becomes a necessity to be more discriminating with new contributions while also working at the same time to improve the existing code. -The following requirements and recommendations are provided to help -maintaining or improving that status. It is indicated which +The following requirements and recommendations are provided as a guide +to maintain or improve that status. It is indicated which individual requirements are strict, and which represent a preference and thus are negotiable or optional. Please feel free to contact the LAMMPS core -developers in case you need additional explanations or clarifications or -in case you need assistance in realizing the (strict) requirements for -your contributions. Requirements include: +developers in case you need additional explanations or clarifications, +or in case you need assistance in realizing the (strict) requirements +for your contributions. Requirements include: + * :ref:`Licensing requirements ` (strict) * :ref:`Integration testing ` (strict) * :ref:`Documentation ` (strict) @@ -39,20 +40,20 @@ your contributions. Requirements include: * :ref:`Citation reminder ` (optional) * :ref:`Testing ` (optional) - .. _ReqLicense: Licensing requirements (strict) ------------------------------- Contributing authors agree when submitting a pull request that their -contributions can be distributed under the LAMMPS license -conditions. This is the GNU public license in version 2 (not 3 or later) -for the publicly distributed versions, e.g. on the LAMMPS homepage or on -GitHub. On request we also make a version of LAMMPS available under -LGPL 2.1 terms; this will usually be the latest available or a previous -stable version with a few LGPL 2.1 incompatible files removed. More details -are found on the :doc:`LAMMPS open-source license page `. +contributions can be distributed under the LAMMPS license conditions. +This is the GNU public license in version 2 (not 3 or later) for the +publicly distributed versions, e.g. on the LAMMPS homepage or on GitHub. +We also make a version of LAMMPS under LGPL 2.1 terms available on +request; this will usually be the latest available or a previous stable +version with a few LGPL 2.1 incompatible files removed. More details +are found on the :doc:`LAMMPS open-source license page +`. Your new source files should have the LAMMPS copyright, GPL notice, and your name and email address at the top, like other user-contributed @@ -89,7 +90,7 @@ The translation of the documentation to HTML and PDF is also tested. This means that contributed source code **must** compile with the most current version of LAMMPS with ``-DLAMMPS_BIGBIG`` in addition to the default setting of ``-DLAMMPS_SMALLBIG``. The code needs to work -correctly in both cases and also in serial and parallel using MPI. +correctly in both cases, and also in serial and parallel using MPI. Some "disruptive" changes may break tests and require updates to the testing tools or scripts or tests themselves. This is rare. If in @@ -105,7 +106,7 @@ Contributions that add new styles or commands or augment existing ones must include the corresponding new or modified documentation in `ReStructuredText format `_ (.rst files in the ``doc/src/`` folder). The documentation shall be written in American English and the -.rst file must use only ASCII characters so it can be cleanly translated +.rst file must use only ASCII characters, so it can be cleanly translated to PDF files (via `sphinx `_ and PDFLaTeX). Special characters may be included via embedded math expression typeset in a LaTeX subset. @@ -120,11 +121,11 @@ packages must be updated as well as a package specific description added and, if necessary, some package specific build instructions included. As appropriate, the text files with the documentation can include inline -mathematical expression or figures (see ``doc/JPG`` for examples). -Additional PDF files with further details (see ``doc/PDF`` for examples) may -also be included. The page should also include literature citations as -appropriate; see the bottom of ``doc/fix_nh.rst`` for examples and the -earlier part of the same file for how to format the cite itself. +mathematical expressions or figures (see ``doc/JPG`` for examples). +Additional PDF files with further details (see ``doc/PDF`` for examples) +may also be included. The page should also include literature citations +as appropriate; see the bottom of ``doc/fix_nh.rst`` for examples and +the earlier part of the same file for how to format the cite itself. Citation labels must be unique across **all** .rst files. The "Restrictions" section of the page should indicate if your command is only available if LAMMPS is built with the appropriate FOO package. See @@ -135,9 +136,10 @@ inspect and proofread the resulting HTML format doc page before submitting your code. Upon submission of a pull request, checks for error free completion of the HTML and PDF build will be performed and also a spell check, a check for correct anchors and labels, and a check -for completeness of references all styles in their corresponding tables -and lists is run. In case the spell check reports false positives they -can be added to the file ``doc/utils/sphinx-config/false_positives.txt`` +for completeness of references to all styles in their corresponding +tables and lists is run. In case the spell check reports false +positives, they can be added to the file +``doc/utils/sphinx-config/false_positives.txt`` Contributions that add or modify the library interface or "public" APIs from the C++ code or the Fortran module must include suitable doxygen @@ -169,7 +171,7 @@ keep the code readable to programmers that have limited C++ programming experience. C++ constructs are acceptable when they help improve the readability and reliability of the code, e.g. when using the `std::string` class instead of manipulating pointers and calling the -string functions of the C library. In addition a collection of +string functions of the C library. In addition, a collection of convenient :doc:`utility functions and classes ` for recurring tasks and a collection of :doc:`platform neutral functions ` for improved @@ -196,8 +198,8 @@ Build system (strict) LAMMPS currently supports two build systems: one that is based on :doc:`traditional Makefiles ` and one that is based on -:doc:`CMake `. Thus your contribution must be compatible -with and support both. +:doc:`CMake `. Therefore, your contribution must be +compatible with and support both build systems. For a single pair of header and implementation files that are an independent feature, it is usually only required to add them to @@ -210,7 +212,7 @@ Install.sh file is also needed to check for those dependencies and modifications to src/Depend.sh to trigger the checks. See other README and Install.sh files in other directories as examples. -Similarly for CMake support, changes may need to be made to +Similarly, for CMake support, changes may need to be made to cmake/CMakeLists.txt, some of the files in cmake/presets, and possibly a file with specific instructions needs to be added to cmake/Modules/Packages/. Please check out how this is handled for @@ -219,7 +221,7 @@ existing packages and ask the LAMMPS developers if you need assistance. .. _ReqNaming: -Command or Style names, file names, and keywords (strict) +Command or style names, file names, and keywords (strict) --------------------------------------------------------- All user-visible command or style names should be all lower case and @@ -238,9 +240,9 @@ Programming style requirements (varied) To maintain consistency across contributions from many people, there are various programming style requirements for contributions to LAMMPS. -Some of these requirements are strict and must be followed while some +Some of these requirements are strict and must be followed, while others are only preferred and thus may be skipped. An in-depth discussion of -the style guidelines are provided in the :doc:`programming style doc +the style guidelines is provided in the :doc:`programming style doc page `. @@ -252,8 +254,8 @@ Examples (preferred) In most cases, it is preferred that example scripts (simple, small, fast to complete on 1 CPU) are included that demonstrate the use of new or extended functionality. These are typically under the examples or -examples/PACKAGES directory are are further described on the -:doc:`examples page `. Guidelines for input scripts include: +examples/PACKAGES directory are further described on the :doc:`examples +page `. Guidelines for input scripts include: - commands that generate output should be commented out (except when the output is the sole purpose or the feature, e.g. for a new compute) @@ -285,7 +287,7 @@ Error or warning messages and explanations (preferred) .. versionchanged:: 4May2022 -Starting with LAMMPS version 4 May 2022 the LAMMPS developers have +Starting with LAMMPS version 4 May 2022, the LAMMPS developers have agreed on a new policy for error and warning messages. Previously, all error and warning strings were supposed to be listed in @@ -298,17 +300,17 @@ source file and the line number of the error location would be printed, so that one could look up the cause by reading the source code. The new policy encourages more specific error messages that ideally -indicate the cause directly requiring no further lookup. This is aided -by the `{fmt} library `_ to convert the Error class -commands so that they take a variable number of arguments and error -text will be treated like a {fmt} syntax format string. Error messages -should still preferably be kept to a single line or two lines at most. +indicate the cause directly, and requiring no further lookup. This is +aided by the `{fmt} library `_ enabling Error class +methods that take a variable number of arguments and an error text that +will be treated like a {fmt} syntax format string. Error messages should +still preferably be kept to a single line or two lines at most. For more complex explanations or errors that have multiple possible reasons, a paragraph should be added to the `Error_details` page with an error code reference (e.g. ``.. _err0001:``) then the utility function :cpp:func:`utils::errorurl() ` can be used -to generate an URL that will directly lead to that paragraph. An error +to generate a URL that will directly lead to that paragraph. An error for missing arguments can be easily generated using the :cpp:func:`utils::missing_cmd_args() ` convenience function. @@ -321,7 +323,7 @@ and thus require some additional explanation. The transformation of existing LAMMPS code to this new scheme is ongoing and - given the size of the LAMMPS source code - will take a significant -amount of time until completion. However, for new code following the +amount of time until completion. For new code, however, following the new approach is strongly preferred. The expectation is that the new scheme will make it easier for LAMMPS users, developers, and maintainers. @@ -337,7 +339,7 @@ algorithm/science behind the feature itself, or its initial usage, or its implementation in LAMMPS), you can add the citation to the \*.cpp source file. See ``src/DIFFRACTION/compute_saed.cpp`` for an example. A BibTeX format citation is stored in a string variable at the top -of the file and a single line of code registering this variable is +of the file, and a single line of code registering this variable is added to the constructor of the class. When your feature is used, by default, LAMMPS will print the brief info and the DOI in the first line to the screen and the full citation to the log file. @@ -346,7 +348,7 @@ If there is additional functionality (which may have been added later) described in a different publication, additional citation descriptions may be added for as long as they are only registered when the corresponding keyword activating this functionality is used. With these -options it is possible to have LAMMPS output a specific citation +options, it is possible to have LAMMPS output a specific citation reminder whenever a user invokes your feature from their input script. Please note that you should *only* use this for the *most* relevant paper for a feature and a publication that you or your group authored. diff --git a/doc/src/Modify_style.rst b/doc/src/Modify_style.rst index a42bdd0d1f..b853ccd721 100644 --- a/doc/src/Modify_style.rst +++ b/doc/src/Modify_style.rst @@ -1,19 +1,17 @@ LAMMPS programming style ======================== - The LAMMPS developers aim to employ a consistent programming style and naming conventions across the entire code base, as this helps with maintenance, debugging, and understanding the code, both for developers -and users. This page provides a list of standard style choices used in -LAMMPS. Some of these standards are required while others are just -preferred. Following these conventions will make it much easier to -integrate your contribution. If you are uncertain, please ask. +and users. This page provides a list of standard style choices used in +LAMMPS. Some of these standards are required, while others are just +preferred. Following these conventions will make it much easier to +integrate your contribution. If you are uncertain, please ask. The files `pair_lj_cut.h`, `pair_lj_cut.cpp`, `utils.h`, and `utils.cpp` may serve as representative examples. - Include files (varied) ^^^^^^^^^^^^^^^^^^^^^^ @@ -28,23 +26,22 @@ Include files (varied) is where type clashes between packages and hard to find bugs have regularly manifested in the past. -- Header files, especially those defining a "style", should only use - the absolute minimum number of include files and **must not** contain - any ``using`` statements. Typically that would be only the header for - the base class. Instead any include statements should be put into the +- Header files, especially those defining a "style", should only use the + absolute minimum number of include files and **must not** contain any + ``using`` statements. Typically, that would be only the header for the + base class. Instead, any include statements should be put into the corresponding implementation files and forward declarations be used. For implementation files, the "include what you use" principle should be employed. However, there is the notable exception that when the ``pointers.h`` header is included (or one of the base classes derived from it) certain headers will always be included and thus do not need - to be explicitly specified. - These are: `mpi.h`, `cstddef`, `cstdio`, `cstdlib`, `string`, `utils.h`, - `vector`, `fmt/format.h`, `climits`, `cinttypes`. - This also means any such file can assume that `FILE`, `NULL`, and - `INT_MAX` are defined. + to be explicitly specified. These are: `mpi.h`, `cstddef`, `cstdio`, + `cstdlib`, `string`, `utils.h`, `vector`, `fmt/format.h`, `climits`, + `cinttypes`. This also means any such file can assume that `FILE`, + `NULL`, and `INT_MAX` are defined. - System headers or from installed libraries are include with angular - brackets (example: ``#include ``), while local include file + brackets (example: ``#include ``), while local include files use double quotes (example: ``#include "atom.h"``) - When including system header files from the C library use the @@ -152,7 +149,7 @@ Miscellaneous standards (varied) contributed. For header files containing a ``SomeStyle(keyword, ClassName)`` macros it is required to have this macro embedded with a pair of ``// clang-format off``, ``// clang-format on`` comments and - the line must be terminated with a semi-colon (;). Example: + the line must be terminated with a semicolon (;). Example: .. code-block:: c++ @@ -168,7 +165,7 @@ Miscellaneous standards (varied) You may also use ``// clang-format on/off`` throughout your files to protect individual sections from being reformatted. -- All files should have 0644 permissions, i.e writable to the user only +- All files should have 0644 permissions, i.e. writable to the user only and readable by all and no executable permissions. Executable permissions (0755) should only be on shell scripts or python or similar scripts for interpreted script languages. diff --git a/doc/src/kspace_modify.rst b/doc/src/kspace_modify.rst index 2d3921e281..351e387c0f 100644 --- a/doc/src/kspace_modify.rst +++ b/doc/src/kspace_modify.rst @@ -142,7 +142,8 @@ the code will stop with an error message. When this option is set to For a typical application, using the automatic parameter generation will provide simulations that are either inaccurate or slow. Using this option is thus not recommended. For guidelines on how to obtain good -parameters, see the :doc:`How-To ` discussion. +parameters, see the :doc:`long-range dispersion howto ` +discussion. ---------- From abe238ce619db844a6738703d22a7928d9a45874 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 8 May 2023 05:54:33 -0400 Subject: [PATCH 168/448] use correct spelling for semicolon --- doc/src/dump_molfile.rst | 2 +- doc/src/fix_wall.rst | 2 +- doc/src/pair_lepton.rst | 2 +- doc/src/read_dump.rst | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/dump_molfile.rst b/doc/src/dump_molfile.rst index f8cc06d039..ffc0b443e0 100644 --- a/doc/src/dump_molfile.rst +++ b/doc/src/dump_molfile.rst @@ -63,7 +63,7 @@ like element names. The *path* keyword determines which in directories. This is a "path" like other search paths, i.e. it can contain multiple directories -separated by a colon (or semi-colon on windows). This keyword is +separated by a colon (or semicolon on Windows). This keyword is optional and default to ".", the current directory. The *unwrap* option of the :doc:`dump_modify ` command allows diff --git a/doc/src/fix_wall.rst b/doc/src/fix_wall.rst index 2cf5aeccff..42cd94978d 100644 --- a/doc/src/fix_wall.rst +++ b/doc/src/fix_wall.rst @@ -209,7 +209,7 @@ it as a single keyword. Optionally, the expression may use "rc" to refer to the cutoff distance for the given wall. Further constants in the expression can be defined -in the same string as additional expressions separated by semi-colons. +in the same string as additional expressions separated by semicolons. The expression "k*(r-rc)^2;k=100.0" represents a repulsive-only harmonic spring as in fix *wall/harmonic* with a force constant *K* (same as :math:`\epsilon` above) of 100 energy units. More details on the Lepton diff --git a/doc/src/pair_lepton.rst b/doc/src/pair_lepton.rst index ffd317af40..608265ecbd 100644 --- a/doc/src/pair_lepton.rst +++ b/doc/src/pair_lepton.rst @@ -76,7 +76,7 @@ instead reference the radii of the two atoms of the pair with "radi" and :doc:`data files ` or the :doc:`set command `. Note that further constants in the expressions can be defined in the -same string as additional expressions separated by semi-colons as shown +same string as additional expressions separated by semicolons as shown in the examples above. The expression `"200.0*(r-1.5)^2"` represents a harmonic potential diff --git a/doc/src/read_dump.rst b/doc/src/read_dump.rst index c03b3b50de..59d6cca78d 100644 --- a/doc/src/read_dump.rst +++ b/doc/src/read_dump.rst @@ -132,7 +132,7 @@ files can be written by LAMMPS via the :doc:`dump dcd ` command. The *path* value specifies a list of directories which LAMMPS will search for the molfile plugins appropriate to the specified *style*\ . The syntax of the *path* value is like other search paths: it can -contain multiple directories separated by a colon (or semi-colon on +contain multiple directories separated by a colon (or semicolon on windows). The *path* keyword is optional and defaults to ".", i.e. the current directory. From 49ac79fcdd40d9111607451f04d70ba739ff5487 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 8 May 2023 08:55:40 -0600 Subject: [PATCH 169/448] change error checks for computes that are not current --- src/VTK/dump_vtk.cpp | 20 ++++-------- src/dump_custom.cpp | 20 ++++-------- src/dump_grid.cpp | 20 ++++-------- src/dump_image.cpp | 18 ++++------- src/dump_local.cpp | 20 ++++-------- src/thermo.cpp | 42 +++++++++--------------- src/variable.cpp | 77 +++++++++++++++++++------------------------- 7 files changed, 83 insertions(+), 134 deletions(-) diff --git a/src/VTK/dump_vtk.cpp b/src/VTK/dump_vtk.cpp index 75033684ae..3667180bc9 100644 --- a/src/VTK/dump_vtk.cpp +++ b/src/VTK/dump_vtk.cpp @@ -294,21 +294,15 @@ int DumpVTK::count() } // invoke Computes for per-atom quantities - // only if within a run or minimize - // else require that computes are current - // this prevents a compute from being invoked by the WriteDump class + // cannot invoke before first run, otherwise invoke if necessary if (ncompute) { - if (update->whichflag == 0) { - for (i = 0; i < ncompute; i++) - if (compute[i]->invoked_peratom != update->ntimestep) - error->all(FLERR,"Compute used in dump between runs is not current"); - } else { - for (i = 0; i < ncompute; i++) { - if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) { - compute[i]->compute_peratom(); - compute[i]->invoked_flag |= Compute::INVOKED_PERATOM; - } + if (update->first_update == 0) + error->all(FLERR,"Dump compute cannot be invoked before first run"); + for (i = 0; i < ncompute; i++) { + if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) { + compute[i]->compute_peratom(); + compute[i]->invoked_flag |= Compute::INVOKED_PERATOM; } } } diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 415bc4c7f0..517956caf1 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -556,21 +556,15 @@ int DumpCustom::count() } // invoke Computes for per-atom quantities - // only if within a run or minimize - // else require that computes are current - // this prevents a compute from being invoked by the WriteDump class + // cannot invoke before first run, otherwise invoke if necessary if (ncompute) { - if (update->whichflag == 0) { - for (i = 0; i < ncompute; i++) - if (compute[i]->invoked_peratom != update->ntimestep) - error->all(FLERR,"Compute used in dump between runs is not current"); - } else { - for (i = 0; i < ncompute; i++) { - if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) { - compute[i]->compute_peratom(); - compute[i]->invoked_flag |= Compute::INVOKED_PERATOM; - } + if (update->first_update == 0) + error->all(FLERR,"Dump compute cannot be invoked before first run"); + for (i = 0; i < ncompute; i++) { + if (!(compute[i]->invoked_flag & Compute::INVOKED_PERATOM)) { + compute[i]->compute_peratom(); + compute[i]->invoked_flag |= Compute::INVOKED_PERATOM; } } } diff --git a/src/dump_grid.cpp b/src/dump_grid.cpp index 2ca4f6c5d4..056cac1095 100644 --- a/src/dump_grid.cpp +++ b/src/dump_grid.cpp @@ -522,21 +522,15 @@ int DumpGrid::count() } // invoke Computes for per-grid quantities - // only if within a run or minimize - // else require that computes are current - // this prevents a compute from being invoked by the WriteDump class + // cannot invoke before first run, otherwise invoke if necessary if (ncompute) { - if (update->whichflag == 0) { - for (i = 0; i < ncompute; i++) - if (compute[i]->invoked_pergrid != update->ntimestep) - error->all(FLERR,"Compute {} used in dump between runs is not current", compute[i]->id); - } else { - for (i = 0; i < ncompute; i++) { - if (!(compute[i]->invoked_flag & Compute::INVOKED_PERGRID)) { - compute[i]->compute_pergrid(); - compute[i]->invoked_flag |= Compute::INVOKED_PERGRID; - } + if (update->first_update == 0) + error->all(FLERR,"Dump compute cannot be invoked before first run"); + for (i = 0; i < ncompute; i++) { + if (!(compute[i]->invoked_flag & Compute::INVOKED_PERGRID)) { + compute[i]->compute_pergrid(); + compute[i]->invoked_flag |= Compute::INVOKED_PERGRID; } } } diff --git a/src/dump_image.cpp b/src/dump_image.cpp index aea052046e..ff1c540d3f 100644 --- a/src/dump_image.cpp +++ b/src/dump_image.cpp @@ -664,20 +664,14 @@ void DumpImage::write() } // invoke Compute for per-grid quantities - // only if within a run or minimize - // else require the compute is current - // this prevents the compute from being invoked by the WriteDump class + // cannot invoke before first run, otherwise invoke if necessary if (grid_compute) { - if (update->whichflag == 0) { - if (grid_compute->invoked_pergrid != update->ntimestep) - error->all(FLERR,"Grid compute {} used in dump image between runs is not current", - grid_compute->id); - } else { - if (!(grid_compute->invoked_flag & Compute::INVOKED_PERGRID)) { - grid_compute->compute_pergrid(); - grid_compute->invoked_flag |= Compute::INVOKED_PERGRID; - } + if (update->first_update == 0) + error->all(FLERR,"Grid compute used in dump image cannot be invoked before first run"); + if (!(grid_compute->invoked_flag & Compute::INVOKED_PERGRID)) { + grid_compute->compute_pergrid(); + grid_compute->invoked_flag |= Compute::INVOKED_PERGRID; } } diff --git a/src/dump_local.cpp b/src/dump_local.cpp index 9c18b7f94f..097589ea41 100644 --- a/src/dump_local.cpp +++ b/src/dump_local.cpp @@ -325,21 +325,15 @@ int DumpLocal::count() int i; // invoke Computes for local quantities - // only if within a run or minimize - // else require that computes are current - // this prevents a compute from being invoked by the WriteDump class + // cannot invoke before first run, otherwise invoke if necessary if (ncompute) { - if (update->whichflag == 0) { - for (i = 0; i < ncompute; i++) - if (compute[i]->invoked_local != update->ntimestep) - error->all(FLERR,"Compute used in dump between runs is not current"); - } else { - for (i = 0; i < ncompute; i++) { - if (!(compute[i]->invoked_flag & Compute::INVOKED_LOCAL)) { - compute[i]->compute_local(); - compute[i]->invoked_flag |= Compute::INVOKED_LOCAL; - } + if (update->first_update == 0) + error->all(FLERR,"Dump compute cannot be invoked before first run"); + for (i = 0; i < ncompute; i++) { + if (!(compute[i]->invoked_flag & Compute::INVOKED_LOCAL)) { + compute[i]->compute_local(); + compute[i]->invoked_flag |= Compute::INVOKED_LOCAL; } } } diff --git a/src/thermo.cpp b/src/thermo.cpp index 302bf566d2..0503018a3a 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -1118,7 +1118,7 @@ int Thermo::add_variable(const char *id) } /* ---------------------------------------------------------------------- - check whether temperature compute is defined, available, and current + check whether temperature compute is defined, active, and needs invoking ------------------------------------------------------------------------- */ void Thermo::check_temp(const std::string &keyword) @@ -1126,18 +1126,16 @@ void Thermo::check_temp(const std::string &keyword) if (!temperature) error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init temperature", keyword); - if (update->whichflag == 0) { - if (temperature->invoked_scalar != update->ntimestep) - error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current", - temperature->style, temperature->id); - } else if (!(temperature->invoked_flag & Compute::INVOKED_SCALAR)) { + if (update->first_update == 0) + error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword); + if (!(temperature->invoked_flag & Compute::INVOKED_SCALAR)) { temperature->compute_scalar(); temperature->invoked_flag |= Compute::INVOKED_SCALAR; } } /* ---------------------------------------------------------------------- - check whether potential energy compute is defined, available, and current + check whether potential energy compute is defined, active, and needs invoking ------------------------------------------------------------------------- */ void Thermo::check_pe(const std::string &keyword) @@ -1147,47 +1145,41 @@ void Thermo::check_pe(const std::string &keyword) if (!pe) error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init potential energy", keyword); - if (update->whichflag == 0) { - if (pe->invoked_scalar != update->ntimestep) - error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current", - pe->style, pe->id); - } else { + if (update->first_update == 0) + error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword); + if (!(pe->invoked_flag & Compute::INVOKED_SCALAR)) { pe->compute_scalar(); pe->invoked_flag |= Compute::INVOKED_SCALAR; } } /* ---------------------------------------------------------------------- - check whether scalar pressure compute is defined, available, and current + check whether scalar pressure compute is defined, active, and needs invoking ------------------------------------------------------------------------- */ void Thermo::check_press_scalar(const std::string &keyword) { if (!pressure) error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init press", keyword); - if (update->whichflag == 0) { - if (pressure->invoked_scalar != update->ntimestep) - error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current", - pressure->style, pressure->id); - } else if (!(pressure->invoked_flag & Compute::INVOKED_SCALAR)) { + if (update->first_update == 0) + error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword); + if (!(pressure->invoked_flag & Compute::INVOKED_SCALAR)) { pressure->compute_scalar(); pressure->invoked_flag |= Compute::INVOKED_SCALAR; } } /* ---------------------------------------------------------------------- - check whether pressure tensor compute is defined, available, and current + check whether tensor pressure compute is defined, active, and needs invoking ------------------------------------------------------------------------- */ void Thermo::check_press_vector(const std::string &keyword) { if (!pressure) error->all(FLERR, "Thermo keyword {} in variable requires thermo to use/init press", keyword); - if (update->whichflag == 0) { - if (pressure->invoked_vector != update->ntimestep) - error->all(FLERR, "Compute {} {} used in variable thermo keyword between runs is not current", - pressure->style, pressure->id); - } else if (!(pressure->invoked_flag & Compute::INVOKED_VECTOR)) { + if (update->first_update == 0) + error->all(FLERR,"Thermo keyword {} cannot be invoked before first run",keyword); + if (!(pressure->invoked_flag & Compute::INVOKED_VECTOR)) { pressure->compute_vector(); pressure->invoked_flag |= Compute::INVOKED_VECTOR; } @@ -1214,8 +1206,6 @@ int Thermo::evaluate_keyword(const std::string &word, double *answer) // invoke a lo-level thermo routine to compute the variable value // if keyword requires a compute, error if thermo doesn't use the compute - // if inbetween runs and needed compute is not current, error - // if in middle of run and needed compute is not current, invoke it // for keywords that use energy (evdwl, ebond, etc): // check if energy was tallied on this timestep and set pe->invoked_flag // this will trigger next timestep for energy tallying via addstep() diff --git a/src/variable.cpp b/src/variable.cpp index b9b3661af8..24b20f41db 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -1440,10 +1440,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) if (nbracket == 0 && compute->scalar_flag && lowercase) { - if (update->whichflag == 0) { - if (compute->invoked_scalar != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_SCALAR)) { compute->compute_scalar(); compute->invoked_flag |= Compute::INVOKED_SCALAR; } @@ -1463,10 +1462,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) if (index1 > compute->size_vector && compute->size_vector_variable == 0) print_var_error(FLERR,"Variable formula compute vector is accessed out-of-range",ivar,0); - if (update->whichflag == 0) { - if (compute->invoked_vector != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) { compute->compute_vector(); compute->invoked_flag |= Compute::INVOKED_VECTOR; } @@ -1490,10 +1488,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0); if (index2 > compute->size_array_cols) print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0); - if (update->whichflag == 0) { - if (compute->invoked_array != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { compute->compute_array(); compute->invoked_flag |= Compute::INVOKED_ARRAY; } @@ -1518,10 +1515,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) print_var_error(FLERR,"Compute global vector in atom-style variable formula",ivar); if (compute->size_vector == 0) print_var_error(FLERR,"Variable formula compute vector is zero length",ivar); - if (update->whichflag == 0) { - if (compute->invoked_vector != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) { compute->compute_vector(); compute->invoked_flag |= Compute::INVOKED_VECTOR; } @@ -1543,10 +1539,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) print_var_error(FLERR,"Compute global vector in atom-style variable formula",ivar); if (compute->size_array_rows == 0) print_var_error(FLERR,"Variable formula compute array is zero length",ivar); - if (update->whichflag == 0) { - if (compute->invoked_array != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { compute->compute_array(); compute->invoked_flag |= Compute::INVOKED_ARRAY; } @@ -1563,10 +1558,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) } else if (nbracket == 1 && compute->peratom_flag && compute->size_peratom_cols == 0) { - if (update->whichflag == 0) { - if (compute->invoked_peratom != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { compute->compute_peratom(); compute->invoked_flag |= Compute::INVOKED_PERATOM; } @@ -1581,10 +1575,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) if (index2 > compute->size_peratom_cols) print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0); - if (update->whichflag == 0) { - if (compute->invoked_peratom != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { compute->compute_peratom(); compute->invoked_flag |= Compute::INVOKED_PERATOM; } @@ -1605,10 +1598,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) print_var_error(FLERR,"Per-atom compute in equal-style variable formula",ivar); if (treetype == VECTOR) print_var_error(FLERR,"Per-atom compute in vector-style variable formula",ivar); - if (update->whichflag == 0) { - if (compute->invoked_peratom != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { compute->compute_peratom(); compute->invoked_flag |= Compute::INVOKED_PERATOM; } @@ -1630,10 +1622,9 @@ double Variable::evaluate(char *str, Tree **tree, int ivar) print_var_error(FLERR,"Per-atom compute in vector-style variable formula",ivar); if (index1 > compute->size_peratom_cols) print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0); - if (update->whichflag == 0) { - if (compute->invoked_peratom != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_PERATOM)) { compute->compute_peratom(); compute->invoked_flag |= Compute::INVOKED_PERATOM; } @@ -4050,10 +4041,9 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t print_var_error(FLERR,mesg,ivar); } if (index == 0 && compute->vector_flag) { - if (update->whichflag == 0) { - if (compute->invoked_vector != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_VECTOR)) { compute->compute_vector(); compute->invoked_flag |= Compute::INVOKED_VECTOR; } @@ -4062,10 +4052,9 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t } else if (index && compute->array_flag) { if (index > compute->size_array_cols) print_var_error(FLERR,"Variable formula compute array is accessed out-of-range",ivar,0); - if (update->whichflag == 0) { - if (compute->invoked_array != update->ntimestep) - print_var_error(FLERR,"Compute used in variable between runs is not current",ivar); - } else if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { + if (update->first_update == 0) + print_var_error(FLERR,"Variable formula compute cannot be invoked before first run",ivar); + if (!(compute->invoked_flag & Compute::INVOKED_ARRAY)) { compute->compute_array(); compute->invoked_flag |= Compute::INVOKED_ARRAY; } From 200f740c0690914d5ea8f8dc10caf363284c6c4a Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Mon, 8 May 2023 09:48:27 -0600 Subject: [PATCH 170/448] update variable doc page to explain new behavior --- doc/src/variable.rst | 208 ++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 131 deletions(-) diff --git a/doc/src/variable.rst b/doc/src/variable.rst index 8bd33218ac..d594b89859 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -1285,18 +1285,19 @@ with a leading $ sign (e.g. $x or ${abc}) versus with a leading "v\_" (e.g. v_x or v_abc). The former can be used in any input script command, including a variable command. The input script parser evaluates the reference variable immediately and substitutes its value -into the command. As explained on the :doc:`Commands parse ` doc page, you can also use un-named -"immediate" variables for this purpose. For example, a string like -this $((xlo+xhi)/2+sqrt(v_area)) in an input script command evaluates -the string between the parenthesis as an equal-style variable formula. +into the command. As explained on the :doc:`Commands parse +` doc page, you can also use un-named "immediate" +variables for this purpose. For example, a string like this +$((xlo+xhi)/2+sqrt(v_area)) in an input script command evaluates the +string between the parenthesis as an equal-style variable formula. Referencing a variable with a leading "v\_" is an optional or required -kind of argument for some commands (e.g. the :doc:`fix ave/chunk ` or :doc:`dump custom ` or -:doc:`thermo_style ` commands) if you wish it to evaluate -a variable periodically during a run. It can also be used in a -variable formula if you wish to reference a second variable. The -second variable will be evaluated whenever the first variable is -evaluated. +kind of argument for some commands (e.g. the :doc:`fix ave/chunk +` or :doc:`dump custom ` or :doc:`thermo_style +` commands) if you wish it to evaluate a variable +periodically during a run. It can also be used in a variable formula +if you wish to reference a second variable. The second variable will +be evaluated whenever the first variable is evaluated. As an example, suppose you use this command in your input script to define the variable "v" as @@ -1309,8 +1310,9 @@ before a run where the simulation box size changes. You might think this will assign the initial volume to the variable "v". That is not the case. Rather it assigns a formula which evaluates the volume (using the thermo_style keyword "vol") to the variable "v". If you -use the variable "v" in some other command like :doc:`fix ave/time ` then the current volume of the box will be -evaluated continuously during the run. +use the variable "v" in some other command like :doc:`fix ave/time +` then the current volume of the box will be evaluated +continuously during the run. If you want to store the initial volume of the system, you can do it this way: @@ -1347,132 +1349,75 @@ will occur when the formula for "vratio" is evaluated later. Variable Accuracy """"""""""""""""" -Obviously, LAMMPS attempts to evaluate variables containing formulas -(\ *equal* and *atom* style variables) accurately whenever the -evaluation is performed. Depending on what is included in the -formula, this may require invoking a :doc:`compute `, either -directly or indirectly via a thermo keyword, or accessing a value -previously calculated by a compute, or accessing a value calculated -and stored by a :doc:`fix `. If the compute is one that calculates -the pressure or energy of the system, then these quantities need to be -tallied during the evaluation of the interatomic potentials (pair, -bond, etc) on timesteps that the variable will need the values. +Obviously, LAMMPS attempts to evaluate variables which contain +formulas (\ *equal* and *vector* and *atom* style variables) +accurately whenever the evaluation is performed. Depending on what is +included in the formula, this may require invoking a :doc:`compute +`, either directly or indirectly via a thermo keyword, or +accessing a value previously calculated by a compute, or accessing a +value calculated and stored by a :doc:`fix `. If the compute is +one that calculates the energy or pressure of the system, then the +corresponding energy or virial quantities need to be tallied during +the evaluation of the interatomic potentials (pair, bond, etc) on any +timestep that the variable needs the tallies. An input script can +also request variables be evaluated before or after or in between +runs, e.g. by including them in a :doc:`print ` command. -LAMMPS keeps track of all of this during a :doc:`run ` or :doc:`energy minimization `. An error will be generated if you -attempt to evaluate a variable on timesteps when it cannot produce -accurate values. For example, if a :doc:`thermo_style custom ` command prints a variable which accesses -values stored by a :doc:`fix ave/time ` command and the -timesteps on which thermo output is generated are not multiples of the -averaging frequency used in the fix command, then an error will occur. +LAMMPS keeps track of all of this as it performs a doc:`run ` or +:doc:`minimize ` simulation, as well as in between +simulations. An error will be generated if you attempt to evaluate a +variable when LAMMPS knows it cannot produce accurate values. For +example, if a :doc:`thermo_style custom ` command prints +a variable which accesses values stored by a :doc:`fix ave/time +` command and the timesteps on which thermo output is +generated are not multiples of the averaging frequency used in the fix +command, then an error will occur. -An input script can also request variables be evaluated before or -after or in between runs, e.g. by including them in a -:doc:`print ` command. In this case, if a compute is needed to -evaluate a variable (either directly or indirectly), LAMMPS will not -invoke the compute, but it will use a value previously calculated by -the compute, and can do this only if it was invoked on the current -timestep. Fixes will always provide a quantity needed by a variable, -but the quantity may or may not be current. This leads to one of -three kinds of behavior: +However, there are two special cases to be aware when a variable +requires invocation of a compute (directly or indirectly). The first +is if the variable is evaluated before the first doc:`run ` or +:doc:`minimize ` command in the input script. In this case, +LAMMPS will generate an error. This is because many computes require +initializations which have not yet taken place. One example is the +calculation of degrees of freedom for temperature computes. Another +example are the computes mentioned above which require tallying of +energy or virial quantities; these values are not tallied until the +first simulation begins. -(1) The variable may be evaluated accurately. If it contains -references to a compute or fix, and these values were calculated on -the last timestep of a preceding run, then they will be accessed and -used by the variable and the result will be accurate. +The second special case is when a variable that depends on a compute +is evaluated in between doc:`run ` or :doc:`minimize ` +commands. It is possible for other input script commands issued +following the previous run, but before the variable is evaluated, to +change the system. For example, the doc:`delete_atoms ` +command could be used to remove atoms. Since the compute will not +re-initialize itself until the next simulation or it may depend on +energy/virial computations performed before the system was changed, it +will potentially generate an incorrect answer when evaluated. Note +that LAMMPS will not generate an error in this case; the evaluated +variable may simply be incorrect. -(2) LAMMPS may not be able to evaluate the variable and will generate -an error message stating so. For example, if the variable requires a -quantity from a :doc:`compute ` that has not been invoked on -the current timestep, LAMMPS will generate an error. This means, for -example, that such a variable cannot be evaluated before the first run -has occurred. Likewise, in between runs, a variable containing a -compute cannot be evaluated unless the compute was invoked on the last -timestep of the preceding run, e.g. by thermodynamic output. - -One way to get around this problem is to perform a 0-timestep run -before using the variable. For example, these commands +The way to get around both of these special cases is to perform a +0-timestep run before evaluating the variable. For example, these +commands .. code-block:: LAMMPS - variable t equal temp - print "Initial temperature = $t" + # delete_atoms random fraction 0.5 yes all NULL 49839 + # run 0 + variable t equal temp # this thermo keyword invokes a temperature compute + print "Temperature of system = $t" run 1000 -will generate an error if the run is the first run specified in the -input script, because generating a value for the "t" variable requires -a compute for calculating the temperature to be invoked. +will generate an error if the "run 1000" command is the first +simulation in the input script. If there were a previous run, these +commands will print the correct temperature of the system. But if the +:doc:`delete_atoms ` command is uncommented, the printed +temperature will be incorrect, because information stored by +temperature compute is no longer valid. -However, this sequence of commands would be fine: - -.. code-block:: LAMMPS - - run 0 - variable t equal temp - print "Initial temperature = $t" - run 1000 - -The 0-timestep run initializes and invokes various computes, including -the one for temperature, so that the value it stores is current and -can be accessed by the variable "t" after the run has completed. Note -that a 0-timestep run does not alter the state of the system, so it -does not change the input state for the 1000-timestep run that -follows. Also note that the 0-timestep run must actually use and -invoke the compute in question (e.g. via :doc:`thermo ` or -:doc:`dump ` output) in order for it to enable the compute to be -used in a variable after the run. Thus if you are trying to print a -variable that uses a compute you have defined, you can ensure it is -invoked on the last timestep of the preceding run by including it in -thermodynamic output. - -Unlike computes, :doc:`fixes ` will never generate an error if -their values are accessed by a variable in between runs. They always -return some value to the variable. However, the value may not be what -you expect if the fix has not yet calculated the quantity of interest -or it is not current. For example, the :doc:`fix indent ` -command stores the force on the indenter. But this is not computed -until a run is performed. Thus if a variable attempts to print this -value before the first run, zeroes will be output. Again, performing -a 0-timestep run before printing the variable has the desired effect. - -(3) The variable may be evaluated incorrectly and LAMMPS may have no -way to detect this has occurred. Consider the following sequence of -commands: - -.. code-block:: LAMMPS - - pair_coeff 1 1 1.0 1.0 - run 1000 - pair_coeff 1 1 1.5 1.0 - variable e equal pe - print "Final potential energy = $e" - -The first run is performed using one setting for the pairwise -potential defined by the :doc:`pair_style ` and -:doc:`pair_coeff ` commands. The potential energy is -evaluated on the final timestep and stored by the :doc:`compute pe -` compute (this is done by the :doc:`thermo_style -` command). Then a pair coefficient is changed, -altering the potential energy of the system. When the potential -energy is printed via the "e" variable, LAMMPS will use the potential -energy value stored by the :doc:`compute pe ` compute, -thinking it is current. There are many other commands which could -alter the state of the system between runs, causing a variable to -evaluate incorrectly. - -The solution to this issue is the same as for case (2) above, namely -perform a 0-timestep run before the variable is evaluated to ensure -the system is up-to-date. For example, this sequence of commands -would print a potential energy that reflected the changed pairwise -coefficient: - -.. code-block:: LAMMPS - - pair_coeff 1 1 1.0 1.0 - run 1000 - pair_coeff 1 1 1.5 1.0 - run 0 - variable e equal pe - print "Final potential energy = $e" +Both these issues are resolved, if the "run 0" command is uncommented. +This is because the "run 0" simulation will initialize (or +re-initialize) the temperature compute correctly. ---------- @@ -1482,11 +1427,12 @@ Restrictions Indexing any formula element by global atom ID, such as an atom value, requires the :doc:`atom style ` to use a global mapping in order to look up the vector indices. By default, only atom styles -with molecular information create global maps. The :doc:`atom_modify map ` command can override the default, e.g. for +with molecular information create global maps. The :doc:`atom_modify +map ` command can override the default, e.g. for atomic-style atom styles. -All *universe*\ - and *uloop*\ -style variables defined in an input script -must have the same number of values. +All *universe*\ - and *uloop*\ -style variables defined in an input +script must have the same number of values. Related commands """""""""""""""" From 820899cd5e659938bf9f81a89118cb96ed029dfe Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 8 May 2023 11:38:27 -0400 Subject: [PATCH 171/448] use more obvious pair style dpd thermostat examples --- doc/src/pair_dpd.rst | 32 ++++++++++++++++++++++---------- doc/src/pair_dpd_ext.rst | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 21 deletions(-) diff --git a/doc/src/pair_dpd.rst b/doc/src/pair_dpd.rst index 815fe46cdc..4c8deab152 100644 --- a/doc/src/pair_dpd.rst +++ b/doc/src/pair_dpd.rst @@ -26,8 +26,8 @@ Syntax pair_style dpd T cutoff seed pair_style dpd/tstat Tstart Tstop cutoff seed -* T = temperature (temperature units) -* Tstart,Tstop = desired temperature at start/end of run (temperature units) +* T = temperature (temperature units) (dpd only) +* Tstart,Tstop = desired temperature at start/end of run (temperature units) (dpd/tstat only) * cutoff = global cutoff for DPD interactions (distance units) * seed = random # seed (positive integer) @@ -40,9 +40,9 @@ Examples pair_coeff * * 3.0 1.0 pair_coeff 1 1 3.0 1.0 1.0 - pair_style dpd/tstat 1.0 1.0 2.5 34387 - pair_coeff * * 1.0 - pair_coeff 1 1 1.0 1.0 + pair_style hybrid/overlay lj/cut 2.5 dpd/tstat 1.0 1.0 2.5 34387 + pair_coeff * * lj/cut 1.0 1.0 + pair_coeff * * dpd/tstat 1.0 Description """"""""""" @@ -53,7 +53,7 @@ Style *dpd* computes a force field for dissipative particle dynamics Style *dpd/tstat* invokes a DPD thermostat on pairwise interactions, which is equivalent to the non-conservative portion of the DPD force field. This pairwise thermostat can be used in conjunction with any -:doc:`pair style `, and in leiu of per-particle thermostats +:doc:`pair style `, and instead of per-particle thermostats like :doc:`fix langevin ` or ensemble thermostats like Nose Hoover as implemented by :doc:`fix nvt `. To use *dpd/tstat* as a thermostat for another pair style, use the @@ -105,14 +105,18 @@ commands: * :math:`\gamma` (force/velocity units) * cutoff (distance units) -The last coefficient is optional. If not specified, the global DPD +The cutoff coefficient is optional. If not specified, the global DPD cutoff is used. Note that sigma is set equal to sqrt(2 T gamma), where T is the temperature set by the :doc:`pair_style ` command so it does not need to be specified. For style *dpd/tstat*, the coefficients defined for each pair of -atoms types via the :doc:`pair_coeff ` command is the same, -except that A is not included. +atoms types via the :doc:`pair_coeff ` command are: + +* :math:`\gamma` (force/velocity units) +* cutoff (distance units) + +The cutoff coefficient is optional. The GPU-accelerated versions of these styles are implemented based on the work of :ref:`(Afshar) ` and :ref:`(Phillips) `. @@ -135,6 +139,12 @@ the work of :ref:`(Afshar) ` and :ref:`(Phillips) `. numbers are applied and thus the individual forces and therefore also the virial/pressure. +.. note:: + + For more consistent time integration and force computation you may + consider using :doc:`fix mvv/dpd ` instead of :doc:`fix + nve `. + ---------- .. include:: accel_styles.rst @@ -206,7 +216,9 @@ command for more details. Related commands """""""""""""""" -:doc:`pair_coeff `, :doc:`fix nvt `, :doc:`fix langevin `, :doc:`pair_style srp ` +:doc:`pair_style dpd/ext `, :doc:`pair_coeff `, +:doc:`fix nvt `, :doc:`fix langevin `, +:doc:`pair_style srp `, :doc:`fix mvv/dpd `. Default """"""" diff --git a/doc/src/pair_dpd_ext.rst b/doc/src/pair_dpd_ext.rst index 47c14fa813..1caed4689b 100644 --- a/doc/src/pair_dpd_ext.rst +++ b/doc/src/pair_dpd_ext.rst @@ -18,7 +18,6 @@ Accelerator Variants: dpd/ext/tstat/kk dpd/ext/tstat/omp Syntax """""" - .. code-block:: LAMMPS pair_style dpd/ext T cutoff seed @@ -32,16 +31,15 @@ Syntax Examples """""""" - .. code-block:: LAMMPS pair_style dpd/ext 1.0 2.5 34387 pair_coeff 1 1 25.0 4.5 4.5 0.5 0.5 1.2 pair_coeff 1 2 40.0 4.5 4.5 0.5 0.5 1.2 - pair_style dpd/ext/tstat 1.0 1.0 2.5 34387 - pair_coeff 1 1 4.5 4.5 0.5 0.5 1.2 - pair_coeff 1 2 4.5 4.5 0.5 0.5 1.2 + pair_style hybrid/overlay lj/cut 2.5 dpd/ext/tstat 1.0 1.0 2.5 34387 + pair_coeff * * lj/cut 1.0 1.0 + pair_coeff * * 4.5 4.5 0.5 0.5 1.2 Description """"""""""" @@ -128,20 +126,39 @@ the :doc:`pair_style ` command so it does not need to be specified. For the style *dpd/ext/tstat*, the coefficients defined for each pair of -atoms types via the :doc:`pair_coeff ` command is the same, -except that A is not included. +atoms types via the :doc:`pair_coeff ` command are: + +* :math:`\gamma_{\parallel}` (force/velocity units) +* :math:`\gamma_{\perp}` (force/velocity units) +* :math:`s_{\parallel}` (unitless) +* :math:`s_{\perp}` (unitless) +* :math:`r_c` (distance units) + +The last coefficient is optional. .. note:: If you are modeling DPD polymer chains, you may want to use the :doc:`pair_style srp ` command in conjunction with these pair - styles. It is a soft segmental repulsive potential (SRP) that can + styles. It is a soft segmental repulsive potential (SRP) that can prevent DPD polymer chains from crossing each other. .. note:: - The virial calculation for pressure when using this pair style includes - all the components of force listed above, including the random force. + The virial calculation for pressure when using these pair styles + includes all the components of force listed above, including the + random force. Since the random force depends on random numbers, + everything that changes the order of atoms in the neighbor list + (e.g. different number of MPI ranks or a different neighbor list + skin distance) will also change the sequence in which the random + numbers are applied and thus the individual forces and therefore + also the virial/pressure. + +.. note:: + + For more consistent time integration and force computation you may + consider using :doc:`fix mvv/dpd ` instead of :doc:`fix + nve `. ---------- @@ -207,7 +224,7 @@ Related commands :doc:`pair_style dpd `, :doc:`pair_coeff `, :doc:`fix nvt `, :doc:`fix langevin `, -:doc:`pair_style srp ` +:doc:`pair_style srp `, :doc:`fix mvv/dpd `. **Default:** none From a6310f170a3e1f40f012016be4804a1081e2a4eb Mon Sep 17 00:00:00 2001 From: ilia Nikiforov Date: Mon, 8 May 2023 18:37:51 -0500 Subject: [PATCH 172/448] streamlined scaling implementation --- src/KIM/pair_kim.cpp | 77 +++++++++++++++++++------------------------- src/KIM/pair_kim.h | 4 ++- 2 files changed, 36 insertions(+), 45 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 26996091dc..da9f574b02 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -138,8 +138,9 @@ PairKIM::PairKIM(LAMMPS *lmp) : kim_init_ok = false; kim_particle_codes_ok = false; - // scale parameter - scale = nullptr; + // scale parameter and whether to apply it + scale = 1.0; + scale_extracted = false; if (lmp->citeme) lmp->citeme->add(cite_openkim); } @@ -180,7 +181,6 @@ PairKIM::~PairKIM() memory->destroy(cutsq); delete[] lmps_map_species_to_unique; lmps_map_species_to_unique = nullptr; - memory->destroy(scale); } // clean up neighborlist pointers @@ -276,46 +276,37 @@ void PairKIM::compute(int eflag, int vflag) } } - // sloppy hack for scale - for (int i = 1; i < atom->ntypes+1; i++) + // scale results for fix adapt if needed + if (scale_extracted) { - for (int j = 1; j < atom->ntypes+1; j++) + if (eflag_global != 0) { - // comparing equality between floats, bad bad - if (scale[i][j] != scale[1][1]) + eng_vdwl *= scale; + } + if (vflag_global != 0) + { + for (int i = 0; i < 6; i++) { - error->all(FLERR,"Different scaling factors between different species pairs not supported"); + virial[i] *= scale; } } - } - double scale_all = scale[1][1]; - if (eflag_global != 0) - { - eng_vdwl *= scale_all; - } - if (vflag_global != 0) - { - for (int i = 0; i < 6; i++) - { - virial[i] *= scale_all; - } - } - for (int i = 0; i < nall; i++) - { - if (eflag_atom != 0) - { - eatom[i] *= scale_all; - } - if (vflag_atom != 0) - { - for (int j = 0; j < 6; j++) + for (int i = 0; i < nall; i++) + { + if (eflag_atom != 0) { - vatom[i][j] *= scale_all; + eatom[i] *= scale; + } + if (vflag_atom != 0) + { + for (int j = 0; j < 6; j++) + { + vatom[i][j] *= scale; + } + } + for (int j = 0; j < 3; j++) + { + atom->f[i][j] *= scale; } - } - for (int j = 0; j < 3; j++) - { - atom->f[i][j] *= scale_all; } } } @@ -336,8 +327,6 @@ void PairKIM::allocate() memory->create(cutsq,n+1,n+1,"pair:cutsq"); - memory->create(scale,n+1,n+1,"pair:scale"); - // allocate mapping array lmps_map_species_to_unique = new int[n+1]; @@ -441,7 +430,6 @@ void PairKIM::coeff(int narg, char **arg) setflag[i][j] = 1; count++; } - scale[i][j] = 1.0; } } @@ -660,9 +648,6 @@ double PairKIM::init_one(int i, int j) // "run ...", "minimize ...", etc. read from input if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set"); - //no need to initialize scale[i][j] = 1 if setflag==0, because that - //raises an error anyway - scale[j][i] = scale[i][j]; return kim_global_influence_distance; } @@ -1191,8 +1176,12 @@ std::string PairKIM::get_atom_type_list() { return atom_type_list; } void *PairKIM::extract(const char *str, int &dim) { - dim = 2; - if (strcmp(str,"scale") == 0) return (void *) scale; + dim = 0; + if (strcmp(str,"scale") == 0) + { + scale_extracted = true; + return (void *) &scale; + } return nullptr; } diff --git a/src/KIM/pair_kim.h b/src/KIM/pair_kim.h index 4ce302e1a9..55f70faad3 100644 --- a/src/KIM/pair_kim.h +++ b/src/KIM/pair_kim.h @@ -101,7 +101,9 @@ class PairKIM : public Pair { int settings_call_count; int init_style_call_count; - double **scale; + // scale factor for fix adapt, and whether or not it's been modified + double scale; + bool scale_extracted; // values set in settings() char *kim_modelname; From 9512568fd88de403c2311c0666ba3881f163e8f2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 9 May 2023 02:40:55 -0400 Subject: [PATCH 173/448] improve pair_coeff error message for pair styles derived from PairHybrid --- src/KOKKOS/pair_hybrid_overlay_kokkos.cpp | 2 +- src/pair_hybrid_overlay.cpp | 2 +- src/pair_hybrid_scaled.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp index cfdb9b7c63..387212f383 100644 --- a/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp +++ b/src/KOKKOS/pair_hybrid_overlay_kokkos.cpp @@ -60,7 +60,7 @@ void PairHybridOverlayKokkos::coeff(int narg, char **arg) int none = 0; if (m == nstyles) { if (strcmp(arg[2],"none") == 0) none = 1; - else error->all(FLERR,"Pair coeff for hybrid has invalid style"); + else error->all(FLERR,"Pair coeff for hybrid has invalid style: {}", arg[2]); } // move 1st/2nd args to 2nd/3rd args diff --git a/src/pair_hybrid_overlay.cpp b/src/pair_hybrid_overlay.cpp index 12c84c3a71..118403d345 100644 --- a/src/pair_hybrid_overlay.cpp +++ b/src/pair_hybrid_overlay.cpp @@ -60,7 +60,7 @@ void PairHybridOverlay::coeff(int narg, char **arg) int none = 0; if (m == nstyles) { if (strcmp(arg[2],"none") == 0) none = 1; - else error->all(FLERR,"Pair coeff for hybrid has invalid style"); + else error->all(FLERR,"Pair coeff for hybrid has invalid style: {}", arg[2]); } // move 1st/2nd args to 2nd/3rd args diff --git a/src/pair_hybrid_scaled.cpp b/src/pair_hybrid_scaled.cpp index 7cfc4a4c48..69ff037e4a 100644 --- a/src/pair_hybrid_scaled.cpp +++ b/src/pair_hybrid_scaled.cpp @@ -516,7 +516,7 @@ void PairHybridScaled::coeff(int narg, char **arg) if (strcmp(arg[2], "none") == 0) none = 1; else - error->all(FLERR, "Pair coeff for hybrid has invalid style"); + error->all(FLERR, "Pair coeff for hybrid has invalid style: {}", arg[2]); } // move 1st/2nd args to 2nd/3rd args From c54ff4380657f75a2d79d26e935e598a8a63a87f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 9 May 2023 02:41:21 -0400 Subject: [PATCH 174/448] compile time compatibility with swig 4.1 --- tools/swig/lammps.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i index 64f120bfb4..b7414573ba 100644 --- a/tools/swig/lammps.i +++ b/tools/swig/lammps.i @@ -18,7 +18,9 @@ %pointer_cast(void *, double *, void_p_to_double_p); %pointer_cast(void *, double **, void_p_to_double_2d_p); +#if !defined(SWIGLUA) %cstring_output_maxsize(char *buffer, int buf_size); +#endif %{ From 4c51264b150226df75438b863e6e6d471d3ab929 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 9 May 2023 08:24:02 -0400 Subject: [PATCH 175/448] explain how to keep pairs in the neighbor list even if the scaling factor should be 0.0 --- doc/src/special_bonds.rst | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/doc/src/special_bonds.rst b/doc/src/special_bonds.rst index 61c7976974..b1104d57cf 100644 --- a/doc/src/special_bonds.rst +++ b/doc/src/special_bonds.rst @@ -92,9 +92,24 @@ The Coulomb factors are applied to any Coulomb (charge interaction) term that the potential calculates. The LJ factors are applied to the remaining terms that the potential calculates, whether they represent LJ interactions or not. The weighting factors are a scaling -prefactor on the energy and force between the pair of atoms. A value -of 1.0 means include the full interaction; a value of 0.0 means -exclude it completely. +prefactor on the energy and force between the pair of atoms. + +A value of 1.0 means include the full interaction without flagging the +pair as a "special pair"; a value of 0.0 means exclude the pair +completely from the neighbor list, except for pair styles that require a +:doc:`kspace style ` and pair styles :doc:`amoeba +`, :doc:`hippo `, :doc:`thole `, +:doc:`coul/exclude `, and pair styles that include +"coul/dsf" or "coul/wolf". + +.. note:: + + To include pairs that would otherwise be excluded (so they are + included in the neighbor list for certain analysis compute styles), + you can use a very small but non-zero value like 1.0e-100 instead of + 0.0. Due to using floating-point math, the computed force, energy, + and virial contributions from the pairs will be too small to cause + differences. The first of the 3 coefficients (LJ or Coulombic) is the weighting factor on 1-2 atom pairs, which are pairs of atoms directly bonded to From ee5a3006438fb5a84c2ec1db09f279ccd3504add Mon Sep 17 00:00:00 2001 From: ilia Nikiforov Date: Tue, 9 May 2023 09:24:53 -0500 Subject: [PATCH 176/448] updated doc for kim adapt --- doc/src/fix_adapt.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/fix_adapt.rst b/doc/src/fix_adapt.rst index e26e9d3c28..86eec3eadb 100644 --- a/doc/src/fix_adapt.rst +++ b/doc/src/fix_adapt.rst @@ -163,6 +163,8 @@ formulas for the meaning of these parameters: +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`harmonic/cut ` | k, cutoff | type pairs | +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ +| :doc:`kim ` | scale | type global | ++------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`lennard/mdf ` | A,B | type pairs | +------------------------------------------------------------------------------+--------------------------------------------------+-------------+ | :doc:`lj/class2 ` | epsilon,sigma | type pairs | From f015aaff84d91fc8bf627e5d5fbb266c1970a1fe Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 9 May 2023 02:41:21 -0400 Subject: [PATCH 177/448] compile time compatibility with swig 4.1 --- tools/swig/lammps.i | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i index 64f120bfb4..b7414573ba 100644 --- a/tools/swig/lammps.i +++ b/tools/swig/lammps.i @@ -18,7 +18,9 @@ %pointer_cast(void *, double *, void_p_to_double_p); %pointer_cast(void *, double **, void_p_to_double_2d_p); +#if !defined(SWIGLUA) %cstring_output_maxsize(char *buffer, int buf_size); +#endif %{ From d2361ffe7d3460a010802a8fddbfe5c9f2d3e7f3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 10 May 2023 17:23:34 -0400 Subject: [PATCH 178/448] add workaround for reset_atoms image --- src/reset_atoms_image.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/reset_atoms_image.cpp b/src/reset_atoms_image.cpp index 56a1bf9f99..953c77f357 100644 --- a/src/reset_atoms_image.cpp +++ b/src/reset_atoms_image.cpp @@ -22,6 +22,7 @@ #include "group.h" #include "input.h" #include "modify.h" +#include "update.h" #include "variable.h" #include @@ -62,7 +63,10 @@ void ResetAtomsImage::command(int narg, char **arg) // initialize system since comm->borders() will be invoked + int old_whichflag = update->whichflag; + update->whichflag = 1; lmp->init(); + update->whichflag = old_whichflag; // setup domain, communication // exchange will clear map, borders will reset From a92e0030e81739b745c187bf5b92670daa975571 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 10 May 2023 17:24:29 -0400 Subject: [PATCH 179/448] whitespace --- doc/src/variable.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/variable.rst b/doc/src/variable.rst index d594b89859..26c5f0d445 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -1402,7 +1402,7 @@ commands .. code-block:: LAMMPS - # delete_atoms random fraction 0.5 yes all NULL 49839 + # delete_atoms random fraction 0.5 yes all NULL 49839 # run 0 variable t equal temp # this thermo keyword invokes a temperature compute print "Temperature of system = $t" From f74947a359d324e12f4a56eeabbc82bf7066bb86 Mon Sep 17 00:00:00 2001 From: Maximilian Maigler Date: Wed, 10 May 2023 15:15:10 -0700 Subject: [PATCH 180/448] Fixed read-in of initial electron temperature file --- src/EXTRA-FIX/fix_ttm_mod.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index b142a369a9..5d7ada74b6 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -601,9 +601,9 @@ void FixTTMMod::read_electron_temperatures(const std::string &filename) auto values = reader.next_values(4); ++nread; - int ix = values.next_int(); - int iy = values.next_int(); - int iz = values.next_int(); + int ix = values.next_int() - 1; + int iy = values.next_int() - 1; + int iz = values.next_int() - 1; double T_tmp = values.next_double(); // check correctness of input data From 7c4883704cef016f68f37ee52b82999c5b3a87a3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 10 May 2023 18:46:55 -0400 Subject: [PATCH 181/448] upgrade sphinx-tabs --- doc/utils/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/utils/requirements.txt b/doc/utils/requirements.txt index aa71e9c5f9..3f7bc065d0 100644 --- a/doc/utils/requirements.txt +++ b/doc/utils/requirements.txt @@ -2,7 +2,7 @@ Sphinx >= 5.3.0, <7.1.0 sphinxcontrib-spelling sphinxcontrib-jquery git+https://github.com/akohlmey/sphinx-fortran@parallel-read -sphinx_tabs +git+https://github.com/executablebooks/sphinx-tabs@v3.4.1 breathe Pygments six From 4c65aa572dfccbc2934b542582aee1cdec6803e8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 10 May 2023 18:48:47 -0400 Subject: [PATCH 182/448] Prefer custom python interpreter set via -DPython_EXECUTABLE if possible --- cmake/Modules/CodingStandard.cmake | 4 ++++ cmake/Modules/Documentation.cmake | 12 ++++++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cmake/Modules/CodingStandard.cmake b/cmake/Modules/CodingStandard.cmake index 6bb607be12..4efd373d22 100644 --- a/cmake/Modules/CodingStandard.cmake +++ b/cmake/Modules/CodingStandard.cmake @@ -5,6 +5,10 @@ if(CMAKE_VERSION VERSION_LESS 3.12) set(Python3_VERSION ${PYTHON_VERSION_STRING}) endif() else() + # use default (or custom) Python executable, if version is sufficient + if(Python_VERSION VERSION_GREATER_EQUAL 3.5) + set(Python3_EXECUTABLE ${Python_EXECUTABLE}) + endif() find_package(Python3 COMPONENTS Interpreter QUIET) endif() diff --git a/cmake/Modules/Documentation.cmake b/cmake/Modules/Documentation.cmake index 46295feea3..0b01407cd9 100644 --- a/cmake/Modules/Documentation.cmake +++ b/cmake/Modules/Documentation.cmake @@ -4,14 +4,18 @@ option(BUILD_DOC "Build LAMMPS HTML documentation" OFF) if(BUILD_DOC) - # Sphinx 3.x requires at least Python 3.5 + # Current Sphinx versions require at least Python 3.8 if(CMAKE_VERSION VERSION_LESS 3.12) - find_package(PythonInterp 3.5 REQUIRED) + find_package(PythonInterp 3.8 REQUIRED) set(VIRTUALENV ${PYTHON_EXECUTABLE} -m venv) else() + # use default (or custom) Python executable, if version is sufficient + if(Python_VERSION VERSION_GREATER_EQUAL 3.8) + set(Python3_EXECUTABLE ${Python_EXECUTABLE}) + endif() find_package(Python3 REQUIRED COMPONENTS Interpreter) - if(Python3_VERSION VERSION_LESS 3.5) - message(FATAL_ERROR "Python 3.5 and up is required to build the HTML documentation") + if(Python3_VERSION VERSION_LESS 3.8) + message(FATAL_ERROR "Python 3.8 and up is required to build the HTML documentation") endif() set(VIRTUALENV ${Python3_EXECUTABLE} -m venv) endif() From dd3d4e2b50f4cc08349f7c745aedff4461d93b48 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 10 May 2023 19:09:13 -0400 Subject: [PATCH 183/448] bump minimum requirement for building docs to python 3.8 --- doc/src/Build_manual.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/src/Build_manual.rst b/doc/src/Build_manual.rst index d86ad85827..e9a55134da 100644 --- a/doc/src/Build_manual.rst +++ b/doc/src/Build_manual.rst @@ -52,11 +52,11 @@ can be translated to different output format using the `Sphinx incorporates programmer documentation extracted from the LAMMPS C++ sources through the `Doxygen `_ program. Currently the translation to HTML, PDF (via LaTeX), ePUB (for many e-book readers) -and MOBI (for Amazon Kindle readers) are supported. For that to work a -Python 3 interpreter, the ``doxygen`` tools and internet access to -download additional files and tools are required. This download is -usually only required once or after the documentation folder is returned -to a pristine state with ``make clean-all``. +and MOBI (for Amazon Kindle(tm) readers) are supported. For that to work a +Python interpreter version 3.8 or later, the ``doxygen`` tools and +internet access to download additional files and tools are required. +This download is usually only required once or after the documentation +folder is returned to a pristine state with ``make clean-all``. For the documentation build a python virtual environment is set up in the folder ``doc/docenv`` and various python packages are installed into From 54b2a5c17af4ef5818cfa80d51851862f1f24a41 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 12 May 2023 09:04:42 -0600 Subject: [PATCH 184/448] allow internal variables in reset_atoms to be used before first run --- src/reset_atoms_image.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/reset_atoms_image.cpp b/src/reset_atoms_image.cpp index 953c77f357..d6f5acdeee 100644 --- a/src/reset_atoms_image.cpp +++ b/src/reset_atoms_image.cpp @@ -63,10 +63,7 @@ void ResetAtomsImage::command(int narg, char **arg) // initialize system since comm->borders() will be invoked - int old_whichflag = update->whichflag; - update->whichflag = 1; lmp->init(); - update->whichflag = old_whichflag; // setup domain, communication // exchange will clear map, borders will reset @@ -96,6 +93,13 @@ void ResetAtomsImage::command(int narg, char **arg) "c_ifmax_r_i_f[*] c_ifmin_r_i_f[*]"); // trigger computes + // need to ensure update->first_update = 1, even if prior to first run/minimize + // b/c variables internal to this command are evaulated which invoke computes + // error will be triggered unless first_update = 1 + // reset update->first_update when done + + int first_update_saved = update->first_update; + update->first_update = 1; frags->compute_peratom(); chunk->compute_peratom(); @@ -104,6 +108,8 @@ void ResetAtomsImage::command(int narg, char **arg) ifmax->compute_array(); cdist->compute_peratom(); + update->first_update = first_update_saved; + // reset image flags for atoms in group const int *const mask = atom->mask; From 9ef4d7f320d43941fbd29bc11277af9f6618d7b4 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 12 May 2023 09:06:29 -0600 Subject: [PATCH 185/448] allow internal variables in reset_atoms to be used before first run --- src/reset_atoms_image.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/reset_atoms_image.cpp b/src/reset_atoms_image.cpp index d6f5acdeee..b383f4a355 100644 --- a/src/reset_atoms_image.cpp +++ b/src/reset_atoms_image.cpp @@ -93,10 +93,11 @@ void ResetAtomsImage::command(int narg, char **arg) "c_ifmax_r_i_f[*] c_ifmin_r_i_f[*]"); // trigger computes - // need to ensure update->first_update = 1, even if prior to first run/minimize - // b/c variables internal to this command are evaulated which invoke computes - // error will be triggered unless first_update = 1 - // reset update->first_update when done + // need to ensure update->first_update = 1 + // to allow this input script command prior to first run/minimize + // this is b/c internal variables are evaulated which invoke computes + // that will trigger an error unless first_update = 1 + // reset update->first_update when done int first_update_saved = update->first_update; update->first_update = 1; From f1a3d0ce5a42227d85e59b3209f4dc981245745a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 11:14:34 -0400 Subject: [PATCH 186/448] whitespace --- src/reset_atoms_image.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/reset_atoms_image.cpp b/src/reset_atoms_image.cpp index b383f4a355..d39ea0fec1 100644 --- a/src/reset_atoms_image.cpp +++ b/src/reset_atoms_image.cpp @@ -98,7 +98,7 @@ void ResetAtomsImage::command(int narg, char **arg) // this is b/c internal variables are evaulated which invoke computes // that will trigger an error unless first_update = 1 // reset update->first_update when done - + int first_update_saved = update->first_update; update->first_update = 1; From b54d39adf9b39bd2f93cf2901f1af3816141e4e4 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Fri, 12 May 2023 11:18:07 -0600 Subject: [PATCH 187/448] minor editing changes --- doc/src/Modify.rst | 8 +- doc/src/Modify_contribute.rst | 148 ++++++++-------- doc/src/Modify_overview.rst | 83 ++++----- doc/src/Modify_requirements.rst | 303 ++++++++++++++++---------------- doc/src/Modify_style.rst | 143 +++++++-------- 5 files changed, 348 insertions(+), 337 deletions(-) diff --git a/doc/src/Modify.rst b/doc/src/Modify.rst index b10e307b14..0d7d4d6b97 100644 --- a/doc/src/Modify.rst +++ b/doc/src/Modify.rst @@ -10,15 +10,15 @@ functions and classes are given in :doc:`Developer`. If you add a new feature to LAMMPS and think it will be of general interest to other users, we encourage you to submit it for inclusion in LAMMPS. This process is explained in the following three pages: -:doc:`how to prepare and submit your code `, -:doc:`requirements for submissions `, and -:doc:`style guidelines `. + +* :doc:`how to prepare and submit your code ` +* :doc:`requirements for submissions ` +* :doc:`style guidelines ` A summary description of various types of styles in LAMMPS follows. A discussion of implementing specific styles from scratch is given in :doc:`writing new styles `. - .. toctree:: :maxdepth: 1 diff --git a/doc/src/Modify_contribute.rst b/doc/src/Modify_contribute.rst index 21bee1722b..8992e63c00 100644 --- a/doc/src/Modify_contribute.rst +++ b/doc/src/Modify_contribute.rst @@ -2,37 +2,40 @@ Submitting new features for inclusion in LAMMPS =============================================== We encourage LAMMPS users to submit new features they wrote for LAMMPS -to be included into the LAMMPS distribution and thus become easily -accessible to all LAMMPS users. The LAMMPS source code is managed with -git and public development is hosted on `GitHub -`_. You can monitor the repository to -be notified of releases, follow the ongoing development, and comment on -topics of interest to you. This section contains general information -regarding the preparation and submission of new features to LAMMPS. If -you are new to development in LAMMPS, we recommend you read one of the -tutorials on developing a new :doc:`pair style ` -or :doc:`fix style ` which provide a friendly -introduction to what LAMMPS development entails and common vocabulary -used in this chapter. +to be included in the LAMMPS distribution and thus become easily +accessible to all LAMMPS users. The LAMMPS source code is managed +with git and public development is hosted on `GitHub +`_. You can monitor the repository +to be notified of releases, follow the ongoing development, and +comment on topics of interest to you. + +This section contains general information regarding the preparation +and submission of new features to LAMMPS. If you are new to +development in LAMMPS, we recommend you read one of the tutorials on +developing a new :doc:`pair style ` or :doc:`fix +style ` which provide a friendly introduction to +what LAMMPS development entails and common vocabulary used on this +section. Communication with the LAMMPS developers ---------------------------------------- -For any larger modifications or programming project, you are encouraged -to contact the LAMMPS developers ahead of time to discuss implementation -strategies. That will make it easier to integrate your contribution and -results in less work for everybody involved. You are also encouraged to -search through the list of `open issues on GitHub -`_ and submit a new issue for a -planned feature, to avoid duplicating work (and possibly being scooped). +For any larger modifications or programming project, you are +encouraged to contact the LAMMPS developers ahead of time to discuss +implementation strategies. That will make it easier to integrate your +contribution and typically results in less work for everyone involved. +You are also encouraged to search through the list of `open issues on +GitHub `_ and submit a new +issue for a planned feature, to avoid duplicating work (and possibly +being scooped). For informal communication with the LAMMPS developers, you may ask to -join the `LAMMPS developers on Slack `_. This -slack work space is by invitation only. For access, please send an -e-mail to ``slack@lammps.org`` explaining what part of LAMMPS you are -working on. Only discussions related to LAMMPS development are -tolerated in that work space, so this is **NOT** for people that look +join the `LAMMPS developers on Slack `_. +This slack work space is by invitation only. For access, please send +an e-mail to ``slack@lammps.org`` explaining what part of LAMMPS you +are working on. Only discussions related to LAMMPS development are +tolerated in that work space, so this is **NOT** for people looking for help with compiling, installing, or using LAMMPS. Please post a message to the `LAMMPS forum `_ for those purposes. @@ -41,16 +44,17 @@ those purposes. Time and effort required ------------------------ -How quickly your contribution will be integrated can vary a lot. It -depends largely on how much effort it will cause the LAMMPS developers -to integrate and test it, how many and what kind of changes to the core -code are required, how quickly you can address them and of how much -interest it is to the larger LAMMPS community. This process can be -streamlined by following the :doc:`requirements ` -and :doc:`style guidelines`. A small, modular, well -written contribution may be integrated within hours, but a complex -change that requires a redesign of some core functionality in LAMMPS can -take months before inclusion (though this is rare). +How quickly your contribution will be integrated can vary widely. It +depends largely on how much effort is required by the LAMMPS +developers to integrate and test it, if any and what kind of changes +to the core code are required, how quickly you can address them, and +how much interest the contribution is to the larger LAMMPS +community. This process can be streamlined by following the +:doc:`requirements ` and :doc:`style +guidelines`. A small, modular, well written +contribution may be integrated within hours, but a complex change that +requires a re-design of a core functionality in LAMMPS can take months +before inclusion (though this is rare). Submission procedure @@ -60,21 +64,22 @@ All changes to LAMMPS (including those from LAMMPS developers) are integrated via pull requests on GitHub and cannot be merged without passing the automated testing and an approving review by a LAMMPS core developer. Before submitting your contribution, you should therefore -first make certain, that your added or modified code compiles and works -correctly with the latest development version of LAMMPS and contains all -bug fixes from it. +first ensure that your added or modified code compiles and works +correctly with the latest development version of LAMMPS and contains +all bug fixes from it. -Once you have prepared everything, see the :doc:`LAMMPS GitHub Tutorial -` page for instructions on how to submit your changes or -new files through a GitHub pull request. If you are unable or unwilling -to submit via GitHub yourself, you may also submit patch files or full -files to the LAMMPS developers and ask them to submit a pull request on -GitHub on your behalf. If this is the case, create a gzipped tar file -of all new or changed files or a corresponding patch file using 'diff --u' or 'diff -c' format and compress it with gzip. Please only use gzip -compression, as this works well and is available on all platforms. This -latter way of submission may delay the integration as it depends on the -LAMMPS developer having free time available. +Once you have prepared everything, see the :doc:`LAMMPS GitHub +Tutorial ` page for instructions on how to submit your +changes or new files through a GitHub pull request. If you are unable +or unwilling to submit via GitHub yourself, you may also send patch +files or full files to the `LAMMPS developers +`_ and ask them to submit a pull +request on GitHub on your behalf. If this is the case, create a +gzipped tar file of all new or changed files or a corresponding patch +file using 'diff -u' or 'diff -c' format and compress it with gzip. +Please only use gzip compression, as this works well and is available +on all platforms. This mode of submission may delay the integration +as it depends more on the LAMMPS developers. External contributions @@ -83,41 +88,42 @@ External contributions If you prefer to do so, you can also develop and support your add-on feature **without** having it included in the LAMMPS distribution, for example as a download from a website of your own. See the `External -LAMMPS packages and tools `_ page -of the LAMMPS website for examples of groups that do this. We are happy -to advertise your package and website from that page. Simply email the -`developers `_ with info about your -package, and we will post it there. We recommend naming external -packages USER-\ so they can be easily distinguished from bundled -packages that do not have the USER- prefix. +LAMMPS packages and tools `_ +page of the LAMMPS website for examples of groups that do this. We +are happy to advertise your package and website from that page. +Simply email the `developers `_ +with info about your package, and we will post it there. We recommend +naming external packages USER-\ so they can be easily +distinguished from packages in the LAMMPS distribution which do not +have the USER- prefix. Location of files: individual files and packages ------------------------------------------------ -We rarely accept new styles in the core src folder. Thus, please review -the list of :doc:`available Packages ` to see if your -contribution could be added to be added to one of them. It should fit +We rarely accept new styles in the core src folder. Thus, please +review the list of :doc:`available Packages ` to see +if your contribution should be added to one of them. It should fit into the general purpose of that package. If it does not fit well, it may be added to one of the EXTRA- packages or the MISC package. However, if your project includes many related features that are not covered by one of the existing packages or is dependent on a library -(bundled or external), it is best to create a package with its own -directory (labeled with a name like FOO). In addition to your new -files, the directory should contain a README text file containing your -name and contact information and a brief description of what your new -package does. +(bundled or external), it is best to create a new package with its own +directory (with a name like FOO). In addition to your new files, the +directory should contain a README text file containing your name and +contact information and a brief description of what your new package +does. Changes to core LAMMPS files -------------------------------- -If designed correctly, many additions do not require any changes to the -core code of LAMMPS; they are simply add-on files that are compiled with -the rest of LAMMPS. To make those styles work, you may need some -trivial changes to the core code; an example of a trivial change is -making a parent-class method "virtual" when you derive a new child class -from it. If your features involve changes to the core LAMMPS files, it -is particularly encouraged that you communicate with the LAMMPS -developers early in development. +If designed correctly, most additions do not require any changes to +the core code of LAMMPS; they are simply add-on files that are +compiled with the rest of LAMMPS. To make those styles work, you may +need some trivial changes to the core code. An example of a trivial +change is making a parent-class method "virtual" when you derive a new +child class from it. If your features involve more substantive +changes to the core LAMMPS files, it is particularly encouraged that +you communicate with the LAMMPS developers early in development. diff --git a/doc/src/Modify_overview.rst b/doc/src/Modify_overview.rst index a3d8e9737d..ab1fa43ed4 100644 --- a/doc/src/Modify_overview.rst +++ b/doc/src/Modify_overview.rst @@ -1,42 +1,44 @@ Overview ======== -The best way to add a new feature to LAMMPS is to find a similar feature -and look at the corresponding source and header files to figure out what -it does. You will need some knowledge of C++ to be able to understand -the high-level structure of LAMMPS and its class organization. -Functions (class methods) that do actual computations are mostly written -in C-style code and operate on simple C-style data structures (vectors -and arrays). A high-level overview of the programming style choices in -LAMMPS is :doc:`given elsewhere `. +The best way to add a new feature to LAMMPS is to find a similar +feature and look at the corresponding source and header files to +figure out what it does. You will need some knowledge of C++ to +understand the high-level structure of LAMMPS and its class +organization. Functions (class methods) that do actual computations +are mostly written in C-style code and operate on simple C-style data +structures (vectors and arrays). A high-level overview of the +programming style choices in LAMMPS is :doc:`given elsewhere +`. Most of the new features described on the :doc:`Modify ` doc -page require you to write a new C++ derived class (except for exceptions -described below, where you can make small edits to existing files). -Creating a new class requires 2 files, a source code file (\*.cpp) and a -header file (\*.h). The derived class must provide certain methods to -work as a new option. Depending on how different your new feature is -compared to existing features, you can either derive from the base class -itself, or from a derived class that already exists. Enabling LAMMPS to -invoke the new class is as simple as putting the two source files in the -src directory and re-building LAMMPS. +page require you to write a new C++ derived class (except for +exceptions described below, where you can make small edits to existing +files). Creating a new class requires 2 files, a source code file +(\*.cpp) and a header file (\*.h). The derived class must provide +certain methods to work as a new option. Depending on how different +your new feature is compared to existing features, you can either +derive from the base class itself, or from a derived class that +already exists. Enabling LAMMPS to invoke the new class is as simple +as putting the two source files in the src directory and re-building +LAMMPS. -The advantage of C++ and its object-orientation is that all the code and -variables needed to define the new feature are in the 2 files you write. -Thus, it should not make the rest of LAMMPS more complex or cause bugs -through unwanted side effects. +The advantage of C++ and its object-orientation is that all the code +and variables needed to define the new feature are in the 2 files you +write. Thus, it should not make the rest of LAMMPS more complex or +cause bugs through unwanted side effects. -Here is a concrete example. Suppose you write 2 files ``pair_foo.cpp`` -and ``pair_foo.h`` that define a new class ``PairFoo`` that computes -pairwise potentials described in the classic 1997 :ref:`paper ` by -Foo, *et al.* If you wish to invoke those potentials in a LAMMPS input -script with a command like: +Here is a concrete example. Suppose you write 2 files +``pair_foo.cpp`` and ``pair_foo.h`` that define a new class +``PairFoo`` which computes pairwise potentials described in the +classic 1997 :ref:`paper ` by Foo, *et al.* If you wish to invoke +those potentials in a LAMMPS input script with a command like: .. code-block:: LAMMPS pair_style foo 0.1 3.5 -Then your ``pair_foo.h`` file should be structured as follows: +then your ``pair_foo.h`` file should be structured as follows: .. code-block:: c++ @@ -59,20 +61,19 @@ the executable and can be invoked with a pair_style command like the example above. Arguments like 0.1 and 3.5 can be defined and processed by your new class. -As illustrated by this example pair style, many kinds of options are -referred to in the LAMMPS documentation as the "style" of a particular -command. +As illustrated by this example, many features referred to in the +LAMMPS documentation are called a "style" of a particular command. The :doc:`Modify page ` lists all the common styles in LAMMPS, -and discusses the header file for the base class that these styles are -derived from. Public variables in that file are ones used and set by -the derived classes, which are also used by the base class. Sometimes -they are also used by the rest of LAMMPS. Pure functions, which means -functions declared as virtual in the base class header file which are -also set to 0, are functions you **must** implement in your new derived -class to give it the functionality LAMMPS expects. Virtual functions -that are not set to 0 are functions you may override or not. Those -are usually defined with an empty function body. +and discusses the header file for the base class that these styles +derive from. Public variables in that file can be used and set by the +derived classes, and may also be used by the base class. Sometimes +they are also accessed by the rest of LAMMPS. Pure functions, which +means functions declared as virtual in the base class header file and +which are also set to 0, are functions you **must** implement in your +new derived class to give it the functionality LAMMPS expects. Virtual +functions that are not set to 0 are functions you may override or not. +Those are usually defined with an empty function body. Additionally, new output options can be added directly to the thermo.cpp, dump_custom.cpp, and variable.cpp files. These are also @@ -86,8 +87,8 @@ functionality: quickly done that way. * Do not try to do anything within the timestepping of a run that is not parallel. For example, do not accumulate a bunch of data on a single - processor and analyze it. You run the risk of seriously degrading - the parallel efficiency this way. + processor and analyze it. That would run the risk of seriously degrading + the parallel efficiency. * If your new feature reads arguments or writes output, make sure you follow the unit conventions discussed by the :doc:`units ` command. diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 9d5ffd38b2..15edafb26c 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -10,23 +10,23 @@ Motivation The LAMMPS developers are committed to provide a software package that is versatile, reliable, high-quality, efficient, portable, and easy to -maintain and modify. Achieving all of these goals is challenging since -a large part of LAMMPS consists of contributed code from many different -authors and not many of them are professionally trained programmers and +maintain and modify. Achieving all of these goals is challenging +since a large part of LAMMPS consists of contributed code from many +different authors who may not be professionally trained programmers or familiar with the idiosyncrasies of maintaining a large software package. In addition, changes that interfere with the parallel efficiency of the core code must be avoided. As LAMMPS continues to -grow and more features and functionality are added, it becomes a -necessity to be more discriminating with new contributions while also -working at the same time to improve the existing code. +grow and more features and functionality are added, it's necessary to +follow established guidelines when accepting new contributions while +also working at the same time to improve the existing code. -The following requirements and recommendations are provided as a guide -to maintain or improve that status. It is indicated which individual -requirements are strict, and which represent a preference and thus are -negotiable or optional. Please feel free to contact the LAMMPS core -developers in case you need additional explanations or clarifications, -or in case you need assistance in realizing the (strict) requirements -for your contributions. Requirements include: +The following requirements and recommendations are provided as a +guide. They indicate which individual requirements are strict, and +which represent a preference and thus are negotiable or optional. +Please feel free to contact the LAMMPS core developers in case you +need additional explanations or clarifications, or you need assistance +in implementing the (strict) requirements for your contributions. +Requirements include: * :ref:`Licensing requirements ` (strict) * :ref:`Integration testing ` (strict) @@ -48,44 +48,44 @@ Licensing requirements (strict) Contributing authors agree when submitting a pull request that their contributions can be distributed under the LAMMPS license conditions. This is the GNU public license in version 2 (not 3 or later) for the -publicly distributed versions, e.g. on the LAMMPS homepage or on GitHub. -We also make a version of LAMMPS under LGPL 2.1 terms available on -request; this will usually be the latest available or a previous stable -version with a few LGPL 2.1 incompatible files removed. More details -are found on the :doc:`LAMMPS open-source license page -`. +publicly distributed versions, e.g. on the LAMMPS homepage or on +GitHub. We also make a version of LAMMPS under LGPL 2.1 terms whcih +is available on request; this will usually be the latest available or +a previous stable version with a few LGPL 2.1 incompatible files +removed. More details are found on the :doc:`LAMMPS open-source +license page `. -Your new source files should have the LAMMPS copyright, GPL notice, and -your name and email address at the top, like other user-contributed -LAMMPS source files. +Your new source files should have the LAMMPS copyright and GPL notice, +followed by your name and email address at the top, like other +user-contributed LAMMPS source files. -Contributions may be under a different license as long as that -license does not conflict with the aforementioned terms. Contributions -that use code with a conflicting license can be split into two parts: +Contributions may be under a different license as long as that license +does not conflict with the aforementioned terms. Contributions that +use code with a conflicting license can be split into two parts: 1. the core parts (i.e. parts that must be in the `src` tree) that are licensed under compatible terms and bundled with the LAMMPS sources 2. an external library that must be downloaded and compiled (either separately or as part of the LAMMPS compilation) -Please note, that this split licensed mode may complicate including the -contribution in binary packages. +Please note, that this split licensing mode may complicate including +the contribution in binary packages. .. _ReqIntegrationTesting: Integration testing (strict) ---------------------------- -Where possible we utilize available continuous integration tools to -search for common programming mistakes, portability limitations, -incompatible formatting, and undesired side effects. Contributed code -must pass the automated tests on GitHub before it can be merged with -the LAMMPS distribution. These tests compile LAMMPS in a variety of -environments and settings and run the bundled unit tests. At the -discretion of the LAMMPS developer managing the pull request, -additional tests may be activated that test for "side effects" on -running a collection of input decks and create consistent results. -The translation of the documentation to HTML and PDF is also tested. +Where possible we use available continuous integration tools to search +for common programming mistakes, portability limitations, incompatible +formatting, and undesired side effects. Contributed code must pass the +automated tests on GitHub before it can be merged with the LAMMPS +distribution. These tests compile LAMMPS in a variety of environments +and settings and run the bundled unit tests. At the discretion of the +LAMMPS developer managing the pull request, additional tests may be +activated that test for "side effects" on running a collection of +input decks and create consistent results. The translation of the +documentation to HTML and PDF is also tested. This means that contributed source code **must** compile with the most current version of LAMMPS with ``-DLAMMPS_BIGBIG`` in addition to the @@ -94,8 +94,8 @@ correctly in both cases, and also in serial and parallel using MPI. Some "disruptive" changes may break tests and require updates to the testing tools or scripts or tests themselves. This is rare. If in -doubt, contact the LAMMPS developer that is assigned to the pull request. - +doubt, contact the LAMMPS developer that is assigned to the pull +request. .. _ReqDocumentation: @@ -105,60 +105,62 @@ Documentation (strict) Contributions that add new styles or commands or augment existing ones must include the corresponding new or modified documentation in `ReStructuredText format `_ (.rst files in the ``doc/src/`` -folder). The documentation shall be written in American English and the -.rst file must use only ASCII characters, so it can be cleanly translated -to PDF files (via `sphinx `_ and PDFLaTeX). -Special characters may be included via embedded math expression typeset -in a LaTeX subset. +folder). The documentation should be written in American English and +the .rst file must only ues ASCII characters, so it can be cleanly +translated to PDF files (via `sphinx `_ +and PDFLaTeX). Special characters may be included via embedded math +expression typeset in a LaTeX subset. .. _rst: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html When adding new commands, they need to be integrated into the sphinx documentation system, and the corresponding command tables and lists -updated. When translating the documentation into html files there should -be no warnings. When adding a new package also some lists describing -packages must be updated as well as a package specific description added -and, if necessary, some package specific build instructions included. +updated. When translating the documentation into html files there +should be no warnings. When adding a new package, some lists +describing packages must also be updated as well as a package specific +description added. Likewise, if necessary, some package specific +build instructions should be included. -As appropriate, the text files with the documentation can include inline -mathematical expressions or figures (see ``doc/JPG`` for examples). -Additional PDF files with further details (see ``doc/PDF`` for examples) -may also be included. The page should also include literature citations -as appropriate; see the bottom of ``doc/fix_nh.rst`` for examples and -the earlier part of the same file for how to format the cite itself. -Citation labels must be unique across **all** .rst files. The -"Restrictions" section of the page should indicate if your command is -only available if LAMMPS is built with the appropriate FOO package. See -other package doc files for examples of how to do this. +As appropriate, the text files with the documentation can include +inline mathematical expressions or figures (see ``doc/JPG`` for +examples). Additional PDF files with further details may also be +included; see ``doc/PDF`` for examples. The page should also include +literature citations as appropriate; see the bottom of +``doc/fix_nh.rst`` for examples and the earlier part of the same file +for how to format the cite itself. Citation labels must be unique +across **all** .rst files. The "Restrictions" section of the page +should indicate if your command is only available if LAMMPS is built +with the appropriate package. See other command doc files for +examples of how to do this. -Please run at least "make html" and "make spelling" and carefully -inspect and proofread the resulting HTML format doc page before -submitting your code. Upon submission of a pull request, checks for -error free completion of the HTML and PDF build will be performed and -also a spell check, a check for correct anchors and labels, and a check -for completeness of references to all styles in their corresponding -tables and lists is run. In case the spell check reports false -positives, they can be added to the file +Please run at least "make html" and "make spelling" from within the +doc/src directory, and carefully inspect and proofread the resulting +HTML format doc page before submitting your code. Upon submission of +a pull request, checks for error free completion of the HTML and PDF +build will be performed and also a spell check, a check for correct +anchors and labels, and a check for completeness of references to all +styles in their corresponding tables and lists is run. In case the +spell check reports false positives, they can be added to the file ``doc/utils/sphinx-config/false_positives.txt`` -Contributions that add or modify the library interface or "public" APIs -from the C++ code or the Fortran module must include suitable doxygen -comments in the source and corresponding changes to the documentation -sources for the "Programmer Guide" guide section of the LAMMPS manual. +Contributions that add or modify the library interface or "public" +APIs from the C++ code or the Fortran module must include suitable +doxygen comments in the source and corresponding changes to the +documentation sources for the "Programmer Guide" guide section of the +LAMMPS manual. -If your feature requires some more complex steps and explanations to be -used correctly or some external or bundled tools or scripts, we +If your feature requires some more complex steps and explanations to +be used correctly or some external or bundled tools or scripts, we recommend that you also contribute a :doc:`Howto document ` providing some more background information and some tutorial material. -This can also be used to provide more in-depth explanations for bundled -examples. +This can also be used to provide more in-depth explanations of models +that require use of multiple commands. -As a rule-of-thumb, the more clear and self-explanatory you make -your documentation, README files and examples, and the easier you make -it for people to get started, the more likely it is that users will try +As a rule-of-thumb, the more clear and self-explanatory you make your +documentation, README files and examples, and the easier you make it +for people to get started, the more likely it is that users will try out your new feature. - .. _ReqProgrammingStandards: Programming language standards (strict) @@ -166,30 +168,29 @@ Programming language standards (strict) The core of LAMMPS is written in C++11 in a style that can be mostly described as "C with classes". Advanced C++ features like operator -overloading or excessive use of templates are avoided with the intent to -keep the code readable to programmers that have limited C++ programming -experience. C++ constructs are acceptable when they help improve the -readability and reliability of the code, e.g. when using the -`std::string` class instead of manipulating pointers and calling the -string functions of the C library. In addition, a collection of +overloading or excessive use of templates are avoided with the intent +to keep the code readable to programmers that have limited C++ +programming experience. C++ constructs are acceptable when they help +improve the readability and reliability of the code, e.g. when using +the `std::string` class instead of manipulating pointers and calling +the string functions of the C library. In addition, a collection of convenient :doc:`utility functions and classes ` for -recurring tasks and a collection of -:doc:`platform neutral functions ` for improved -portability are provided. +recurring tasks and a collection of :doc:`platform neutral functions +` for improved portability are provided. Included Fortran code has to be compatible with the Fortran 2003 -standard. Python code must be compatible with Python 3.5. Large parts -of LAMMPS (including the :ref:`PYTHON package `) are also -compatible with Python 2.7. Compatibility with Python 2.7 is +standard. Python code must be compatible with Python 3.5. Large +parts of LAMMPS (including the :ref:`PYTHON package `) are +also compatible with Python 2.7. Compatibility with Python 2.7 is desirable, but compatibility with Python 3.5 is **required**. Compatibility with these older programming language standards is very important to maintain portability and availability of LAMMPS on many platforms. This applies especially to HPC cluster environments, which -tend to be running older software stacks and LAMMPS users may be +tend to be running older software stacks and where LAMMPS users may be required to use those older tools for access to advanced hardware -features or not have the option to install newer compilers or libraries. - +features or not have the option to install newer compilers or +libraries. .. _ReqBuildSystem: @@ -206,18 +207,19 @@ independent feature, it is usually only required to add them to `src/.gitignore``. For traditional make, if your contributed files or package depend on -other LAMMPS style files or packages also being installed (e.g. because -your file is a derived class from the other LAMMPS class), then an -Install.sh file is also needed to check for those dependencies and -modifications to src/Depend.sh to trigger the checks. See other README -and Install.sh files in other directories as examples. +other LAMMPS style files or packages also being installed +(e.g. because your file is a derived class from the other LAMMPS +class), then an Install.sh file is also needed to check for those +dependencies and modifications to src/Depend.sh to trigger the checks. +See other README and Install.sh files in other directories as +examples. Similarly, for CMake support, changes may need to be made to -cmake/CMakeLists.txt, some of the files in cmake/presets, and possibly a -file with specific instructions needs to be added to +cmake/CMakeLists.txt, some of the files in cmake/presets, and possibly +a file with specific instructions needs to be added to cmake/Modules/Packages/. Please check out how this is handled for -existing packages and ask the LAMMPS developers if you need assistance. - +existing packages and ask the LAMMPS developers if you need +assistance. .. _ReqNaming: @@ -229,33 +231,33 @@ should only use letters, numbers, or forward slashes. They should be descriptive and initialisms should be avoided unless they are well established (e.g. lj for Lennard-Jones). For a compute style "some/name" the source files must be called `compute_some_name.h` and -`compute_some_name.cpp`. The "include guard" would then be -`LMP_COMPUTE_SOME_NAME_H` and the class name `ComputeSomeName`. - +`compute_some_name.cpp`. The "include guard" in the header file would +then be `LMP_COMPUTE_SOME_NAME_H` and the class name +`ComputeSomeName`. .. _ReqProgrammingStyle: Programming style requirements (varied) --------------------------------------- -To maintain consistency across contributions from many people, there are -various programming style requirements for contributions to LAMMPS. -Some of these requirements are strict and must be followed, while others -are only preferred and thus may be skipped. An in-depth discussion of -the style guidelines is provided in the :doc:`programming style doc -page `. - +To maintain source code consistency across contributions from many +people, there are various programming style requirements for +contributions to LAMMPS. Some of these requirements are strict and +must be followed, while others are only preferred and thus may be +skipped. An in-depth discussion of the style guidelines is provided +in the :doc:`programming style doc page `. .. _ReqExamples: Examples (preferred) -------------------- -In most cases, it is preferred that example scripts (simple, small, fast -to complete on 1 CPU) are included that demonstrate the use of new or -extended functionality. These are typically under the examples or -examples/PACKAGES directory are further described on the :doc:`examples -page `. Guidelines for input scripts include: +For many new features, it is preferred that example scripts (simple, +small, fast to complete on 1 CPU) are included that demonstrate the +use of new or extended functionality. These are typically include +under the examples or examples/PACKAGES directory and are further +described on the :doc:`examples page `. Guidelines for +input scripts include: - commands that generate output should be commented out (except when the output is the sole purpose or the feature, e.g. for a new compute) @@ -279,7 +281,6 @@ page `. Guidelines for input scripts include: - where possible, potential files from the "potentials" folder or data file from other folders should be re-used through symbolic links - .. _ReqErrorMessages: Error or warning messages and explanations (preferred) @@ -321,13 +322,12 @@ commands and that may create :ref:`"Unknown identifier in data file" ` errors that may have multiple possible reasons which complicates debugging, and thus require some additional explanation. -The transformation of existing LAMMPS code to this new scheme is ongoing -and - given the size of the LAMMPS source code - will take a significant -amount of time until completion. For new code, however, following the -new approach is strongly preferred. The expectation is that the new -scheme will make it easier for LAMMPS users, developers, and -maintainers. - +The transformation of existing LAMMPS code to this new scheme is +ongoing. Given the size of the LAMMPS code base, it will take a +significant amount of time to complete. For new code, however, +following the new approach is strongly preferred. The expectation is +that the new scheme will make understanding errors easier for LAMMPS +users, developers, and maintainers. .. _ReqCitation: @@ -338,38 +338,39 @@ If there is a paper of yours describing your feature (either the algorithm/science behind the feature itself, or its initial usage, or its implementation in LAMMPS), you can add the citation to the \*.cpp source file. See ``src/DIFFRACTION/compute_saed.cpp`` for an example. -A BibTeX format citation is stored in a string variable at the top -of the file, and a single line of code registering this variable is -added to the constructor of the class. When your feature is used, -by default, LAMMPS will print the brief info and the DOI -in the first line to the screen and the full citation to the log file. +A BibTeX format citation is stored in a string variable at the top of +the file, and a single line of code registering this variable is added +to the constructor of the class. When your feature is used, then +LAMMPS (by default) will print the brief info and the DOI in the first +line to the screen and the full citation to the log file. If there is additional functionality (which may have been added later) described in a different publication, additional citation descriptions -may be added for as long as they are only registered when the -corresponding keyword activating this functionality is used. With these -options, it is possible to have LAMMPS output a specific citation -reminder whenever a user invokes your feature from their input script. -Please note that you should *only* use this for the *most* relevant -paper for a feature and a publication that you or your group authored. -E.g. adding a citation in the code for a paper by Nose and Hoover if you -write a fix that implements their integrator is not the intended usage. -That latter kind of citation should just be included in the -documentation page you provide describing your contribution. If you are -not sure what the best option would be, please contact the LAMMPS -developers for advice. +may be added so long as they are only registered when the +corresponding keyword activating this functionality is used. + +With these options, it is possible to have LAMMPS output a specific +citation reminder whenever a user invokes your feature from their +input script. Please note that you should *only* use this for the +*most* relevant paper for a feature and a publication that you or your +group authored. E.g. adding a citation in the source code for a paper +by Nose and Hoover if you write a fix that implements their integrator +is not the intended usage. That kind of citation should just be +included in the documentation page you provide describing your +contribution. If you are not sure what the best option would be, +please contact the LAMMPS developers for advice. .. _ReqUnitTesting: Testing (optional) ------------------ -If your contribution contains new utility functions or a supporting class -(i.e. anything that does not depend on a LAMMPS object), new unit tests -should be added to a suitable folder in the ``unittest`` tree. -When adding a new LAMMPS style computing forces or selected fixes, -a ``.yaml`` file with a test configuration and reference data should be -added for the styles where a suitable tester program already exists -(e.g. pair styles, bond styles, etc.). Please see -:ref:`this section in the manual ` for more information on -how to enable, run, and expand testing. +If your contribution contains new utility functions or a supporting +class (i.e. anything that does not depend on a LAMMPS object), new +unit tests should be added to a suitable folder in the ``unittest`` +tree. When adding a new LAMMPS style computing forces or selected +fixes, a ``.yaml`` file with a test configuration and reference data +should be added for the styles where a suitable tester program already +exists (e.g. pair styles, bond styles, etc.). Please see :ref:`this +section in the manual ` for more information on how to +enable, run, and expand testing. diff --git a/doc/src/Modify_style.rst b/doc/src/Modify_style.rst index b853ccd721..4da8501f12 100644 --- a/doc/src/Modify_style.rst +++ b/doc/src/Modify_style.rst @@ -1,55 +1,58 @@ LAMMPS programming style ======================== -The LAMMPS developers aim to employ a consistent programming style and -naming conventions across the entire code base, as this helps with -maintenance, debugging, and understanding the code, both for developers -and users. This page provides a list of standard style choices used in -LAMMPS. Some of these standards are required, while others are just -preferred. Following these conventions will make it much easier to -integrate your contribution. If you are uncertain, please ask. +The aim of the LAMMPS developers is to use a consistent programming +style and naming conventions across the entire code base, as this +helps with maintenance, debugging, and understanding the code, both +for developers and users. This page provides a list of standard style +choices used in LAMMPS. Some of these standards are required, while +others are just preferred. Following these conventions will make it +much easier to integrate your contribution. If you are uncertain, +please ask. -The files `pair_lj_cut.h`, `pair_lj_cut.cpp`, `utils.h`, and `utils.cpp` -may serve as representative examples. +The files `pair_lj_cut.h`, `pair_lj_cut.cpp`, `utils.h`, and +`utils.cpp` may serve as representative examples. Include files (varied) ^^^^^^^^^^^^^^^^^^^^^^ - Header files that define a new LAMMPS style (i.e. that have a - ``SomeStyle(some/name,SomeName);`` macro in them) should only use the - include file for the base class and otherwise use forward declarations - and pointers; when interfacing to a library use the PIMPL (pointer - to implementation) approach where you have a pointer to a struct - that contains all library specific data (and thus requires the library - header) but use a forward declaration and define the struct only in - the implementation file. This is a **strict** requirement since this - is where type clashes between packages and hard to find bugs have - regularly manifested in the past. + ``SomeStyle(some/name,SomeName);`` macro in them) should only use + the include file for the base class and otherwise use forward + declarations and pointers; when interfacing to a library use the + PIMPL (pointer to implementation) approach where you have a pointer + to a struct that contains all library specific data (and thus + requires the library header) but use a forward declaration and + define the struct only in the implementation file. This is a + **strict** requirement since this is where type clashes between + packages and hard-to-find bugs have regularly manifested in the + past. -- Header files, especially those defining a "style", should only use the - absolute minimum number of include files and **must not** contain any - ``using`` statements. Typically, that would be only the header for the - base class. Instead, any include statements should be put into the - corresponding implementation files and forward declarations be used. - For implementation files, the "include what you use" principle should - be employed. However, there is the notable exception that when the - ``pointers.h`` header is included (or one of the base classes derived - from it) certain headers will always be included and thus do not need - to be explicitly specified. These are: `mpi.h`, `cstddef`, `cstdio`, - `cstdlib`, `string`, `utils.h`, `vector`, `fmt/format.h`, `climits`, - `cinttypes`. This also means any such file can assume that `FILE`, - `NULL`, and `INT_MAX` are defined. +- Header files, especially those defining a "style", should only use + the absolute minimum number of include files and **must not** + contain any ``using`` statements. Typically, that would only be the + header for the base class. Instead, any include statements should + be put in the corresponding implementation files and forward + declarations be used. For implementation files, the "include what + you use" principle should be employed. However, there is the + notable exception that when the ``pointers.h`` header is included + (or one of the base classes derived from it) certain headers will + always be included and thus do not need to be explicitly specified. + These are: `mpi.h`, `cstddef`, `cstdio`, `cstdlib`, `string`, + `utils.h`, `vector`, `fmt/format.h`, `climits`, `cinttypes`. This + also means any such file can assume that `FILE`, `NULL`, and + `INT_MAX` are defined. -- System headers or from installed libraries are include with angular - brackets (example: ``#include ``), while local include files - use double quotes (example: ``#include "atom.h"``) +- System headers or headers from installed libraries are included with + angular brackets (example: ``#include ``), while local + include files use double quotes (example: ``#include "atom.h"``) - When including system header files from the C library use the - C++-style names (```` or ````) instead of the - C-style names (```` or ````) + C++-style names (```` or ````) instead of the + C-style names (```` or ````) -- The order of ``#include`` statements in a file ``some_name.cpp`` that - implements a class ``SomeName`` defined in a header file +- The order of ``#include`` statements in a file ``some_name.cpp`` + that implements a class ``SomeName`` defined in a header file ``some_name.h`` should be as follows: - ``#include "some_name.h"`` followed by an empty line @@ -62,25 +65,23 @@ Include files (varied) - ``using namespace LAMMPS_NS`` or other namespace imports. - Whitespace (preferred) ^^^^^^^^^^^^^^^^^^^^^^ Source files should not contain TAB characters unless required by the syntax (e.g. in makefiles) and no trailing whitespace. Text files -should be added with Unix-style line endings (LF-only). Git will -automatically convert those in both directions when running on Windows; -use dos2unix on Linux machines to convert files. Text files should have -a line ending on the last line. +should have Unix-style line endings (LF-only). Git will automatically +convert those in both directions when running on Windows; use dos2unix +on Linux machines to convert files to Unix-style line endings. The +last line of text files include a line ending. You can check for these issues with the python scripts in the :ref:`"tools/coding_standard" ` folder. When run normally with a source file or a source folder as argument, they will list all non-conforming lines. By adding the `-f` flag to the command -line, they will modify the flagged files to try removing the detected +line, they will modify the flagged files to try to remove the detected issues. - Placement of braces (strongly preferred) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -89,12 +90,11 @@ For new files added to the "src" tree, a `clang-format provided under the name `.clang-format`. This file is compatible with clang-format version 8 and later. With that file present, files can be reformatted according to the configuration with a command like: -`clang-format -i new-file.cpp`. Ideally, this is done while writing the -code or before a pull request is submitted. Blocks of code where the -reformatting from clang-format yields undesirable output may be -protected with placing a pair `// clang-format off` and `// clang-format -on` comments around that block. - +`clang-format -i new-file.cpp`. Ideally, this is done while writing +the code or before a pull request is submitted. Blocks of code where +the reformatting from clang-format yields hard-to-read or otherwise +undesirable output may be protected with placing a pair `// +clang-format off` and `// clang-format on` comments around that block. Miscellaneous standards (varied) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -104,24 +104,26 @@ Miscellaneous standards (varied) - Do not use so-called "alternative tokens" like ``and``, ``or``, ``not`` and similar, but rather use the corresponding operators ``&&``, ``||``, and ``!``. The alternative tokens are not available - by default on all compilers, and also we want to maintain a consistent - programming style. + by default on all compilers. -- Output to the screen and the logfile should be using the corresponding - FILE pointers and only be done on MPI rank 0. Use the :cpp:func:`utils::logmesg` - convenience function where possible. +- Output to the screen and the logfile should use the corresponding + FILE pointers and only be done on MPI rank 0. Use the + :cpp:func:`utils::logmesg` convenience function where possible. -- Usage of C++11 `virtual`, `override`, `final` keywords: Please follow the - `C++ Core Guideline C.128 `_. +- Usage of C++11 `virtual`, `override`, `final` keywords: Please + follow the `C++ Core Guideline C.128 + `_. That means, you should only use `virtual` to declare a new virtual - function, `override` to indicate you are overriding an existing virtual - function, and `final` to prevent any further overriding. + function, `override` to indicate you are overriding an existing + virtual function, and `final` to prevent any further overriding. -- Trivial destructors: Prefer not writing destructors when they are empty and `default`. +- Trivial destructors: Do not write destructors when they are empty + and `default`. .. code-block:: c++ // don't write destructors for A or B like this + class A : protected Pointers { public: A(); @@ -135,6 +137,7 @@ Miscellaneous standards (varied) }; // instead, let the compiler create the implicit default destructor by not writing it + class A : protected Pointers { public: A(); @@ -147,9 +150,9 @@ Miscellaneous standards (varied) - Please use clang-format only to reformat files that you have contributed. For header files containing a ``SomeStyle(keyword, - ClassName)`` macros it is required to have this macro embedded with a - pair of ``// clang-format off``, ``// clang-format on`` comments and - the line must be terminated with a semicolon (;). Example: + ClassName)`` macros it is required to have this macro embedded with + a pair of ``// clang-format off``, ``// clang-format on`` comments + and the line must be terminated with a semicolon (;). Example: .. code-block:: c++ @@ -162,10 +165,10 @@ Miscellaneous standards (varied) #ifndef LMP_RUN_H [...] - You may also use ``// clang-format on/off`` throughout your files - to protect individual sections from being reformatted. + You may also use ``// clang-format on/off`` throughout your files to + protect individual sections from being reformatted. -- All files should have 0644 permissions, i.e. writable to the user only - and readable by all and no executable permissions. Executable - permissions (0755) should only be on shell scripts or python or similar - scripts for interpreted script languages. +- All files should have 0644 permissions, i.e. writable by the user + only and readable by all and no executable permissions. Executable + permissions (0755) should only be for shell scripts or python or + similar scripts for interpreted script languages. From cbb05587787503f3decd3e17b8161d0e9a688ad3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 15:06:03 -0400 Subject: [PATCH 188/448] correct comments --- src/EXTRA-FIX/fix_ttm_grid.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_grid.cpp b/src/EXTRA-FIX/fix_ttm_grid.cpp index ec5ba2540e..d9c6f13e2f 100644 --- a/src/EXTRA-FIX/fix_ttm_grid.cpp +++ b/src/EXTRA-FIX/fix_ttm_grid.cpp @@ -281,7 +281,7 @@ void FixTTMGrid::read_electron_temperatures(const std::string &filename) } // read the file - // Grid3d::read_file() calls back to read_grid_lines() with chunks of lines + // Grid3d::read_file() calls back to unpack_read_grid() with chunks of lines grid->read_file(Grid3d::FIX,this,fp,CHUNK,MAXLINE); @@ -419,7 +419,7 @@ void FixTTMGrid::write_restart_file(const char *file) } // write file - // Grid3d::write_file() calls back to pack_write_file() and unpack_write_file() + // Grid3d::write_file() calls back to pack_write_grid() and unpack_write_grid() grid->write_file(Grid3d::FIX,this,0,1,sizeof(double), MPI_DOUBLE); From 5f34f53ab745388625a4eb4974ff29b5cd306a11 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 15:06:34 -0400 Subject: [PATCH 189/448] also use 1-based indexing when writing out the electron temperature --- src/EXTRA-FIX/fix_ttm_mod.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index 5d7ada74b6..1aa07b6781 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -658,7 +658,7 @@ void FixTTMMod::write_electron_temperatures(const std::string &filename) for (iz = 0; iz < nzgrid; iz++) { if (movsur == 1 && T_electron[ix][iy][iz] == 0.0) T_electron[ix][iy][iz] = electron_temperature_min; - fprintf(fp,"%d %d %d %20.16g\n",ix,iy,iz,T_electron[ix][iy][iz]); + fprintf(fp,"%d %d %d %20.16g\n",ix+1,iy+1,iz+1,T_electron[ix][iy][iz]); } fclose(fp); From 0abb217d597f66221f194e6c17bea4a639a2dbe2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 15:13:29 -0400 Subject: [PATCH 190/448] whitespace --- doc/src/Modify_style.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/src/Modify_style.rst b/doc/src/Modify_style.rst index 4da8501f12..c5aef71597 100644 --- a/doc/src/Modify_style.rst +++ b/doc/src/Modify_style.rst @@ -123,7 +123,7 @@ Miscellaneous standards (varied) .. code-block:: c++ // don't write destructors for A or B like this - + class A : protected Pointers { public: A(); @@ -137,7 +137,7 @@ Miscellaneous standards (varied) }; // instead, let the compiler create the implicit default destructor by not writing it - + class A : protected Pointers { public: A(); From aa069b2cfb4e35ca8796bee3591b7b17cb5687bd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 15:44:54 -0400 Subject: [PATCH 191/448] fix typos --- doc/src/Modify_requirements.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 15edafb26c..5484040689 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -49,7 +49,7 @@ Contributing authors agree when submitting a pull request that their contributions can be distributed under the LAMMPS license conditions. This is the GNU public license in version 2 (not 3 or later) for the publicly distributed versions, e.g. on the LAMMPS homepage or on -GitHub. We also make a version of LAMMPS under LGPL 2.1 terms whcih +GitHub. We also have a version of LAMMPS under LGPL 2.1 terms which is available on request; this will usually be the latest available or a previous stable version with a few LGPL 2.1 incompatible files removed. More details are found on the :doc:`LAMMPS open-source @@ -105,10 +105,10 @@ Documentation (strict) Contributions that add new styles or commands or augment existing ones must include the corresponding new or modified documentation in `ReStructuredText format `_ (.rst files in the ``doc/src/`` -folder). The documentation should be written in American English and -the .rst file must only ues ASCII characters, so it can be cleanly -translated to PDF files (via `sphinx `_ -and PDFLaTeX). Special characters may be included via embedded math +folder). The documentation should be written in American English and the +.rst file must only use ASCII characters, so it can be cleanly +translated to PDF files (via `sphinx `_ and +PDFLaTeX). Special characters may be included via embedded math expression typeset in a LaTeX subset. .. _rst: https://www.sphinx-doc.org/en/master/usage/restructuredtext/index.html From cd792763090254cf7639eb5a1ecd2571c931fb9d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 15:45:24 -0400 Subject: [PATCH 192/448] small formatting tweaks --- doc/src/Modify_requirements.rst | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 5484040689..15d7e089af 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -16,7 +16,7 @@ different authors who may not be professionally trained programmers or familiar with the idiosyncrasies of maintaining a large software package. In addition, changes that interfere with the parallel efficiency of the core code must be avoided. As LAMMPS continues to -grow and more features and functionality are added, it's necessary to +grow and more features and functionality are added, it is necessary to follow established guidelines when accepting new contributions while also working at the same time to improve the existing code. @@ -204,22 +204,21 @@ compatible with and support both build systems. For a single pair of header and implementation files that are an independent feature, it is usually only required to add them to -`src/.gitignore``. +``src/.gitignore``. For traditional make, if your contributed files or package depend on other LAMMPS style files or packages also being installed (e.g. because your file is a derived class from the other LAMMPS -class), then an Install.sh file is also needed to check for those -dependencies and modifications to src/Depend.sh to trigger the checks. +class), then an ``Install.sh`` file is also needed to check for those +dependencies and modifications to ``src/Depend.sh`` to trigger the checks. See other README and Install.sh files in other directories as examples. Similarly, for CMake support, changes may need to be made to -cmake/CMakeLists.txt, some of the files in cmake/presets, and possibly -a file with specific instructions needs to be added to -cmake/Modules/Packages/. Please check out how this is handled for -existing packages and ask the LAMMPS developers if you need -assistance. +``cmake/CMakeLists.txt``, some of the files in ``cmake/presets``, and +possibly a file with specific instructions needs to be added to +``cmake/Modules/Packages/``. Please check out how this is handled for +existing packages and ask the LAMMPS developers if you need assistance. .. _ReqNaming: @@ -230,10 +229,10 @@ All user-visible command or style names should be all lower case and should only use letters, numbers, or forward slashes. They should be descriptive and initialisms should be avoided unless they are well established (e.g. lj for Lennard-Jones). For a compute style -"some/name" the source files must be called `compute_some_name.h` and -`compute_some_name.cpp`. The "include guard" in the header file would -then be `LMP_COMPUTE_SOME_NAME_H` and the class name -`ComputeSomeName`. +"some/name" the source files must be called ``compute_some_name.h`` and +``compute_some_name.cpp``. The "include guard" in the header file would +then be ``LMP_COMPUTE_SOME_NAME_H`` and the class name +``ComputeSomeName``. .. _ReqProgrammingStyle: From 96af466f4af08af1f90b0bed5554233fa84ff88f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 15:45:55 -0400 Subject: [PATCH 193/448] as a few details to the discussion of programming languages and their standards --- doc/src/Modify_requirements.rst | 35 +++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/doc/src/Modify_requirements.rst b/doc/src/Modify_requirements.rst index 15d7e089af..0637c860ab 100644 --- a/doc/src/Modify_requirements.rst +++ b/doc/src/Modify_requirements.rst @@ -168,29 +168,38 @@ Programming language standards (strict) The core of LAMMPS is written in C++11 in a style that can be mostly described as "C with classes". Advanced C++ features like operator -overloading or excessive use of templates are avoided with the intent -to keep the code readable to programmers that have limited C++ -programming experience. C++ constructs are acceptable when they help -improve the readability and reliability of the code, e.g. when using -the `std::string` class instead of manipulating pointers and calling -the string functions of the C library. In addition, a collection of +overloading or excessive use of templates are avoided with the intent to +keep the code readable to programmers that have limited C++ programming +experience. C++ constructs are acceptable when they help improve the +readability and reliability of the code, e.g. when using the +`std::string` class instead of manipulating pointers and calling the +string functions of the C library. In addition, a collection of convenient :doc:`utility functions and classes ` for recurring tasks and a collection of :doc:`platform neutral functions ` for improved portability are provided. +Contributions with code requiring more recent C++ standards are only +accepted as packages with the post C++11 standard code confined to the +package so that it is optional. Included Fortran code has to be compatible with the Fortran 2003 -standard. Python code must be compatible with Python 3.5. Large -parts of LAMMPS (including the :ref:`PYTHON package `) are -also compatible with Python 2.7. Compatibility with Python 2.7 is -desirable, but compatibility with Python 3.5 is **required**. +standard. Since not all platforms supported by LAMMPS provide good +support for compiling Fortran files, it should be considered to rewrite +these parts as C++ code, if possible and thus allow for a wider adoption +of the contribution. As of January 2023, all previously included +Fortran code for the LAMMPS executable has been replaced by equivalent +C++ code. -Compatibility with these older programming language standards is very +Python code must be compatible with Python 3.5 and later. Large parts +of LAMMPS (including the :ref:`PYTHON package `) are also +compatible with Python 2.7. Compatibility with Python 2.7 is desirable, +but compatibility with Python 3.5 is **required**. + +Compatibility with older programming language standards is very important to maintain portability and availability of LAMMPS on many platforms. This applies especially to HPC cluster environments, which tend to be running older software stacks and where LAMMPS users may be required to use those older tools for access to advanced hardware -features or not have the option to install newer compilers or -libraries. +features or not have the option to install newer compilers or libraries. .. _ReqBuildSystem: From 8414d23c2ba2bca9f91058103d8a50bdfe98bce1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 12 May 2023 18:04:37 -0400 Subject: [PATCH 194/448] use symbolic constants --- src/atom.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/atom.cpp b/src/atom.cpp index 3f2f4550e9..f30ace174e 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -823,9 +823,9 @@ void Atom::modify_params(int narg, char **arg) if (iarg+2 > narg) utils::missing_cmd_args(FLERR, "atom_modify map", error); if (domain->box_exist) error->all(FLERR,"Atom_modify map command after simulation box is defined"); - if (strcmp(arg[iarg+1],"array") == 0) map_user = 1; - else if (strcmp(arg[iarg+1],"hash") == 0) map_user = 2; - else if (strcmp(arg[iarg+1],"yes") == 0) map_user = 3; + if (strcmp(arg[iarg+1],"array") == 0) map_user = MAP_ARRAY; + else if (strcmp(arg[iarg+1],"hash") == 0) map_user = MAP_HASH; + else if (strcmp(arg[iarg+1],"yes") == 0) map_user = MAP_YES; else error->all(FLERR,"Illegal atom_modify map command argument {}", arg[iarg+1]); map_style = map_user; iarg += 2; From 17747a3c58814a13a5d4e198f1ae1867f11d7f5f Mon Sep 17 00:00:00 2001 From: ilia Nikiforov Date: Sun, 14 May 2023 15:07:31 -0500 Subject: [PATCH 195/448] moved scaling to immediately after compute and removed virial scaling --- src/KIM/pair_kim.cpp | 61 ++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 34 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index da9f574b02..daf31d79c7 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -253,6 +253,33 @@ void PairKIM::compute(int eflag, int vflag) int kimerror = KIM_Model_Compute(pkim, pargs); if (kimerror) error->all(FLERR,"KIM Compute returned error {}", kimerror); + // scale results for fix adapt if needed + if (scale_extracted) + { + if (eflag_global != 0) + { + eng_vdwl *= scale; + } + for (int i = 0; i < nall; i++) + { + if (eflag_atom != 0) + { + eatom[i] *= scale; + } + if (vflag_atom != 0) + { + for (int j = 0; j < 6; j++) + { + vatom[i][j] *= scale; + } + } + for (int j = 0; j < 3; j++) + { + atom->f[i][j] *= scale; + } + } + } + // compute virial before reverse comm! if (vflag_global) virial_fdotr_compute(); @@ -275,40 +302,6 @@ void PairKIM::compute(int eflag, int vflag) vatom[i][5] = -tmp; } } - - // scale results for fix adapt if needed - if (scale_extracted) - { - if (eflag_global != 0) - { - eng_vdwl *= scale; - } - if (vflag_global != 0) - { - for (int i = 0; i < 6; i++) - { - virial[i] *= scale; - } - } - for (int i = 0; i < nall; i++) - { - if (eflag_atom != 0) - { - eatom[i] *= scale; - } - if (vflag_atom != 0) - { - for (int j = 0; j < 6; j++) - { - vatom[i][j] *= scale; - } - } - for (int j = 0; j < 3; j++) - { - atom->f[i][j] *= scale; - } - } - } } /* ---------------------------------------------------------------------- From d584f2fe50ec520ea710bc97b492bc56065a31ef Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 15 May 2023 01:58:45 -0400 Subject: [PATCH 196/448] follow LAMMMPS' programming style more closely --- src/KIM/pair_kim.cpp | 42 ++++++++++++------------------------------ 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index daf31d79c7..58d7840cbb 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -251,43 +251,25 @@ void PairKIM::compute(int eflag, int vflag) // compute via KIM model int kimerror = KIM_Model_Compute(pkim, pargs); - if (kimerror) error->all(FLERR,"KIM Compute returned error {}", kimerror); + if (kimerror) error->all(FLERR, "KIM Compute returned error {}", kimerror); // scale results for fix adapt if needed - if (scale_extracted) - { - if (eflag_global != 0) - { - eng_vdwl *= scale; - } - for (int i = 0; i < nall; i++) - { - if (eflag_atom != 0) - { - eatom[i] *= scale; - } - if (vflag_atom != 0) - { - for (int j = 0; j < 6; j++) - { - vatom[i][j] *= scale; - } - } - for (int j = 0; j < 3; j++) - { - atom->f[i][j] *= scale; + if (scale_extracted) { + if (eflag_global != 0) eng_vdwl *= scale; + for (int i = 0; i < nall; i++) { + if (eflag_atom != 0) eatom[i] *= scale; + if (vflag_atom != 0) { + for (int j = 0; j < 6; j++) vatom[i][j] *= scale; } + for (int j = 0; j < 3; j++) atom->f[i][j] *= scale; } } // compute virial before reverse comm! - if (vflag_global) - virial_fdotr_compute(); + if (vflag_global) virial_fdotr_compute(); // if newton is off, perform reverse comm - if (!lmps_using_newton) { - comm->reverse_comm(this); - } + if (!lmps_using_newton) comm->reverse_comm(this); if ((vflag_atom != 0) && KIM_SupportStatus_NotEqual(kim_model_support_for_particleVirial, @@ -1169,8 +1151,8 @@ std::string PairKIM::get_atom_type_list() { return atom_type_list; } void *PairKIM::extract(const char *str, int &dim) { - dim = 0; - if (strcmp(str,"scale") == 0) + dim = 0; + if (strcmp(str,"scale") == 0) { scale_extracted = true; return (void *) &scale; From cf51c94be006c1884bdae9601ac4117a1f1e18f8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 15 May 2023 02:02:36 -0400 Subject: [PATCH 197/448] update unit test for presence of Pair::extract() function in pair style kim --- unittest/force-styles/tests/atomic-pair-kim_lj.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unittest/force-styles/tests/atomic-pair-kim_lj.yaml b/unittest/force-styles/tests/atomic-pair-kim_lj.yaml index 5663efccbf..5475004348 100644 --- a/unittest/force-styles/tests/atomic-pair-kim_lj.yaml +++ b/unittest/force-styles/tests/atomic-pair-kim_lj.yaml @@ -14,7 +14,8 @@ input_file: in.metal pair_style: kim ex_model_Ar_P_LJ pair_coeff: ! | * * Ar Ar -extract: ! "" +extract: ! | + scale 0 natoms: 32 init_vdwl: 9544.77366960673 init_coul: 0 From 91e0d0411b49b0e243d796135f462c8ea8a50bdd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 15 May 2023 02:04:17 -0400 Subject: [PATCH 198/448] one more programming style tweak --- src/KIM/pair_kim.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/KIM/pair_kim.cpp b/src/KIM/pair_kim.cpp index 58d7840cbb..ae2e6e6ea0 100644 --- a/src/KIM/pair_kim.cpp +++ b/src/KIM/pair_kim.cpp @@ -1152,11 +1152,9 @@ std::string PairKIM::get_atom_type_list() { return atom_type_list; } void *PairKIM::extract(const char *str, int &dim) { dim = 0; - if (strcmp(str,"scale") == 0) - { + if (strcmp(str,"scale") == 0) { scale_extracted = true; return (void *) &scale; } - return nullptr; } From b9256fa4925bc7e0578309477d9de5bd2420262d Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 16 May 2023 11:09:37 -0600 Subject: [PATCH 199/448] Reduce memory allocations --- src/KOKKOS/atom_kokkos.cpp | 14 +++++-- src/KOKKOS/atom_kokkos.h | 19 +++++++++ src/KOKKOS/atom_map_kokkos.cpp | 73 +++++++++++++++++++--------------- src/KOKKOS/kokkos_type.h | 13 ++++++ 4 files changed, 85 insertions(+), 34 deletions(-) diff --git a/src/KOKKOS/atom_kokkos.cpp b/src/KOKKOS/atom_kokkos.cpp index feca086911..03537e7b88 100644 --- a/src/KOKKOS/atom_kokkos.cpp +++ b/src/KOKKOS/atom_kokkos.cpp @@ -26,16 +26,24 @@ #include "modify.h" #include "fix.h" -#include - using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ AtomKokkos::AtomKokkos(LAMMPS *lmp) : Atom(lmp) { - k_error_flag = DAT::tdual_int_scalar("atom:error_flag"); avecKK = nullptr; + + k_error_flag = DAT::tdual_int_scalar("atom:error_flag"); + + d_tag_min_max = t_tagint_2(Kokkos::NoInit("atom:tag_min_max")); + h_tag_min_max = t_host_tagint_2(Kokkos::NoInit("atom:tag_min_max")); + + d_tag_min = Kokkos::subview(d_tag_min_max,0); + d_tag_max = Kokkos::subview(d_tag_min_max,1); + + h_tag_min = Kokkos::subview(h_tag_min_max,0); + h_tag_max = Kokkos::subview(h_tag_min_max,1); } /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/atom_kokkos.h b/src/KOKKOS/atom_kokkos.h index a994542dd9..23566cff03 100644 --- a/src/KOKKOS/atom_kokkos.h +++ b/src/KOKKOS/atom_kokkos.h @@ -15,6 +15,8 @@ #include "atom.h" // IWYU pragma: export #include "kokkos_type.h" +#include + #ifndef LMP_ATOM_KOKKOS_H #define LMP_ATOM_KOKKOS_H @@ -84,6 +86,23 @@ class AtomKokkos : public Atom { DAT::tdual_int_1d k_map_array; dual_hash_type k_map_hash; + DAT::t_tagint_1d d_tag_sorted; + DAT::t_int_1d d_i_sorted; + + typedef Kokkos::DualView tdual_tagint_2; + typedef tdual_tagint_2::t_dev t_tagint_2; + typedef tdual_tagint_2::t_host t_host_tagint_2; + + t_tagint_2 d_tag_min_max; + t_host_tagint_2 h_tag_min_max; + + DAT::t_tagint_scalar d_tag_min,d_tag_max; + HAT::t_tagint_scalar h_tag_min,h_tag_max; + + using MapKeyViewType = decltype(d_tag_sorted); + using BinOpMap = Kokkos::BinOp1D; + Kokkos::BinSort Sorter; + class AtomVecKokkos* avecKK; // map lookup function inlined for efficiency diff --git a/src/KOKKOS/atom_map_kokkos.cpp b/src/KOKKOS/atom_map_kokkos.cpp index 5a91b34f94..f928e3c1d5 100644 --- a/src/KOKKOS/atom_map_kokkos.cpp +++ b/src/KOKKOS/atom_map_kokkos.cpp @@ -21,8 +21,6 @@ #include "modify.h" #include "neighbor_kokkos.h" -#include - #include using namespace LAMMPS_NS; @@ -145,33 +143,31 @@ void AtomKokkos::map_set() // sort by tag - auto d_tag_sorted = DAT::t_tagint_1d(Kokkos::NoInit("atom:tag_sorted"),nall); - auto d_i_sorted = DAT::t_int_1d(Kokkos::NoInit("atom:i_sorted"),nall); + int nmax = atom->nmax; - typedef Kokkos::DualView tdual_tagint_2; - typedef tdual_tagint_2::t_dev t_tagint_2; - typedef tdual_tagint_2::t_host t_host_tagint_2; - - auto d_tag_min_max = t_tagint_2(Kokkos::NoInit("atom:tag_min_max")); - auto h_tag_min_max = t_host_tagint_2(Kokkos::NoInit("atom:tag_min_max")); - - auto d_tag_min = Kokkos::subview(d_tag_min_max,0); - auto d_tag_max = Kokkos::subview(d_tag_min_max,1); - - auto h_tag_min = Kokkos::subview(h_tag_min_max,0); - auto h_tag_max = Kokkos::subview(h_tag_min_max,1); + int realloc_flag = 0; + if (d_tag_sorted.extent(0) < nmax) { + MemKK::realloc_kokkos(d_tag_sorted,"atom:tag_sorted",nmax); + MemKK::realloc_kokkos(d_i_sorted,"atom:i_sorted",nmax); + realloc_flag = 1; + } h_tag_min() = MAXTAGINT; h_tag_max() = 0; Kokkos::deep_copy(d_tag_min_max,h_tag_min_max); + auto l_tag_sorted = d_tag_sorted; + auto l_i_sorted = d_i_sorted; + auto l_tag_min = d_tag_min; + auto l_tag_max = d_tag_max; + Kokkos::parallel_for(nall, LAMMPS_LAMBDA(int i) { - d_i_sorted(i) = i; + l_i_sorted(i) = i; tagint tag_i = d_tag(i); - d_tag_sorted(i) = tag_i; - Kokkos::atomic_min(&d_tag_min(),tag_i); - Kokkos::atomic_max(&d_tag_max(),tag_i); + l_tag_sorted(i) = tag_i; + Kokkos::atomic_min(&l_tag_min(),tag_i); + Kokkos::atomic_max(&l_tag_max(),tag_i); }); Kokkos::deep_copy(h_tag_min_max,d_tag_min_max); @@ -179,12 +175,25 @@ void AtomKokkos::map_set() tagint min = h_tag_min(); tagint max = h_tag_max(); - using KeyViewType = decltype(d_tag_sorted); - using BinOp = Kokkos::BinOp1D; + using MapKeyViewType = decltype(d_tag_sorted); + using BinOpMap = Kokkos::BinOp1D; - BinOp binner(nall, min, max); + auto binner = BinOpMap(nall, min, max); + + if (!Sorter.bin_offsets.data() || realloc_flag) { + Sorter = Kokkos::BinSort(d_tag_sorted, 0, nall, binner, true); + MemKK::realloc_kokkos(Sorter.bin_count_atomic,"Kokkos::SortImpl::BinSortFunctor::bin_count",nmax+1); + Kokkos::deep_copy(Sorter.bin_count_atomic,0); + Sorter.bin_count_const = Sorter.bin_count_atomic; + MemKK::realloc_kokkos(Sorter.bin_offsets,"Kokkos::SortImpl::BinSortFunctor::bin_offsets",nmax+1); + MemKK::realloc_kokkos(Sorter.sort_order,"Kokkos::SortImpl::BinSortFunctor::sort_order",nmax); + } else { + Kokkos::deep_copy(Sorter.bin_count_atomic,0); + Sorter.bin_op = binner; + Sorter.range_begin = 0; + Sorter.range_end = nall; + } - Kokkos::BinSort Sorter(d_tag_sorted, 0, nall, binner, true); Sorter.create_permute_vector(LMPDeviceType()); Sorter.sort(LMPDeviceType(), d_tag_sorted, 0, nall); Sorter.sort(LMPDeviceType(), d_i_sorted, 0, nall); @@ -201,8 +210,8 @@ void AtomKokkos::map_set() // atom with smallest local id for atom map Kokkos::parallel_for(nall, LAMMPS_LAMBDA(int ii) { - const int i = d_i_sorted(ii); - const tagint tag_i = d_tag_sorted(ii); + const int i = l_i_sorted(ii); + const tagint tag_i = l_tag_sorted(ii); int i_min = i; int i_closest = MAXTAGINT; @@ -213,9 +222,9 @@ void AtomKokkos::map_set() int closest_flag = 0; while (jj < nall) { - const tagint tag_j = d_tag_sorted(jj); + const tagint tag_j = l_tag_sorted(jj); if (tag_j != tag_i) break; - const int j = d_i_sorted(jj); + const int j = l_i_sorted(jj); i_min = MIN(i_min,j); if (j > i) { i_closest = MIN(i_closest,j); @@ -229,9 +238,9 @@ void AtomKokkos::map_set() jj = ii-1; while (jj >= 0) { - const tagint tag_j = d_tag_sorted(jj); + const tagint tag_j = l_tag_sorted(jj); if (tag_j != tag_i) break; - const int j = d_i_sorted(jj); + const int j = l_i_sorted(jj); i_min = MIN(i_min,j); if (j > i) { i_closest = MIN(i_closest,j); @@ -256,7 +265,9 @@ void AtomKokkos::map_set() }); - auto h_error_flag = Kokkos::create_mirror_view_and_copy(LMPHostType(),d_error_flag); + auto h_error_flag = k_error_flag.h_view; + Kokkos::deep_copy(h_error_flag,d_error_flag); + if (h_error_flag()) error->one(FLERR,"Failed to insert into Kokkos hash atom map"); diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index f8d2b4947a..3c9886905e 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -652,6 +652,13 @@ typedef tdual_int_scalar::t_dev_const t_int_scalar_const; typedef tdual_int_scalar::t_dev_um t_int_scalar_um; typedef tdual_int_scalar::t_dev_const_um t_int_scalar_const_um; +typedef Kokkos:: + DualView tdual_tagint_scalar; +typedef tdual_tagint_scalar::t_dev t_tagint_scalar; +typedef tdual_tagint_scalar::t_dev_const t_tagint_scalar_const; +typedef tdual_tagint_scalar::t_dev_um t_tagint_scalar_um; +typedef tdual_tagint_scalar::t_dev_const_um t_tagint_scalar_const_um; + typedef Kokkos:: DualView tdual_float_scalar; @@ -970,6 +977,12 @@ typedef tdual_int_scalar::t_host_const t_int_scalar_const; typedef tdual_int_scalar::t_host_um t_int_scalar_um; typedef tdual_int_scalar::t_host_const_um t_int_scalar_const_um; +typedef Kokkos::DualView tdual_tagint_scalar; +typedef tdual_tagint_scalar::t_host t_tagint_scalar; +typedef tdual_tagint_scalar::t_host_const t_tagint_scalar_const; +typedef tdual_tagint_scalar::t_host_um t_tagint_scalar_um; +typedef tdual_tagint_scalar::t_host_const_um t_tagint_scalar_const_um; + typedef Kokkos::DualView tdual_float_scalar; typedef tdual_float_scalar::t_host t_float_scalar; typedef tdual_float_scalar::t_host_const t_float_scalar_const; From b1ee177c0a01ddf50ab9ae4ebf275d486111d5d9 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 16 May 2023 12:43:19 -0600 Subject: [PATCH 200/448] Must use local variable for lambda capture --- src/KOKKOS/atom_map_kokkos.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/KOKKOS/atom_map_kokkos.cpp b/src/KOKKOS/atom_map_kokkos.cpp index f928e3c1d5..575d87cf45 100644 --- a/src/KOKKOS/atom_map_kokkos.cpp +++ b/src/KOKKOS/atom_map_kokkos.cpp @@ -161,6 +161,7 @@ void AtomKokkos::map_set() auto l_i_sorted = d_i_sorted; auto l_tag_min = d_tag_min; auto l_tag_max = d_tag_max; + int map_style_array = (map_style == MAP_ARRAY); Kokkos::parallel_for(nall, LAMMPS_LAMBDA(int i) { l_i_sorted(i) = i; @@ -255,7 +256,7 @@ void AtomKokkos::map_set() d_sametag(i) = i_closest; if (i == i_min) { - if (map_style == MAP_ARRAY) + if (map_style_array) d_map_array(tag_i) = i_min; else { auto insert_result = d_map_hash.insert(tag_i, i_min); From 858fd4cc2c2391293c8419cb203d5b55bfb287e5 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Tue, 16 May 2023 15:23:31 -0600 Subject: [PATCH 201/448] Small optimization --- src/KOKKOS/domain_kokkos.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/domain_kokkos.cpp b/src/KOKKOS/domain_kokkos.cpp index 9478aa939d..6311d45a3f 100644 --- a/src/KOKKOS/domain_kokkos.cpp +++ b/src/KOKKOS/domain_kokkos.cpp @@ -571,9 +571,11 @@ void DomainKokkos::lamda2x(int n) KOKKOS_INLINE_FUNCTION void DomainKokkos::operator()(TagDomain_lamda2x, const int &i) const { - x(i,0) = h[0]*x(i,0) + h[5]*x(i,1) + h[4]*x(i,2) + boxlo[0]; - x(i,1) = h[1]*x(i,1) + h[3]*x(i,2) + boxlo[1]; - x(i,2) = h[2]*x(i,2) + boxlo[2]; + const double xi1 = x(i,1); + const double xi2 = x(i,2); + x(i,0) = h[0]*x(i,0) + h[5]*xi1 + h[4]*xi2 + boxlo[0]; + x(i,1) = h[1]*xi1 + h[3]*xi2 + boxlo[1]; + x(i,2) = h[2]*xi2 + boxlo[2]; } /* ---------------------------------------------------------------------- From 2b9c65855aa34fd9d12c149d9815f49034c9160e Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 16 May 2023 16:38:12 -0600 Subject: [PATCH 202/448] swap 3d array indices in fix ttm/mod --- src/EXTRA-FIX/fix_ttm_mod.cpp | 225 ++++++++++++++++------------------ src/EXTRA-FIX/fix_ttm_mod.h | 3 - 2 files changed, 105 insertions(+), 123 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index 1aa07b6781..1fcc0d54ff 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -75,10 +75,8 @@ static constexpr double SHIFT = 0.0; FixTTMMod::FixTTMMod(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), - random(nullptr), nsum(nullptr), nsum_all(nullptr), - gfactor1(nullptr), gfactor2(nullptr), ratio(nullptr), flangevin(nullptr), - T_electron(nullptr), T_electron_old(nullptr), sum_vsq(nullptr), sum_mass_vsq(nullptr), - sum_vsq_all(nullptr), sum_mass_vsq_all(nullptr), net_energy_transfer(nullptr), + random(nullptr), gfactor1(nullptr), gfactor2(nullptr), ratio(nullptr), flangevin(nullptr), + T_electron(nullptr), T_electron_old(nullptr), net_energy_transfer(nullptr), net_energy_transfer_all(nullptr) { if (lmp->citeme) lmp->citeme->add(cite_fix_ttm_mod); @@ -166,21 +164,15 @@ FixTTMMod::FixTTMMod(LAMMPS *lmp, int narg, char **arg) : gfactor2 = new double[atom->ntypes+1]; // allocate 3d grid variables - - memory->create(nsum,nxgrid,nygrid,nzgrid,"ttm/mod:nsum"); - memory->create(nsum_all,nxgrid,nygrid,nzgrid,"ttm/mod:nsum_all"); - memory->create(sum_vsq,nxgrid,nygrid,nzgrid,"ttm/mod:sum_vsq"); - memory->create(sum_mass_vsq,nxgrid,nygrid,nzgrid,"ttm/mod:sum_mass_vsq"); - memory->create(sum_vsq_all,nxgrid,nygrid,nzgrid,"ttm/mod:sum_vsq_all"); - memory->create(sum_mass_vsq_all,nxgrid,nygrid,nzgrid, - "ttm/mod:sum_mass_vsq_all"); - memory->create(T_electron_old,nxgrid,nygrid,nzgrid,"ttm/mod:T_electron_old"); - memory->create(T_electron_first,nxgrid,nygrid,nzgrid,"ttm/mod:T_electron_first"); - memory->create(T_electron,nxgrid,nygrid,nzgrid,"ttm/mod:T_electron"); - memory->create(net_energy_transfer,nxgrid,nygrid,nzgrid, + + memory->create(T_electron_old,nzgrid,nygrid,nxgrid,"ttm/mod:T_electron_old"); + memory->create(T_electron_first,nzgrid,nygrid,nxgrid,"ttm/mod:T_electron_first"); + memory->create(T_electron,nzgrid,nygrid,nxgrid,"ttm/mod:T_electron"); + memory->create(net_energy_transfer,nzgrid,nygrid,nxgrid, "ttm/mod:net_energy_transfer"); - memory->create(net_energy_transfer_all,nxgrid,nygrid,nzgrid, + memory->create(net_energy_transfer_all,nzgrid,nygrid,nxgrid, "ttm/mod:net_energy_transfer_all"); + flangevin = nullptr; grow_arrays(atom->nmax); @@ -203,10 +195,10 @@ FixTTMMod::FixTTMMod(LAMMPS *lmp, int narg, char **arg) : // initialize electron temperatures on grid int ix,iy,iz; - for (ix = 0; ix < nxgrid; ix++) + for (iz = 0; iz < nzgrid; iz++) for (iy = 0; iy < nygrid; iy++) - for (iz = 0; iz < nzgrid; iz++) - T_electron[ix][iy][iz] = tinit; + for (ix = 0; ix < nxgrid; ix++) + T_electron[iz][iy][ix] = tinit; // if specified, read initial electron temperatures from file @@ -221,18 +213,13 @@ FixTTMMod::~FixTTMMod() delete[] gfactor1; delete[] gfactor2; - memory->destroy(nsum); - memory->destroy(nsum_all); - memory->destroy(sum_vsq); - memory->destroy(sum_mass_vsq); - memory->destroy(sum_vsq_all); - memory->destroy(sum_mass_vsq_all); memory->destroy(T_electron_first); memory->destroy(T_electron_old); memory->destroy(T_electron); - memory->destroy(flangevin); memory->destroy(net_energy_transfer); memory->destroy(net_energy_transfer_all); + + memory->destroy(flangevin); } /* ---------------------------------------------------------------------- */ @@ -265,10 +252,10 @@ void FixTTMMod::init() sqrt(24.0*force->boltz*gamma_p/update->dt/force->mvv2e) / force->ftm2v; } - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) - net_energy_transfer_all[ix][iy][iz] = 0; + for (int ix = 0; ix < nxgrid; ix++) + net_energy_transfer_all[iz][iy][ix] = 0; if (utils::strmatch(update->integrate_style,"^respa")) nlevels_respa = (dynamic_cast(update->integrate))->nlevels; @@ -320,10 +307,10 @@ void FixTTMMod::post_force(int /*vflag*/) while (iy < 0) iy += nygrid; while (iz < 0) iz += nzgrid; - if (T_electron[ix][iy][iz] < 0) + if (T_electron[iz][iy][ix] < 0) error->all(FLERR,"Electronic temperature dropped below zero"); - double tsqrt = sqrt(T_electron[ix][iy][iz]); + double tsqrt = sqrt(T_electron[iz][iy][ix]); gamma1 = gfactor1[type[i]]; double vsq = v[i][0]*v[i][0] + v[i][1]*v[i][1] + v[i][2]*v[i][2]; @@ -348,14 +335,14 @@ void FixTTMMod::post_force(int /*vflag*/) if (left_x == -1) left_x = nxgrid - 1; if (left_y == -1) left_y = nygrid - 1; if (left_z == -1) left_z = nzgrid - 1; - double T_i = T_electron[ix][iy][iz]; - double T_ir = T_electron[right_x][iy][iz]; - double T_iu = T_electron[ix][right_y][iz]; - double T_if = T_electron[ix][iy][right_z]; - double C_i = el_properties(T_electron[ix][iy][iz]).el_heat_capacity; - double C_ir = el_properties(T_electron[right_x][iy][iz]).el_heat_capacity; - double C_iu = el_properties(T_electron[ix][right_y][iz]).el_heat_capacity; - double C_if = el_properties(T_electron[ix][iy][right_z]).el_heat_capacity; + double T_i = T_electron[iz][iy][ix]; + double T_ir = T_electron[right_z][iy][ix]; + double T_iu = T_electron[iz][right_y][ix]; + double T_if = T_electron[iz][iy][right_x]; + double C_i = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; + double C_ir = el_properties(T_electron[right_z][iy][ix]).el_heat_capacity; + double C_iu = el_properties(T_electron[iz][right_y][ix]).el_heat_capacity; + double C_if = el_properties(T_electron[iz][iy][right_x]).el_heat_capacity; double diff_x = (x_at - x_surf)*(x_at - x_surf); diff_x = pow(diff_x,0.5); double len_factor = diff_x/(diff_x+free_path); @@ -587,7 +574,7 @@ void FixTTMMod::read_electron_temperatures(const std::string &filename) if (comm->me == 0) { int ***T_initial_set; - memory->create(T_initial_set,nxgrid,nygrid,nzgrid,"ttm/mod:T_initial_set"); + memory->create(T_initial_set,nzgrid,nygrid,nxgrid,"ttm/mod:T_initial_set"); memset(&T_initial_set[0][0][0],0,ngridtotal*sizeof(int)); // read initial electron temperature values from file @@ -614,8 +601,8 @@ void FixTTMMod::read_electron_temperatures(const std::string &filename) if (T_tmp < 0.0) throw TokenizerException("Fix ttm electron temperatures must be > 0.0",""); - T_electron[ix][iy][iz] = T_tmp; - T_initial_set[ix][iy][iz] = 1; + T_electron[iz][iy][ix] = T_tmp; + T_initial_set[iz][iy][ix] = 1; } } catch (std::exception &e) { error->one(FLERR, e.what()); @@ -626,7 +613,7 @@ void FixTTMMod::read_electron_temperatures(const std::string &filename) for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) for (int ix = 0; ix < nxgrid; ix++) - if (T_initial_set[ix][iy][iz] == 0) + if (T_initial_set[iz][iy][ix] == 0) error->all(FLERR,"Fix ttm/mod infile did not set all temperatures"); memory->destroy(T_initial_set); @@ -656,9 +643,9 @@ void FixTTMMod::write_electron_temperatures(const std::string &filename) for (ix = 0; ix < nxgrid; ix++) for (iy = 0; iy < nygrid; iy++) for (iz = 0; iz < nzgrid; iz++) { - if (movsur == 1 && T_electron[ix][iy][iz] == 0.0) - T_electron[ix][iy][iz] = electron_temperature_min; - fprintf(fp,"%d %d %d %20.16g\n",ix+1,iy+1,iz+1,T_electron[ix][iy][iz]); + if (movsur == 1 && T_electron[iz][iy][ix] == 0.0) + T_electron[iz][iy][ix] = electron_temperature_min; + fprintf(fp,"%d %d %d %20.16g\n",ix+1,iy+1,iz+1,T_electron[iz][iy][ix]); } fclose(fp); @@ -700,20 +687,21 @@ void FixTTMMod::end_of_step() int nlocal = atom->nlocal; if (movsur == 1) { - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) { - double TTT = T_electron[ix][iy][iz]; + for (int ix = 0; ix < nxgrid; ix++) { + double TTT = T_electron[iz][iy][ix]; if (TTT > 0) { if (ix < t_surface_l) t_surface_l = ix; } } } - for (int ix = 0; ix < nxgrid; ix++) + + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) - net_energy_transfer[ix][iy][iz] = 0; + for (int ix = 0; ix < nxgrid; ix++) + net_energy_transfer[iz][iy][ix] = 0; for (int i = 0; i < nlocal; i++) if (mask[i] & groupbit) { @@ -731,7 +719,7 @@ void FixTTMMod::end_of_step() while (iz < 0) iz += nzgrid; if (ix >= t_surface_l) { if (ix < surface_r) - net_energy_transfer[ix][iy][iz] += + net_energy_transfer[iz][iy][ix] += (flangevin[i][0]*v[i][0] + flangevin[i][1]*v[i][1] + flangevin[i][2]*v[i][2]); } @@ -747,18 +735,19 @@ void FixTTMMod::end_of_step() double del_vol = dx*dy*dz; double el_specific_heat = 0.0; double el_thermal_conductivity = el_properties(electron_temperature_min).el_thermal_conductivity; - for (int ix = 0; ix < nxgrid; ix++) + + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) + for (int ix = 0; ix < nxgrid; ix++) { - if (el_properties(T_electron[ix][iy][iz]).el_thermal_conductivity > el_thermal_conductivity) - el_thermal_conductivity = el_properties(T_electron[ix][iy][iz]).el_thermal_conductivity; + if (el_properties(T_electron[iz][iy][ix]).el_thermal_conductivity > el_thermal_conductivity) + el_thermal_conductivity = el_properties(T_electron[iz][iy][ix]).el_thermal_conductivity; if (el_specific_heat > 0.0) { - if ((T_electron[ix][iy][iz] > 0.0) && (el_properties(T_electron[ix][iy][iz]).el_heat_capacity < el_specific_heat)) - el_specific_heat = el_properties(T_electron[ix][iy][iz]).el_heat_capacity; + if ((T_electron[iz][iy][ix] > 0.0) && (el_properties(T_electron[iz][iy][ix]).el_heat_capacity < el_specific_heat)) + el_specific_heat = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; } - else if (T_electron[ix][iy][iz] > 0.0) el_specific_heat = el_properties(T_electron[ix][iy][iz]).el_heat_capacity; + else if (T_electron[iz][iy][ix] > 0.0) el_specific_heat = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; } // num_inner_timesteps = # of inner steps (thermal solves) // required this MD step to maintain a stable explicit solve @@ -767,17 +756,15 @@ void FixTTMMod::end_of_step() double inner_dt = update->dt; double stability_criterion = 0.0; - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) - T_electron_first[ix][iy][iz] = - T_electron[ix][iy][iz]; + for (int ix = 0; ix < nxgrid; ix++) + T_electron_first[iz][iy][ix] = T_electron[iz][iy][ix]; do { - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) - T_electron[ix][iy][iz] = - T_electron_first[ix][iy][iz]; + for (int ix = 0; ix < nxgrid; ix++) + T_electron[iz][iy][ix] = T_electron_first[iz][iy][ix]; stability_criterion = 1.0 - 2.0*inner_dt/el_specific_heat * @@ -792,16 +779,15 @@ void FixTTMMod::end_of_step() error->warning(FLERR,"Too many inner timesteps in fix ttm/mod"); for (int ith_inner_timestep = 0; ith_inner_timestep < num_inner_timesteps; ith_inner_timestep++) { - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) - T_electron_old[ix][iy][iz] = - T_electron[ix][iy][iz]; + for (int ix = 0; ix < nxgrid; ix++) + T_electron_old[iz][iy][ix] = T_electron[iz][iy][ix]; // compute new electron T profile duration = duration + inner_dt; - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) { + for (int ix = 0; ix < nxgrid; ix++) { int right_x = ix + 1; int right_y = iy + 1; int right_z = iz + 1; @@ -821,50 +807,50 @@ void FixTTMMod::end_of_step() if (duration < width) { if (ix >= t_surface_l) mult_factor = (intensity/(dx*skin_layer_d))*exp((-1.0)*(ix_d - surface_d)/skin_layer_d); } - if (ix < t_surface_l) net_energy_transfer_all[ix][iy][iz] = 0.0; + if (ix < t_surface_l) net_energy_transfer_all[iz][iy][ix] = 0.0; double cr_vac = 1; - if (T_electron_old[ix][iy][iz] == 0) cr_vac = 0; + if (T_electron_old[iz][iy][ix] == 0) cr_vac = 0; double cr_v_l_x = 1; - if (T_electron_old[left_x][iy][iz] == 0) cr_v_l_x = 0; + if (T_electron_old[left_z][iy][ix] == 0) cr_v_l_x = 0; double cr_v_r_x = 1; - if (T_electron_old[right_x][iy][iz] == 0) cr_v_r_x = 0; + if (T_electron_old[right_z][iy][ix] == 0) cr_v_r_x = 0; double cr_v_l_y = 1; - if (T_electron_old[ix][left_y][iz] == 0) cr_v_l_y = 0; + if (T_electron_old[iz][left_y][ix] == 0) cr_v_l_y = 0; double cr_v_r_y = 1; - if (T_electron_old[ix][right_y][iz] == 0) cr_v_r_y = 0; + if (T_electron_old[iz][right_y][ix] == 0) cr_v_r_y = 0; double cr_v_l_z = 1; - if (T_electron_old[ix][iy][left_z] == 0) cr_v_l_z = 0; + if (T_electron_old[iz][iy][left_x] == 0) cr_v_l_z = 0; double cr_v_r_z = 1; - if (T_electron_old[ix][iy][right_z] == 0) cr_v_r_z = 0; + if (T_electron_old[iz][iy][right_x] == 0) cr_v_r_z = 0; if (cr_vac != 0) { - T_electron[ix][iy][iz] = - T_electron_old[ix][iy][iz] + - inner_dt/el_properties(T_electron_old[ix][iy][iz]).el_heat_capacity * - ((cr_v_r_x*el_properties(T_electron_old[ix][iy][iz]/2.0+T_electron_old[right_x][iy][iz]/2.0).el_thermal_conductivity* - (T_electron_old[right_x][iy][iz]-T_electron_old[ix][iy][iz])/dx - - cr_v_l_x*el_properties(T_electron_old[ix][iy][iz]/2.0+T_electron_old[left_x][iy][iz]/2.0).el_thermal_conductivity* - (T_electron_old[ix][iy][iz]-T_electron_old[left_x][iy][iz])/dx)/dx + - (cr_v_r_y*el_properties(T_electron_old[ix][iy][iz]/2.0+T_electron_old[ix][right_y][iz]/2.0).el_thermal_conductivity* - (T_electron_old[ix][right_y][iz]-T_electron_old[ix][iy][iz])/dy - - cr_v_l_y*el_properties(T_electron_old[ix][iy][iz]/2.0+T_electron_old[ix][left_y][iz]/2.0).el_thermal_conductivity* - (T_electron_old[ix][iy][iz]-T_electron_old[ix][left_y][iz])/dy)/dy + - (cr_v_r_z*el_properties(T_electron_old[ix][iy][iz]/2.0+T_electron_old[ix][iy][right_z]/2.0).el_thermal_conductivity* - (T_electron_old[ix][iy][right_z]-T_electron_old[ix][iy][iz])/dz - - cr_v_l_z*el_properties(T_electron_old[ix][iy][iz]/2.0+T_electron_old[ix][iy][left_z]/2.0).el_thermal_conductivity* - (T_electron_old[ix][iy][iz]-T_electron_old[ix][iy][left_z])/dz)/dz); - T_electron[ix][iy][iz]+=inner_dt/el_properties(T_electron[ix][iy][iz]).el_heat_capacity* + T_electron[iz][iy][ix] = + T_electron_old[iz][iy][ix] + + inner_dt/el_properties(T_electron_old[iz][iy][ix]).el_heat_capacity * + ((cr_v_r_x*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[right_z][iy][ix]/2.0).el_thermal_conductivity* + (T_electron_old[right_z][iy][ix]-T_electron_old[iz][iy][ix])/dx - + cr_v_l_x*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[left_z][iy][ix]/2.0).el_thermal_conductivity* + (T_electron_old[iz][iy][ix]-T_electron_old[left_z][iy][ix])/dx)/dx + + (cr_v_r_y*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][right_y][ix]/2.0).el_thermal_conductivity* + (T_electron_old[iz][right_y][ix]-T_electron_old[iz][iy][ix])/dy - + cr_v_l_y*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][left_y][ix]/2.0).el_thermal_conductivity* + (T_electron_old[iz][iy][ix]-T_electron_old[iz][left_y][ix])/dy)/dy + + (cr_v_r_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[ix][iy][right_z]/2.0).el_thermal_conductivity* + (T_electron_old[iz][iy][right_x]-T_electron_old[iz][iy][ix])/dz - + cr_v_l_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][iy][left_x]/2.0).el_thermal_conductivity* + (T_electron_old[iz][iy][ix]-T_electron_old[iz][iy][left_x])/dz)/dz); + T_electron[iz][iy][ix]+=inner_dt/el_properties(T_electron[iz][iy][ix]).el_heat_capacity* (mult_factor - - net_energy_transfer_all[ix][iy][iz]/del_vol); + net_energy_transfer_all[iz][iy][ix]/del_vol); } - else T_electron[ix][iy][iz] = - T_electron_old[ix][iy][iz]; - if ((T_electron[ix][iy][iz] > 0.0) && (T_electron[ix][iy][iz] < electron_temperature_min)) - T_electron[ix][iy][iz] = T_electron[ix][iy][iz] + 0.5*(electron_temperature_min - T_electron[ix][iy][iz]); + else T_electron[iz][iy][ix] = T_electron_old[iz][iy][ix]; + + if ((T_electron[iz][iy][ix] > 0.0) && (T_electron[iz][iy][ix] < electron_temperature_min)) + T_electron[iz][iy][ix] = T_electron[iz][iy][ix] + 0.5*(electron_temperature_min - T_electron[iz][iy][ix]); - if (el_properties(T_electron[ix][iy][iz]).el_thermal_conductivity > el_thermal_conductivity) - el_thermal_conductivity = el_properties(T_electron[ix][iy][iz]).el_thermal_conductivity; - if ((T_electron[ix][iy][iz] > 0.0) && (el_properties(T_electron[ix][iy][iz]).el_heat_capacity < el_specific_heat)) - el_specific_heat = el_properties(T_electron[ix][iy][iz]).el_heat_capacity; + if (el_properties(T_electron[iz][iy][ix]).el_thermal_conductivity > el_thermal_conductivity) + el_thermal_conductivity = el_properties(T_electron[iz][iy][ix]).el_thermal_conductivity; + if ((T_electron[iz][iy][ix] > 0.0) && (el_properties(T_electron[iz][iy][ix]).el_heat_capacity < el_specific_heat)) + el_specific_heat = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; } } stability_criterion = 1.0 - @@ -913,12 +899,11 @@ double FixTTMMod::compute_vector(int n) double dz = domain->zprd/nzgrid; double del_vol = dx*dy*dz; - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) { - e_energy += el_sp_heat_integral(T_electron[ix][iy][iz])*del_vol; - transfer_energy += - net_energy_transfer_all[ix][iy][iz]*update->dt; + for (int ix = 0; ix < nxgrid; ix++) { + e_energy += el_sp_heat_integral(T_electron[iz][iy][ix])*del_vol; + transfer_energy += net_energy_transfer_all[iz][iy][ix]*update->dt; } if (n == 0) return e_energy; @@ -933,7 +918,7 @@ double FixTTMMod::compute_vector(int n) void FixTTMMod::write_restart(FILE *fp) { double *rlist; - memory->create(rlist,nxgrid*nygrid*nzgrid+4,"ttm/mod:rlist"); + memory->create(rlist,nzgrid*nygrid*nxgrid + 4,"ttm/mod:rlist"); int n = 0; rlist[n++] = nxgrid; @@ -941,10 +926,10 @@ void FixTTMMod::write_restart(FILE *fp) rlist[n++] = nzgrid; rlist[n++] = seed; - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) - rlist[n++] = T_electron[ix][iy][iz]; + for (int ix = 0; ix < nxgrid; ix++) + rlist[n++] = T_electron[iz][iy][ix]; if (comm->me == 0) { int size = n * sizeof(double); @@ -982,10 +967,10 @@ void FixTTMMod::restart(char *buf) // restore global frid values - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) - T_electron[ix][iy][iz] = rlist[n++]; + for (int ix = 0; ix < nxgrid; ix++) + T_electron[iz][iy][ix] = rlist[n++]; } /* ---------------------------------------------------------------------- diff --git a/src/EXTRA-FIX/fix_ttm_mod.h b/src/EXTRA-FIX/fix_ttm_mod.h index 28c3209697..469a641d56 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.h +++ b/src/EXTRA-FIX/fix_ttm_mod.h @@ -64,11 +64,8 @@ class FixTTMMod : public Fix { int nxgrid, nygrid, nzgrid; int ngridtotal; - int ***nsum, ***nsum_all; double *gfactor1, *gfactor2, *ratio, **flangevin; double ***T_electron, ***T_electron_old, ***T_electron_first; - double ***sum_vsq, ***sum_mass_vsq; - double ***sum_vsq_all, ***sum_mass_vsq_all; double ***net_energy_transfer, ***net_energy_transfer_all; double gamma_p, gamma_s, v_0, v_0_sq; From 0d31ab9c88ac50c2ab5b32c7e2b43a4951fd2662 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 16 May 2023 16:51:00 -0600 Subject: [PATCH 203/448] one more change --- src/EXTRA-FIX/fix_ttm_mod.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index 1fcc0d54ff..69d403edfa 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -834,7 +834,7 @@ void FixTTMMod::end_of_step() (T_electron_old[iz][right_y][ix]-T_electron_old[iz][iy][ix])/dy - cr_v_l_y*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][left_y][ix]/2.0).el_thermal_conductivity* (T_electron_old[iz][iy][ix]-T_electron_old[iz][left_y][ix])/dy)/dy + - (cr_v_r_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[ix][iy][right_z]/2.0).el_thermal_conductivity* + (cr_v_r_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][iy][right_x]/2.0).el_thermal_conductivity* (T_electron_old[iz][iy][right_x]-T_electron_old[iz][iy][ix])/dz - cr_v_l_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][iy][left_x]/2.0).el_thermal_conductivity* (T_electron_old[iz][iy][ix]-T_electron_old[iz][iy][left_x])/dz)/dz); From 05b8082e3c231472d79ab039c6ace01a901d5434 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Tue, 16 May 2023 17:03:34 -0600 Subject: [PATCH 204/448] code cleanup --- src/EXTRA-FIX/fix_ttm_mod.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index 69d403edfa..e7ad9735cf 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -738,16 +738,13 @@ void FixTTMMod::end_of_step() for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int ix = 0; ix < nxgrid; ix++) - { + for (int ix = 0; ix < nxgrid; ix++) { if (el_properties(T_electron[iz][iy][ix]).el_thermal_conductivity > el_thermal_conductivity) el_thermal_conductivity = el_properties(T_electron[iz][iy][ix]).el_thermal_conductivity; - if (el_specific_heat > 0.0) - { + if (el_specific_heat > 0.0) { if ((T_electron[iz][iy][ix] > 0.0) && (el_properties(T_electron[iz][iy][ix]).el_heat_capacity < el_specific_heat)) el_specific_heat = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; - } - else if (T_electron[iz][iy][ix] > 0.0) el_specific_heat = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; + } else if (T_electron[iz][iy][ix] > 0.0) el_specific_heat = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; } // num_inner_timesteps = # of inner steps (thermal solves) // required this MD step to maintain a stable explicit solve From 2e58a9ecf80b488d886c10a213692d3e5f089738 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 16 May 2023 21:13:48 -0400 Subject: [PATCH 205/448] whitespace --- src/EXTRA-FIX/fix_ttm_mod.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index e7ad9735cf..d75f5915ba 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -164,7 +164,7 @@ FixTTMMod::FixTTMMod(LAMMPS *lmp, int narg, char **arg) : gfactor2 = new double[atom->ntypes+1]; // allocate 3d grid variables - + memory->create(T_electron_old,nzgrid,nygrid,nxgrid,"ttm/mod:T_electron_old"); memory->create(T_electron_first,nzgrid,nygrid,nxgrid,"ttm/mod:T_electron_first"); memory->create(T_electron,nzgrid,nygrid,nxgrid,"ttm/mod:T_electron"); @@ -735,7 +735,7 @@ void FixTTMMod::end_of_step() double del_vol = dx*dy*dz; double el_specific_heat = 0.0; double el_thermal_conductivity = el_properties(electron_temperature_min).el_thermal_conductivity; - + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) for (int ix = 0; ix < nxgrid; ix++) { @@ -840,7 +840,7 @@ void FixTTMMod::end_of_step() net_energy_transfer_all[iz][iy][ix]/del_vol); } else T_electron[iz][iy][ix] = T_electron_old[iz][iy][ix]; - + if ((T_electron[iz][iy][ix] > 0.0) && (T_electron[iz][iy][ix] < electron_temperature_min)) T_electron[iz][iy][ix] = T_electron[iz][iy][ix] + 0.5*(electron_temperature_min - T_electron[iz][iy][ix]); From 4f57026dc062fa03b08176c605a345835fe55672 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 16 May 2023 21:15:01 -0400 Subject: [PATCH 206/448] whitespace --- src/KOKKOS/atom_map_kokkos.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/atom_map_kokkos.cpp b/src/KOKKOS/atom_map_kokkos.cpp index 575d87cf45..92786b7e37 100644 --- a/src/KOKKOS/atom_map_kokkos.cpp +++ b/src/KOKKOS/atom_map_kokkos.cpp @@ -161,7 +161,7 @@ void AtomKokkos::map_set() auto l_i_sorted = d_i_sorted; auto l_tag_min = d_tag_min; auto l_tag_max = d_tag_max; - int map_style_array = (map_style == MAP_ARRAY); + int map_style_array = (map_style == MAP_ARRAY); Kokkos::parallel_for(nall, LAMMPS_LAMBDA(int i) { l_i_sorted(i) = i; From e044ccbbb34076a4b8bafd33de5878ee57ff1668 Mon Sep 17 00:00:00 2001 From: Shern Tee Date: Wed, 17 May 2023 16:41:21 +1000 Subject: [PATCH 207/448] Bugfix fix_efield.cpp for atom-style energy --- src/fix_efield.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fix_efield.cpp b/src/fix_efield.cpp index d1765ed536..7880655973 100644 --- a/src/fix_efield.cpp +++ b/src/fix_efield.cpp @@ -395,7 +395,7 @@ void FixEfield::post_force(int vflag) } f[i][2] += fz; fsum[3] += fz; - if (estyle == ATOM) fsum[0] += efield[0][3]; + if (estyle == ATOM) fsum[0] += efield[i][3]; } } From d98b1e9f0418714d81950e667d2dc0d11439a6f5 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 17 May 2023 08:15:42 -0600 Subject: [PATCH 208/448] fix left/right indices --- src/EXTRA-FIX/fix_ttm_mod.cpp | 38 +++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index e7ad9735cf..16248ccbd7 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -329,20 +329,14 @@ void FixTTMMod::post_force(int /*vflag*/) if (right_x == nxgrid) right_x = 0; if (right_y == nygrid) right_y = 0; if (right_z == nzgrid) right_z = 0; - int left_x = ix - 1; - int left_y = iy - 1; - int left_z = iz - 1; - if (left_x == -1) left_x = nxgrid - 1; - if (left_y == -1) left_y = nygrid - 1; - if (left_z == -1) left_z = nzgrid - 1; double T_i = T_electron[iz][iy][ix]; - double T_ir = T_electron[right_z][iy][ix]; + double T_ir = T_electron[iz][iy][right_x]; double T_iu = T_electron[iz][right_y][ix]; - double T_if = T_electron[iz][iy][right_x]; + double T_if = T_electron[right_z][iy][ix]; double C_i = el_properties(T_electron[iz][iy][ix]).el_heat_capacity; - double C_ir = el_properties(T_electron[right_z][iy][ix]).el_heat_capacity; + double C_ir = el_properties(T_electron[iz][iy][right_x]).el_heat_capacity; double C_iu = el_properties(T_electron[iz][right_y][ix]).el_heat_capacity; - double C_if = el_properties(T_electron[iz][iy][right_x]).el_heat_capacity; + double C_if = el_properties(T_electron[right_z][iy][ix]).el_heat_capacity; double diff_x = (x_at - x_surf)*(x_at - x_surf); diff_x = pow(diff_x,0.5); double len_factor = diff_x/(diff_x+free_path); @@ -808,33 +802,33 @@ void FixTTMMod::end_of_step() double cr_vac = 1; if (T_electron_old[iz][iy][ix] == 0) cr_vac = 0; double cr_v_l_x = 1; - if (T_electron_old[left_z][iy][ix] == 0) cr_v_l_x = 0; + if (T_electron_old[iz][iy][left_x] == 0) cr_v_l_x = 0; double cr_v_r_x = 1; - if (T_electron_old[right_z][iy][ix] == 0) cr_v_r_x = 0; + if (T_electron_old[iz][iy][right_x] == 0) cr_v_r_x = 0; double cr_v_l_y = 1; if (T_electron_old[iz][left_y][ix] == 0) cr_v_l_y = 0; double cr_v_r_y = 1; if (T_electron_old[iz][right_y][ix] == 0) cr_v_r_y = 0; double cr_v_l_z = 1; - if (T_electron_old[iz][iy][left_x] == 0) cr_v_l_z = 0; + if (T_electron_old[left_z][iy][ix] == 0) cr_v_l_z = 0; double cr_v_r_z = 1; - if (T_electron_old[iz][iy][right_x] == 0) cr_v_r_z = 0; + if (T_electron_old[right_z][iy][ix] == 0) cr_v_r_z = 0; if (cr_vac != 0) { T_electron[iz][iy][ix] = T_electron_old[iz][iy][ix] + inner_dt/el_properties(T_electron_old[iz][iy][ix]).el_heat_capacity * - ((cr_v_r_x*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[right_z][iy][ix]/2.0).el_thermal_conductivity* - (T_electron_old[right_z][iy][ix]-T_electron_old[iz][iy][ix])/dx - - cr_v_l_x*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[left_z][iy][ix]/2.0).el_thermal_conductivity* - (T_electron_old[iz][iy][ix]-T_electron_old[left_z][iy][ix])/dx)/dx + + ((cr_v_r_x*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][iy][right_x]/2.0).el_thermal_conductivity* + (T_electron_old[iz][iy][right_x]-T_electron_old[iz][iy][ix])/dx - + cr_v_l_x*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][iy][left_x]/2.0).el_thermal_conductivity* + (T_electron_old[iz][iy][ix]-T_electron_old[iz][iy][left_x])/dx)/dx + (cr_v_r_y*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][right_y][ix]/2.0).el_thermal_conductivity* (T_electron_old[iz][right_y][ix]-T_electron_old[iz][iy][ix])/dy - cr_v_l_y*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][left_y][ix]/2.0).el_thermal_conductivity* (T_electron_old[iz][iy][ix]-T_electron_old[iz][left_y][ix])/dy)/dy + - (cr_v_r_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][iy][right_x]/2.0).el_thermal_conductivity* - (T_electron_old[iz][iy][right_x]-T_electron_old[iz][iy][ix])/dz - - cr_v_l_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[iz][iy][left_x]/2.0).el_thermal_conductivity* - (T_electron_old[iz][iy][ix]-T_electron_old[iz][iy][left_x])/dz)/dz); + (cr_v_r_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[right_z][iy][ix]/2.0).el_thermal_conductivity* + (T_electron_old[right_z][iy][ix]-T_electron_old[iz][iy][ix])/dz - + cr_v_l_z*el_properties(T_electron_old[iz][iy][ix]/2.0+T_electron_old[left_z][iy][ix]/2.0).el_thermal_conductivity* + (T_electron_old[iz][iy][ix]-T_electron_old[left_z][iy][ix])/dz)/dz); T_electron[iz][iy][ix]+=inner_dt/el_properties(T_electron[iz][iy][ix]).el_heat_capacity* (mult_factor - net_energy_transfer_all[iz][iy][ix]/del_vol); From 7c98d4dba3b56407ff2209e3249c32df9092a36c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 May 2023 10:26:33 -0400 Subject: [PATCH 209/448] avoid null pointer dereferences by allocating a buffer for at least 1 item --- src/library.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index cc4e748f57..33f49a4e53 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -3159,7 +3159,8 @@ void lammps_gather_bonds(void *handle, void *data) } tagint **bonds; - lmp->memory->create(bonds, localbonds, 3, "library:gather_bonds:localbonds"); + // add 1 to localbonds, so "bonds" does not become a NULL pointer + lmp->memory->create(bonds, localbonds+1, 3, "library:gather_bonds:localbonds"); lmp->atom->avec->pack_bond(bonds); MPI_Allgatherv(&bonds[0][0], 3*localbonds, MPI_LMP_TAGINT, data, bufsizes, bufoffsets, MPI_LMP_TAGINT, lmp->world); @@ -3269,7 +3270,8 @@ void lammps_gather_angles(void *handle, void *data) } tagint **angles; - lmp->memory->create(angles, localangles, 4, "library:gather_angles:localangles"); + // add 1 to localangles, so "angles" does not become a NULL pointer + lmp->memory->create(angles, localangles+1, 4, "library:gather_angles:localangles"); lmp->atom->avec->pack_angle(angles); MPI_Allgatherv(&angles[0][0], 4*localangles, MPI_LMP_TAGINT, data, bufsizes, bufoffsets, MPI_LMP_TAGINT, lmp->world); @@ -3380,7 +3382,8 @@ void lammps_gather_dihedrals(void *handle, void *data) } tagint **dihedrals; - lmp->memory->create(dihedrals, localdihedrals, 5, "library:gather_dihedrals:localdihedrals"); + // add 1 to localdihedrals, so "dihedrals" does not become a NULL pointer + lmp->memory->create(dihedrals, localdihedrals+1, 5, "library:gather_dihedrals:localdihedrals"); lmp->atom->avec->pack_dihedral(dihedrals); MPI_Allgatherv(&dihedrals[0][0], 5*localdihedrals, MPI_LMP_TAGINT, data, bufsizes, bufoffsets, MPI_LMP_TAGINT, lmp->world); @@ -3491,7 +3494,8 @@ void lammps_gather_impropers(void *handle, void *data) } tagint **impropers; - lmp->memory->create(impropers, localimpropers, 5, "library:gather_impropers:localimpropers"); + // add 1 to localimpropers, so "impropers" does not become a NULL pointer + lmp->memory->create(impropers, localimpropers+1, 5, "library:gather_impropers:localimpropers"); lmp->atom->avec->pack_improper(impropers); MPI_Allgatherv(&impropers[0][0], 5*localimpropers, MPI_LMP_TAGINT, data, bufsizes, bufoffsets, MPI_LMP_TAGINT, lmp->world); From 377c652a830a9041b71c115ea38fb0700e9cff29 Mon Sep 17 00:00:00 2001 From: Giacomo Fiorin Date: Wed, 17 May 2023 13:29:00 -0400 Subject: [PATCH 210/448] Update Colvars library to version 2023-05-01 This update consists exclusively of bugfixes or maintenance-related changes. The following is a list of pull requests in the Colvars repository since the previous update to LAMMPS: - 532 Add XYZ trajectory reading feature https://github.com/Colvars/colvars/pull/532 (@jhenin, @giacomofiorin) - 531 Delete objects quietly, unless explicitly requested via script (including VMD) https://github.com/Colvars/colvars/pull/531 (@giacomofiorin) - 530 Append newline to log and error messages if not already present https://github.com/Colvars/colvars/pull/530 (@giacomofiorin) - 528 Forward-declare OpenMP lock https://github.com/Colvars/colvars/pull/528 (@giacomofiorin) - 527 Remove unneeded STL container https://github.com/Colvars/colvars/pull/527 (@giacomofiorin) - 526 Allow collecting configuration files and strings before setting up interface https://github.com/Colvars/colvars/pull/526 (@giacomofiorin, @jhenin) - 523 Fallback to linearCombination when customFunction is missing in customColvar https://github.com/Colvars/colvars/pull/523 (@HanatoK, @giacomofiorin) - 522 Use iostream::fail() to check for I/O error https://github.com/Colvars/colvars/pull/522 (@jhenin) - 520 Fix ref count https://github.com/Colvars/colvars/pull/520 (@giacomofiorin) - 513 Set target temperature through a common code path https://github.com/Colvars/colvars/pull/513 (@giacomofiorin, @jhenin) - 509 Safer detection of Windows with recent Microsoft Visual Studio versions https://github.com/Colvars/colvars/pull/509 (@akohlmey) - 508 Update LAMMPS patching method to reflect Lepton availability https://github.com/Colvars/colvars/pull/508 (@giacomofiorin) - 497 Increase the precision of write_multicol https://github.com/Colvars/colvars/pull/497 (@HanatoK) - 496 Only perform MTS automatic enable/disable for timeStepFactor > 1 https://github.com/Colvars/colvars/pull/496 (@giacomofiorin) - 493 Remove unused branch of quaternion input function https://github.com/Colvars/colvars/pull/493 (@giacomofiorin) - 489 Ensure there are spaces between the fields in the header https://github.com/Colvars/colvars/pull/489 (@HanatoK) - 487 Use map of output streams, and return references to its elements https://github.com/Colvars/colvars/pull/487 (@giacomofiorin, @jhenin) - 486 Remember first step of moving restraint https://github.com/Colvars/colvars/pull/486 (@jhenin) - 485 Add decoupling option for moving restraints https://github.com/Colvars/colvars/pull/485 (@jhenin) - 483 Update Lepton via patching procedure https://github.com/Colvars/colvars/pull/483 (@giacomofiorin) - 481 Make file-reading operations of input data abstractable https://github.com/Colvars/colvars/pull/481 (@giacomofiorin) Authors: @akohlmey, @giacomofiorin, @HanatoK, @jhenin --- doc/src/PDF/colvars-refman-lammps.pdf | Bin 1492597 -> 1498869 bytes lib/colvars/Makefile.common | 2 + lib/colvars/Makefile.deps | 504 ++++------------ lib/colvars/colvar.cpp | 78 +-- lib/colvars/colvar.h | 2 - lib/colvars/colvar_UIestimator.h | 91 +-- lib/colvars/colvar_arithmeticpath.h | 1 - lib/colvars/colvar_geometricpath.h | 2 - lib/colvars/colvar_neuralnetworkcompute.cpp | 32 +- lib/colvars/colvar_neuralnetworkcompute.h | 10 +- lib/colvars/colvaratoms.cpp | 28 +- lib/colvars/colvarbias.cpp | 96 ++-- lib/colvars/colvarbias.h | 2 +- lib/colvars/colvarbias_abf.cpp | 77 ++- lib/colvars/colvarbias_abf.h | 2 +- lib/colvars/colvarbias_alb.cpp | 24 +- lib/colvars/colvarbias_histogram.cpp | 22 +- .../colvarbias_histogram_reweight_amd.cpp | 102 ++-- .../colvarbias_histogram_reweight_amd.h | 12 +- lib/colvars/colvarbias_meta.cpp | 185 +++--- lib/colvars/colvarbias_meta.h | 11 +- lib/colvars/colvarbias_restraint.cpp | 167 ++++-- lib/colvars/colvarbias_restraint.h | 8 +- lib/colvars/colvarcomp.h | 2 +- lib/colvars/colvarcomp_combination.cpp | 173 +++--- lib/colvars/colvarcomp_coordnums.cpp | 14 +- lib/colvars/colvarcomp_distances.cpp | 1 + lib/colvars/colvarcomp_gpath.cpp | 7 +- lib/colvars/colvarcomp_protein.cpp | 13 +- lib/colvars/colvarcomp_rotations.cpp | 8 +- lib/colvars/colvargrid.cpp | 121 +++- lib/colvars/colvargrid.h | 311 ++++------ lib/colvars/colvargrid_def.h | 261 +++++++++ lib/colvars/colvarmodule.cpp | 279 ++++----- lib/colvars/colvarmodule.h | 28 +- lib/colvars/colvarmodule_refs.h | 46 +- lib/colvars/colvarproxy.cpp | 537 +++--------------- lib/colvars/colvarproxy.h | 352 ++---------- lib/colvars/colvarproxy_io.cpp | 310 ++++++++++ lib/colvars/colvarproxy_io.h | 167 ++++++ lib/colvars/colvarproxy_system.cpp | 203 +++++++ lib/colvars/colvarproxy_system.h | 177 ++++++ lib/colvars/colvarproxy_tcl.cpp | 1 + lib/colvars/colvarproxy_volmaps.cpp | 8 +- lib/colvars/colvarproxy_volmaps.h | 2 +- lib/colvars/colvars_version.h | 2 +- lib/colvars/colvarscript_commands.h | 95 +++- lib/colvars/colvartypes.cpp | 85 +-- lib/colvars/colvartypes.h | 128 ++--- src/COLVARS/colvarproxy_lammps.cpp | 34 +- src/COLVARS/colvarproxy_lammps.h | 13 +- src/COLVARS/colvarproxy_lammps_version.h | 2 +- src/COLVARS/fix_colvars.cpp | 10 +- 53 files changed, 2575 insertions(+), 2273 deletions(-) create mode 100644 lib/colvars/colvargrid_def.h create mode 100644 lib/colvars/colvarproxy_io.cpp create mode 100644 lib/colvars/colvarproxy_io.h create mode 100644 lib/colvars/colvarproxy_system.cpp create mode 100644 lib/colvars/colvarproxy_system.h diff --git a/doc/src/PDF/colvars-refman-lammps.pdf b/doc/src/PDF/colvars-refman-lammps.pdf index 59d12f925349e610767d251b9a71dffcaf0d9d24..4f85537b35d994f8d7e75d00545d15224a55d384 100644 GIT binary patch delta 362034 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 h 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%0D(&W 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Ċs^)-JOV2~ zt*VM2SQgIk4c|0mx==Y3)d%Tv*<7Kwh#TPz>R2$lyo4Fq-~92F;8GS)Z@l!tun79p z)W>iv6C6p-ye2ka;Dj$F^86KC8B_$|Zm`P;6As|WWcS#~#C-Gmb-j188ez*CN=~Bm zyIDXaXJPu-4Ugx38m-Rvdq8Uw_froRG!LZq{_5@`dxWPI17WV?#xh5(NY2TXFlRp}i^$6e+G5x`L?~1ir_iQ-*>Wp}s})#%*ROU!xSC_QwJ4kb$=uCt zMIK+U7_{QyD6Wfu=WRR-5C2cs-TbEO03&QW*_)(Om56jc0)DJ;pFy3N8=hV@#QcPw z{s*f|()a=OOYV;+ppm0B>6=eMWbWzWa^lM_Fvv=tryioa7#s;CB{8!h6sIro15;aq z062>Bc36PGnequxVg)R2#O60=0s7mBGnaRlZAN?JY`zhm>n1S3Eka{)#GWoeW0f7` zPmhT$1Pf+k;UOOMFXitfqbW{jjzos5AuwwM*fV}^L?b{46vchV#Nkg}Fx%&cRV5`z z`Q1li_dx65b~jmY{15Fo z6``fg*HT^qmBDm5PKjq7(<)d>MPH~LWRF_A8i9d#=u(n}CEVOuA)W4FLHjmZeE3oz z1<23i4qL6`*FLWa$U%HLStQ^z;1AYkVJJMLQ>$_VZJ?m(}B6F8^c174o{ zyR(6f7P^RVf089I1^1v#IZ|u+Yt_!`5!Ahr{+o}70d{lLE63HWg0tE_En9CTSmXJ$ zZ!YF|V7-@rh*m-dvqu?TDWI)vul?}yyr(t&h9d~m!6|YT;Jj#R z5Zgllpr<$ar##Hi1W&`Lnfso8nZJ?!vjlAkCH0BY+>ITLmV;V=jY!fJ6TG~KwgvkK z($j0gsOIEb{j3sYC^HLEHQ&N~^!4R?t2C+C2sl9O);~om7_EC*{A14j>wPQAe~{>$ z#vgt=zcRYLQ^C0UUXh-94FUOm9jRQ5ne;3VP`lg(xa||QQy&M9Vmj&v^Tmb0yr@{B zPa?1;_DzBUTZ)IW+WzIT29M;M!L)GuLs|T8Za9Wu7gLlr11)skNa-0(K#Ng2S-C&U z1>(%D=W4#psw~`>gZ|PuSGcqET?`+F=|VxGmMdTtS6mh6L^fUKHfCj>5N~p`HJp4J zkg&&-l%V3f@=WqOCtRa3o@H|5N-h^xA^}d>Ybu9>)NL6*tTuk z?yzHZY}>{a+fK)}JGO1xww-+WpZ6Z)->fy(oSSp3d9JFX-umd*s_$a=j%mNc@g&|4 z8iNvJX(<00aF;%9md&bR=^*Npox6$n#Y*pk>(cwt2MM0+#*<&Y8lkeOl$ z9Us^NsV?*AItao_gCF0}kHT@Lec%?5e2LaTUqvi3Jh&O?i1P*QD%?6R??TUWa0myu z%AZ2bQ=m{3D#i{R!^*`vs{(DPl~21V8UQGy#WGlmNdC=Nk1 zE*lp$5pMa_gd_H>cmDcBrO~`u;q%l0q|}0%2qRUtKr? z_y12D_(9J9-^cc)wv7`mXTn#t9y6hv)p+1@GmTpL2g-2kx^+iW;$-zWA(aKmy+|UA z6uF%5CqJSo69{$00R`XUqK-A_e4qsz&StbYr>S{WvXyZ`<6SgMgpm0^PB25G1j;y^ z5>g;~+-nrz#UN4Rs*J+$sNYf&);73BhJ2t0LP}vL6qsm7=KVo&@Z_>0aj_C$ z?A1~5|7}MPX3qCJ!`(1n}@aw0x z>!uR3qod&y<{;EKOzZqrv=17Ka3HOyqiQ#aD8$f=GnP^e zRjLAHhL=~$zoWO{ZL_nWoT=Kf}pUm za~?4ppe^U3|MA(efWR{x2BTBkWbCc(51Z{>GA`?oW=|YPKBl`nIdx4v1G1(7T&VJx zH&wE8LN_<`=ca!Pvn>v*lZZv>1j3t=H@}>R+RT-Olm1907u2y{8agTK?VGb&sSCKZCWNaQ z?Dde&CnR~hM2<9$zq4dE13b__{jVFR?h1-cQ9za9RRMNNqyG>hS$Pq#pO_rRf{}gB z>ykCgG$*mBds%94HBB@v9{ZUL$RGgsq=@3J90vD1BZ2&fb78=IMBV}8Y%4v~VL|ls zU@c=v1YzN5J2gHjLbXxrWFIa<+8CM_`Ce&UdEI}s)1ubBt+B%lzHN(wL`8sfP=rjw*y0-4XMlQ~YSs{%dV>SPr9;j! zj4!bUs3d}4AQObyprn{eMNj-LptSz{iBd{W=aG+Y?6WO(S-X_ z$H-=d6T%?LSdMsMzsA zBFAeIb8s0NLnJQ|F#r3FLOg{$CyeFyvX2!pM`F9W_wz6BoN=p?^8D)7==SN6Hh6rn zP;qZHQQRj)&}?teuxm>CP%I9r$6Ed#oJA6M3?3-9Bbf8z&a$<|eck{7&#||7j~VU0 z?xV?h&6)a0OV`AD3pddI>M7QG@TJ{ZF*tdbuk|QpZTnu{o++2jAi(a?>r@(dBCjW# zasvNdt{R(`H3$QGObU6ID31rxgVuwgKX3~U1s(=23A$qptO5*UqDIv&vWh-dt>7A5 zPn)D8|N05dNsui@wn7J(Hfee7@dE)VYH@q!H35lqUpRJ(;kc85=Pqb?&w`wc2qvPtEiGp9f1xUN2SY81fZ$K~so$O!9-AAGyPLB~L5`_bROSCM6F_6E*x}feC znIgodt5hT*5&25lG0X&E{4!9V2|31wii{t*H%G{>N*+4&;VKR_1W`;+Q?4-Lp-Kel+Cz(_cRJ6T;e#221Tg0#XAsx$0P5J=}XNnW_4 z!r%t+0?p&2-m*@YIPycxnopVX{r@f^gS8SAa);yw-OouV9C)-PODKr;0X2ICIlCVj zxe`!XllB29u#)h^2V8dmUVAU=j)QJZ_P2&@zJMn=DdT-8)=Mxm{vZaqdevF!|7X@}C31oe(H=nE=23`1WW!LA4qETsgtg-+2 zi3Id{Pepylg*?5b$xRpvFKcf!ULc}<@C{+5HFp5LCrLHnkgrm{0$Yeo4vyPB&j%Fu z5$+}}0k%miIVN3g-YPfm-=1C9O~mucuT>qRPB1t3E{Z5+E+Q;q6yu9y*~oJLWJ17L z8g#eh?5Tb$Y0kj`iDJ13@<*hpH1K$D>*_0YG$$P^U`rd%c9wdCB@9wcGM!XY-<;sR zQG)?QCh9}UHA0yhu`NCQmG0x*Brfyw@Q>PTLmO-HuVSy2>IhSLz@Nrk^xN1L>x zbY?5hd&*S7m46ZGF#t2`V4bz4nvt{=#CV(37X0C1<>)IdH9A0k=P}iwNw$NiGwVf={SXRC^>G8RxJha#@rP%h`83vdT6=56GHzuUV8C#$=8B_>Pw*w^hWWwP`)H}I&J~-;V+W-*`RNB zmQ66&EHA7)N-wVYpBcy?Abp(a>w9rG%OW3SF%8g?% z6HXs&TCasVw`UuW;U9+awPO3*N!r%K&xE-EK`Cy(#w~x5YKZSMbURN!B}85rJ?z|x zJk?ewX@xlvw!gO4b6b;5Fba=z@y#NlfAUe#XXjuezH}sf)p2N^#EDZ|%WDFjG@xJy ziyz(f>Qg3i8eh4OCB7^-94C#q1-H!j*o}Duwd*(R8#QCS(FwT4TbGJOM%={e1{RR2ta%}bP(`n59{&xU zs_ri`1F8PQ2R&%2!s==3XZEX7sng-A+QT?AY}#1x`D{r0{CpUXpx;|#aLN6Xn*XHv z`HW$AeS0&wBTmzAD4-(l{bgK=#sgfoF=W}gulkz!&wrE0l%Nwp^A7KB)D0{b$o1Qc z|FgsJEyrSuMU#8f(~;+!uDaP*SE58S*-*f!y9#|igKS~vofdp%-Dg+d$lsbR34S+5 z8UJ#0RQT_^;iZ5t2X7jsvdMrxlR8#Q*i%zgWqO{CbI|~6#(T%DtwIvMv{Zy^vcvnj zZ>`P0eG#mWKRP1-^->2*D;&BVfqOisWUmR=*w$w|tm~K-n{KVv4ZFJS$=n{>6^nG8 z)|9Nqrgvtl+{mA72=n6SmRgSZ4gBT3txH{|ZVl%6SM=pJ1>x<%#thAFAEb=CB=Zk>B&?%;*~s4k3kf7v)!? zJ4tqg*HEBp4M&FOUX-WT9}gqF@qRo7pB@?U|PgC3hS-n#Gr_FWRZG! zV+*oixZVJu25_|sU>+>hJSKnlyl;}_O+1u)m7Gd0NrtA_ zqd9G9A;!<*C^Wi`mn#k4Zwk6M=FZZCCwbHEK+-#?(fa!J!5(>T1$A+~*XRyf=L6dN zX@s_E+<28Tzla#O`)W)*m6{l7yX4b-l}8RazJmzZ^t6W95NtuhoIf0#9KJT&q;&Y{ z)IBN{^vx8)PL0GK0Le1;6?^^(enEVC3w}adYHrZwl~tH<_U_EAgz8lbI^S2e5azaN zG;5lCPL|xuP1p%!yNxeCM7(L|?rLh^gWgQYg?O4)_g?NPX;0h!*^{{4pETUm$)5Ji z9nJ+%SGL8@XV0rXqYi1y3WhIQ*S`UgY5>$-v(&#k{8~3A7@1E74Oe>|eKB&(`S+G> zTUS_!zpv9~#_hU1pZ3nX`QFd&uah=93;)>=oF15bZ^OWC_dXUInAot_*JCpt@^cvd zGGP^819TYU>d!eE$fSY zy}ViSST&U$VC|#4nI+F@S55O7vpJ^Y<0Y`!){ZhhdiY?-V$`f)ZNQsY8nbDH8gFb6~8fKGmNU13gtQ>}N=@=YV#I2g1#o z3Ve-**1Q>mCX5fl&HjIitrATS7lfPh|5Vv9+8;^~ZtmuvH#M0+S$`<0|6Aioh&~4Q zBmdh%nGXF3>PP->57cIPcJu|9ANk)VJVNMS_&<{Se`{0ab-NymK)G1C zQytcR`Wjr^RMoXt+vu;Z$}~nH&dW1W3n<{ge?7KLh-y}~8Bje( zt@YniFme9e?=2$Mmm9!zZJKYD7Z-Q{Qog>vJ|Nm005gzAE$#pYjJ~I?djP({6u{Us z1)u=*tG9YuEbuFAv9>M=RQRV@9J9yp`09$TZ}QUG2-l$$H41>(WwbS^^7K%h_lg8}yqVfq@f z?!5x?-I2~^x*-R;00HvST6g%4R~jD127FMC-a}eLgTKCW_h$lgq{P_j1H#~6UW0d! zO;4dATG~DRK0m+o_5|Iq`1pX32G;QP!JB-#Lb?}o3~DF!yx67P)WSG>utvba?tuIN zeBZk10zb)i2$zRfUhT~}Xt*5?mH9-D1cPt0>+hI^ln{Pt$2+JyU@kqFTS4AKfQDjP z&T~!#PD|3KP;0yjkSj(%WO(6Do z8rDbNmIuN-B9|`ec?{$d@N3IdpXRx7a+8G?*Psdio22rRxK>>oCt>IaQ9Deb$KH;o zIsfN$Ks(L4^71fS{&B^?Zci)X==5~Bjq(S-zSv~i0K*2;k%xQY!-hs#Q>5uFN;wbW zM6+1cnU|WynBYmDu$G`L?2VLfor^t$*qP`8^QVW>l=n4PHD){k%2E@@`Ev|7Qk#nF z3<^XyFMl;_cuLC^p6AF=y78Mpc&TzUm+aukn(wfcffzhe6K5ONHuZDl^7cC!Ju&9y^Ii3Aw{|kKn zG(6mDk#_%9t15zt0_i<+(4rik&4T%FiLHJMhHVNde1iZLO*NQ9m5}1Dz60&ik-%>+ z(t37<5^sl13?vmK-0(2ffl355r5ur==4W+E0W7K=^{SjPKpGNv5H^k|wQC;+IxEd= znpmadq0~%|Ro=&ZbKhB3+FKG&K7o_bUH`If?2(?_o?RCAQeDWuz`TS*>!xLMSuJ%nqvieYYL)ke`6XL>jh~*VV2#hZyP{DR3>-p2{kOG0HP_SKdGt9=;}_qmF(RsXILm} zS<^>NP0%QBkB_4HqS&4T5U9W&oyVKX4MT^WA$bNN(P^gi%AyZPw-u}qJY5ovv^C`T zrI~ZS=6@(chpu`V7n~yNkp?pIZ&;#FDr^Y85Bj4c`%Cg2 z--^ogQ^dEfGBDS>p2rNXjKaw|fagj4Kau)fr&Z5P`HbZ<#)~%O(lJ`nEOV9dx z@;^7RY7|G9y^dFC^2kPp-Bkr11Xmi%aUI250+xTJawbxFG#tZQsd`7L%$66zNVGZf=>qR|!qef-%KnkA@7elJ6&2bFcQ?~_5f))O zY1;!9HPX$n`ZbP0VXrW#4sZ}6tcM@97+=1S-kKIp)q?7AU%Ol)#H_;cemhMN2+w3@ z0qpfDK-Zpp-F|11Xu7N|ME@;m@rD`sR9Ak0i~ROyqYA@B&Rc_cR)dE}wJ4S!tQCjN zsCJNvUht12OY9aD!wHr{DR~ahaNkRRVesi*@%xPjG%99hQMU^_*VZk}U>EVUD5@u! zn;>Ush+L~Ik8oSIdL}+gl$CkcV{~t_4 z`DZmG=a1gE{H$2^=7F_oekUg_#%y8of^A=aEG^#*?$lviT;CkIkfM7|uP8$8&c1QeI?=DvC85-pU)5*7`N{(}I)}eyU_ZY3oCLm$S z6zI2F$Qu7DIwMmT^8K51?#{1X3{S@ZR~Nt8*hN!miZ%D9D!g*C^yfMi4fAXB&ITfO z-0OOB4A`y8_{xVSCdajy1o#vzOLsUh$`xf$J4qo-mkJ0MR!Y}dhfi6hH*=4-^tfAr z)u4kwQg1vHcks~7mzj;#-_6K62ms+bsjKH-(R^rD*q^>)Fx8se5}x75Gx_F3F~Y4G z??!!&>O7A@2`s;Qa<5AD5=4RMb$6QaE?K9`W%N9$y4;WT&m}(=&}kjuCw2`)=l$?K zw?*V5*p`|x|BqE6}!By`++;Upm7fi^W^x#At;KwS3ygN%03;jFuZ8N<|3k=e&ki zLWwT3G_zyB+{g5&aimC%69ItJ$Mo5Jyn=R3dzytYe9DFhn~A+Bd_%b^O=DS&WY!9qtg_2>~Z z{og9^Rc^UI7p`pSwd)CJG@&O6k@2nof5n;GG8r>N|GiB0>lP^jP1K7Y5;HUy1 znb`cXBCb=rg71w{zIm2zB+;F1UB`-LPKoe-pm2fM(yMMJ{;# zH;Ydo62n|6D|%S|bjWnOd4`06=fK6iau4tl&{Ep~+eD3X$zN*uA6$0V!2YgMmFoYf zk$;7Yg#O)RYwC4gIFFWsf)&-6blq^K@&0^QzyF#u0AGy99s;aZ|9kV7Kq<{R+dCl@h=ad6ifh^2v(Z3OZYNh69qrIop48NhgG)J0wzYy#Qe{a2wXr%6T(S-1 zt56&5U|&m9D2-t0({+KBA?5#8Vy!V);V?+Ly|#=s)ygs z3?%BiX{L}7m;=naT7~lBVg>oY?-pEYJ&I^{Q$ZLb#uK-$|0+U+!aLj-L@$9ZBB3%$ z0~j&=&1TK-uuKC^5-UBh)y{^FW;SM)XEOdfG%qzk}&bUx?wkOu=LwlCZm${_UO z+R6`!J~lNcjtz!sd>Bk;XBn0cIb4AYwFDS%Dz-Eh;Fu4~t%Sdvio@S4!})ve zcs%_tTRLQ_W-gAz?Xf?#qw?&z&CMCnUXa+4;mZBGedCO0Bi`r_5B_t@%MSylMW9#Kf{d^!>44!F5 zq>=t>gODRETT2++MfkS{rZz&1xJ2bBG=EJKGRC1h$DH^YNB_bpQ-l zn|&IbmFqoLAIA#B!#{)7Dr7*iPQa-OcpDY9!%U!MwcFS}1oqa?jt%Kw$`rhJvXRYYZ45dco3JLO4XspEm^Sl+^hE}(J^f>IKh<*T zQ?V2kU8;u>2ch62jhXgd_U%W5P^%AA(}o<_oo?5w9^H1~|6n+p1j@~F_XFy|C91OZ z*ae0S>>*8KSeXXW~`x5^6^Z*@13lH+9Bi|HyN{{`5>~ye_9Y8vf1;2VFPJ z!KtM(z4TT+EKgbG*diLAf=j02`yQ}I|I@`mKs^XASFZoB5KeO2zgp6IqS*}>r|u!! zlo)$FHMj_^n2;)q(&GB!2o-?rW6249BS0>7&F{tUG*lAMX0OAC$~h32p*a2Yuas|^ zb`M7ZiJ{45b+bP6pWBE84Q-W_Bzp;MyJp}un|Is142NdhekkJV|}_Z zWo_?!-#n?HWrYc~rkus3oQzhX3pVeU!C281=U_>VQ;Q$j?EXwp`$DmgVyC8dO6MsW z{yS4n08pMVkWh7CO?+68an-{>2Xx&XF^C9xkKKFWkg!U-Y}kjg(eI?8UFLcik-vU&xfMZ0M8iXBP7ALHL(^QVL064sjtaA zpLY=0GlC)t9x}tDiaS(BBJ~Z3ORQ>)W&8%xy;u9tf?ZC5d(XuC(YuT(YDJ5vqgjB=otkI=%up`D4UDgp zq%>ajLeXfiy2ttg6wOBE)#iK3R(#k|qyXo5}>(?Zt*%N2s_pzI}6o&HOECq_QVKAth~>LHW>NbJ>%s+$-q?Iqr& z=nAL3JdW*W3=d#?3N0);RdYO?WRY4!Oyw0)lC;V~2P~;}BJZo1t0%Y%z-L77n zK-bh5&Vm}UB@xr}TgpdH3MJGa3FBV(pIzTR)54c1icu^(ie1C^V8xJwG~&Hs)IW_> zQMzJDf&K74-^N(gYc&gw2YXf%5LUf*v^nFtYND0yd_#cOgW-G2XVct#b}k{!x$Ylp z&>NBg0~OLKV#)xYUi4Bt_TLBDX&`%J<_Axdtt!`ZgX#Q*tk|7un{2*mWXs;=vS{4q z&(|L3(Y5(cxT7TOORPHXlGW6N>|@D|pL{nC{tnux)|7STFwZ9vV0mjin~uKnM6zNs}k{ zVD!Bia^H8(>0`TaN*=&_VZ)pRgjR}g7l)z)xU-5t}SZtWSzG?R`(hJy1!F=EJf zfX>Y~5*)BDv%%4Z58CM=T3Rk$>X zf=fL=P53Eb{9~Rh#xYj!weM4F4PBk@ddKJ2R>|7jvh3Hb9>jsKNYe+2u4pdm;fzTC z=;$j|aFY-lmNxfUo|W~rbuI;a`isjZDm$9G=>!*;yl7}Iwv_2>aymBp*BaU zjeQj-Ig%wzr$hxN%#<{YZwr>t#^PV}OkXfNtZ@yFYS`Ycq{p-stw)DI!94_M#&-{4 zv*hX#L!{>463ysCXI)50{FN0PatAS>?j-Wy`keG|I`hAn1nzcQ_~K`zO18x{QxQ}A zIFtKOX&9pP5dx3?leL{jg-iNZMa0;0bzKQNQQ)T;Y-`0CHnf_{du=oMiZQI_q*z4; z)K{n8s=gaKk$6A(l6|g4|2X>x^S%cDbI~N+_|3nlTn@I{lGU9$w79kT{GC8feVl*X zZg+oiXZ&8YeP|?o`;=9`LpG1K>yz?z=J~x9d4A)B(ogF~wF|WpRmv^lzT;YHg~sdt zZIVnNZa@=D*dS+41j-s=6mNeB+3SsD-|DW$JlcE_E_42|0P3WZ%wu07wIaNKok!d#> z?y9!~w?}baM+5v9{NHeGM#p#=}TnVF{*r4BKC=kl$zy3)#G7=f4&HVy;U<; zl}OBO`s+0_cfr-DmZ*-enjKs zq>L3#h2vyscIp@1TZt*$w*Hy!tberXYtqZ>`ttRvYp9J%N(~=zn-8LGap~ljJc{J9D`?{R!$f3idpel z-&ff^KhgtJ=a`e@GK}CaCdoY*>WkPC&#EAk-6OB4c3^_*FaI#OZb6K5A(p?`{wKf$ z*z(O-f}%@ir+;147m)KGZ0K8jJ=m>kDnMm*o&z{7@1#s^c*Teb{&wYBX9gUE>uCKJ zi$xS3x~d&kLgf<$U}T)*mn+qGrrrD0S*QdeFS+lyls`nPzGTZ{4DNPW1K#mL zed!@84||9u4Fm9j6jZ>y-5a z*T=0EQhiXE&9B5}0%c#3noIQV{ut>5Dd0t{6R4njJez1%BXWhTMw_@2P_Pd*QjXKP zX-YMyZNy~N!Bk!7Vyxg>4Eb6mwtVN3;2$4s-K-fG7x^Doott<>{>6A$J6yvoWBjWc z5av_~(6yrrHC{a*7B(aLD)plw6E{5D(>=gzVA10uA@wc);FUWyh z>&&pvdRREscQ(Xx3~*(Pex>=nC?%Lg8{~oTbkxAzl&2p(pkEz)Pt(i5WBP{}(1l7g zp*hk+yN^eabH6Gj+}289W{tf`yqR!ZC0DLGX@`59;p%Km9f`Aq_1d;5B2sUu^$e;fHm_ zSl!{I_mtS=*n@kjFklh;AkCUjP0!>7JdC2bqAJRi1`ky~|-tJRbS4D5&3mb_r@qT90CBpo2`;-e~hu#+W^VmP7b-g&U>P{T6!b6Dq>pH*DCn4s*<&7+QXYCFs zHgEy&7}SxgR-Nc$&sVfbAG?kkfKHT5lp}fG(>*rx>}Q%VyD>9>ExlBX>?U((ZwJ-Q zQftDKB|&PHDFl&*Nc#>qV4JnWv#OfCBRltOC$OvNbUa5sH#zV-ie1Jdl-fz~@K*9E z2#iYnWb%yH$-TLLdsv1~IxW(J9)gDY@b|HyAm24CD2MO+B~c>!6UVdIS2Lg^5Af}@-xuNr-7a%GWV?P1nq#bJExn41W!1=5O{|(v zI^AA@wn(M}v)##aP%Y&(?RmSYdug!Y@@UePi#MD^mt^~=l ztd}`Vp`QHOC7(b0M_lda{BhMSdt<4-B~PM$Eu|g4+FkKZczzpR%Bhlh>wrs!e@V(& zsz$Dh%aYyGE}@^J*fyy;(ZA1S=B`XkQ``>-9kkzsghJtKK6AF3;8M-T8Teb{exT`u z77?3l!uK=7Dsb`CtSH&a#70PxaSkG|HM56LOi(a@e8^64%0wsyoZa-sqMu3RyT{ka zsoiGaA|uWDO;S{O)+7Y2SXa3TEELZX;X3#vi;i87Fn#Lskgj0}XvS>fzoHS0)d)8R zb_HGJE4^safdRriiC(NNx>kC7bK?}gf`bPUv6Y##)z%^54s~>&C;N^A&EVOu#x@@A zgVXjB%cb~|Pfz&(GKE>W;6A^eBo}{Cd_Cs*<<5jQHr_Pn=2rOr{!VLnK_b)Aix?V@ zbovZ0yN2Vi0b8Z@01}h>>E^k^+-vJntfPil6(nztsqL&Hd_bfqLZ$p%@5k;pdNwPo zRQ+A3e2w=~20II)k_?7;181UH0Sd^F^NLT+Z^s-ncN#vXFNIzaB&Lk?f-3+sk6j=ax zK*#7W6$N8%FjXvkEYd;F8#?QI)xa){cGsk{)hf0z25%2yXAYkVI_4}(HUvfF!D{N@$tFBw@^0?GK}|7a;s3vI2P!Bl z^M7`WZC`X>=pXr?-NHExJsJH+{%6@B%0@RA{gMCKEpqnI9~FM&e|C!sRt!W?F6JMA z(2v~$oSB1zgDbT+9+(nP*=pomq|;1+x9;j{z20QwG~8sPrh;B!xGoorUXq|wLSMOIvLSN;q=yBG2OgXj861u~Gb_9?Fd2ZEYhnOEKx$?Jt*r-9|AF=G zPyrdn$ZatQ(OPi=HHMU9z~ke80yMu?L6{!D5D&)Z(ajHmaz8w8YHOXG>znQE-}7I( zT~!)tfm$@Qfav^PF@TuKP4KbBsDT=j@*#xA`g;2gE1*o=lzDTpg$T?|cXup>L2I3z zfmc4gfSH_}nIHjQ%71D1F;l~6d%$+ij13?@92;&}8tmU7^C7u3T2?@Hbh@*Fh1C3# zBf|sNm$6&8LHrO*U9XP5$!<)Voj=q>@1fcWBG&TMoMK zof|kD-YJ`CZ(t#~G<`4G+}NDHO9}x7dTe^78PGGm=sN(@-NPq&I%QZt?wQ5WseyOe zC(QIj*c&~ImUa;Q$}d(>Prt|?2XJI-R&d2R<|O8`V99-s3&>aVnQUg}MaTEyzt3&y zBLQZgg52M``ll;u z@g)!0HSR{q&UX-AZbeecU3=C4dpGh?2e_(qo?>8vgMAsZeFm2TsCipYo_?jljUzS4 zHST#cVjgf3J9DSAKQ~jVs=!Nc=R%e6u4?Nu5LyI`@WBK!jSyzWflRRApfI;9{1uux zi;$C}R*oegEDiCEj)8mD{q=OcJAX*gr*xC959!TIEai01;o54&_U`9>yW<%83=n+~ zoAz|0gmopFbVjRqPWLi}&%dH;htFEVoV2(3FxniraN>3}qo)vp2qS|6j33>>rc{zj zGex$vimc-9v`d&$yfg_@R>W^!=HWYUwzaDrub0oyBHV3at=CDjpjmGF%=ha*rh3Y6Wy1pG25AJAJ& zvhB~O19?dFAwToo9#u1jPU&Jc%n56R{`-f+(1>%2E_A9)qGv=6DQ%v{c!xqmqJjtl zE7qk)x|z{0ernxs4?WgkAO+0uv~f?r-mdTTMGjejk|Des_O1_OZ+Z9OFL)ZsC{=dI zt<`B2Z{S};>tiAqzy9HaCBR1%N#}_A>C1(wlF1H!OLE?C%D&eazrksX6>1O^m&yuG zNJpXO6>qXtpJjP)oB~}8UK>Fgfd##J$bG=^zX>WSqyrxxm4KtFo$!%B$R?pr4&6L9 zHhOpNz@^HjyW#@;3=soGjg{-oI97fgk-S>E0sM6aTm^5N&?I?u06)p^t!5j2s9$SJ6iQ1PtOEjsjssUoB9)hY#GilB5o>Gl z@lG91TmP#f-85uCO*Rl;a7i=yIHr%bKhML%DfDp1K96XYs9mD(o+QLlCD>17FUa zaZ5{aJt~8@i4YAF8`8+`(=g3mxAy%(QIxH~+?-BM@y=0Z>E|`j2q&J1-@3=R{q|)LDfjxk4?`hiHfy`kB9ibj z56b;y-e(YHxU5ZMP30CnhB2IB--ZTl{R?lAdImy2VAPJNY_H@b0Z;Siij7KQKfxTtLopMJBj{XwwKQ^;+kysBL(6; zCu1#qKyC)S09#BxZw+Pko^bQAKh262-Q}!Vl5gPeRulxMJImTe;V-@`jV3u{$Rx>p zKGF3))W;I^lJOmVFYcP&RV)4NpgzLjEMUCWIG0ZN9}izQ9ugvp$O}3+082P>gqnLtlmZw#wZ`MAQ9i$$wfCKa zXWAI$ZzM5s@q!9Ev!!06`s{S5>`t!^VHJ=76S!4UdsOuO#Vl3#7OtiS%NUOMzkOOm zNvv-Lrj%a&`RE)>WB4Kq4uA?bxZ{}2%EBuc+LFg9b{s=izki?GMDpHsowW`XR!D0)W}BJ2}iD!&#oh|_qR z35VOjSXt(n9Ey68u#WOjt&gf`;X=5U(I*L~%}ZqGHycZ_Y_3v8>10CAT>oa{rW6}I zT)_mdc$CGEpmO&wBLDKp!3d+M`z+@KfK^DvnNTxFhZ%xBnn_MrvuOkM^fba>i<8&v zPi$c2EsQg}c<}N0jL{8-tf1V7G@Y=UE(7*9e>9R{qySc@G!n+Ebau4pltg2x{d2MJTmb?sX-4R33nCYzAF)FC za}Z`tDXGgA!@3*4Ama)k+yk$44q{hLYV=NViYiNK(im;EUTcMH$nE+^1|d7jy!U5l^dx;TW-AZHN`A=PsY8J*9Zz#0vz_lfhSVU!84+{68PA4MB!UOx7|4nIs^bs8NezDAGCFZx$Q z_NHKM>c=JaDHlWwUDjTIGg`@A)a14VkOQJ#1vmt7~%I%5`E8Y z1+omyL&d-tH+Rg$D%52Me=K%=Pi8v`?Y<7M4M_at+Pwf1OqgoANs$4>GcT~UbaD#N zwAgBp_|azdq>M_w^@v}}(J)GJaHdpp9xmv~k6P}#%JmF*N9rmr zD}QIb_(UAprJ`?l)?#5C=(*os@`Qe-BCIcB2qJ?#z1c~8+FI>?%=BswC*zMbwP<#N zU@os9d7-z8k*jx)hMOU^fW@yncxTYgA}YqZ6LO3$%8S|yszO6#p;!atUcQBQs>oRn zBXw(ZfsQD#%#(IpNuqxnHQgbH>D*TBq1L6@D{ds*XWbm*a6QkMDtWRd9Z&$7j)zK_|(FB!ZxQ) zWk4AnmLe-yDke$ntF*2pZF3CT?VC`}cYPmHpV^0L&)jojryxYb0`a;pmTRQu<}SfU zEaAG`sQ+z{uc?N!TC+sUa(#d7`TD3cFwdDDpNxvGE;njeZ0W>7+IC+zI~74XPb9c!Om|1xzGFn3I1{aGK23LaEQ45P!>=%MJam zVL>%*S9r+Nf(EHg4=Syqw=Xl$7}+s{sl!;fF3B~tGLDnmn%HbzrbRB3g#zcM<-0%5Ye~|{MvY_ z;cH3Nk34bv(2K>=MTQdhvy2(EN5Zkz3v2uto3J!@C6J-;XYuVv%B2Y!o)$F12xlIm)U>W zaSGlwAwuUW$=s`Ti;90K+Z7Bw4G={|9)IuMtd|tIIyX@IT(m^d?}_!t!ajYAqcr7X zHfn?$YF#_TR+u1P1zsMJc(Tpt@=xYxbL2pwmfi|Y+R!wFpSV$aZh1h(G&cOenV~=) z#?`iNcYn7EB-(s++Vv?7ar5k!7S?~$65}}KaKBUiMFg}GNCsn}096I!)RCssO@ZLU z5QvsK_H}gMIuuvF% z_L1}TEYL5>cdiw@rc06G)O@CK$Hr}cfDP8j1tXHdr$&2?)#~~;`tH>R6?IMfBzkIp zX%i)teg4{jCyIF1Ts0|3n%vg=tAY_jQ^PO>Vu%)Qc}>|zp!JOQ=k`n`SWlk4e4wzVk`*N@xVHH`!A*P(7)&{)h_l zj%#dMK1`yqyb7H{L}O@rc1S^UdylJ$7q^+WL5(Kvu|&eX$EiRCrVJENNifE zM(k~gc%4b4#9g|kk7j>^iac{ypRerK+bfB}+|QVO1q9!Fyj*ImgI$ti0hFrKqThP~ z1qp^o<7MO2Y!>o z;0!9qB46P+M9gA_nk6X^^Ygk*C6AvWN*CfZ9CZ>6Kou)S=h%NUwg>}`LAnUvAJ>fq z{%Iuf7ot`njyuuhu*TT~Vz009^Ch4xJ)AzA(w^-$!t5q4)8e0@WpC1EGV;JKDJBi~ zdQQ7gx;mD8EdSJ2GPC0~jsDD3rTY^52$q zs7QHqJw8n4K_q{)s8fR+)a5^&Jnv=D@PH@0!J3}BEc=UtoRK*6#HPocH(DI*U%1~$ zR&7C|)XK?t>#Q?FI*xWnzpE~T2-V&A8?CbEs3y6g&pLk?H{JJ*x)11nDk*18@iLWU zkGpDNA^4{5w&#LxW9N$?{rzk3riFhM6kmZk#%gYI5(s~=i9?Qqh zr4kA8&itvvkh4HsS%=8M%HMI2XDu^%ti>g2cG4W=9zFJHKj}6yhE;TpdSMb;%!%j? zNGY7huc{_@T6G}e#v3CBdd_GI{=}SCnL0uW!@Pg#--;5of0su<-pRF} zNSjlIAY2TIc=>R!PBGtOR>D9SJ*!E#tt?+s^$S zlze}|294!?Op-C)bXlgDY(~fyI%W1*)~l~OTRKQ6YsYkFJy&#nti@!2;VtSw_)O&# z>?2P#n{7jYOEvuclBtZ5EXS7>%nF#>IDWqBV=F&|2l_$!hiwF6nO|tO*bDJJY`OYA z9ivA_imTZS+di)?(tVmvf0yvhVT#%is{wz~VH7l~9izs;!LW2Pw(U-kuoRRkZlSHS zlyBqIKxsN@B2Ax(P~@kaTQw@##R$=z5i%rKp#Tx9{Jl-^HNjIpzMy%4TcKD?70gVfTlUQ((QCUot{rhdV1;h&K*H2tSDYK-;}!e7+WmjH z;cu*LY@U-*9)De(R_A4eb*&FBWcJW?SA)J?dul@S!d5nj+SZrBdHj;$S2dzbJuul# zk^QaY74abY`L}`?Pr6N)%@;zp-C18r*xgTL*^{iYV0IorbA5OYb}?5*m+OpxsdU)A zo2=(D0--NG0DXtu&_KP*+9fk?xgdW75(iej$iPsJ$PyC+9wzpkdxhfL#XV`c1S1zmdirxGBd*6_!9^5B-`+4K5K4(Hil;{N8#9!>t(84GFWW!w7xo4`!7&;lQba~wM}%FCk=FTX@;RqN*ZK0ANdjBB{c z=Q!Vs%gHh?G#YO%9lQUuB99J0n`%-8AL;m+fW-0{B4_=Yev+L(HgA-#Q;w2Frx@r9<|=BYb;5tovx+a!~be#5(Q zk!4E`IH~Z?gJV2ivfn&=(8`qMDGeP1p#6>^J*1i*U1w6lh0zQNg!LY8l z)F1Xp>+Z}r@ru+DQ>v87G>P;b3HRN6<#}9fwTA4LCG12m26S^!0|1Mwq`ze@fBQl^ffJK6-eyh;APh(No5ce0cU@ZKt8E zvR%0St=_0KF|iw<7;1mJ z;P544sX84axZLg9kh}(n5f>hMRH{3rD}Zl=hd6Im3noN5PXr_8BWjStZ0b}m3H*IP z&j{>!c3ZwE#p@RLpbmNCy|eP4;jpjhU4Y-*PpUr-Z@LyDfTeOB0c(%lH z43xd>9ow)kX-|~>F-$?2w4t!Ban{Z1xOoOY3~;DaB`ALz_08l33jzgBoiIW%c%Yu{ zZRJF4TI*o{0QMf8#ZH$-tG1k+Gk_GIQ5B5tyZ(qsNd|L(JTsxY2=)7dGFoRI#TI@qy*YGy4)@+ht$V8fb7_r1?=HE-V3t_beKglN+!1q@`AYXE7iwQnb zZjxYcBQJj}uVzJmZGr3GED(?LHd$`Wh%~S!3h-$x&hk=_JAq`AKdjB={(^ z7Y`oHSr2@QpCb#Z1|mg5zDdTSL6H0h*rAg@bC|pr6g0u7($KF(#Dbk1v0K_VhJc?D~D}NixG>>buOj;Rc~v zSiZA)RV*@h2C)tD6}-%__>kIZ9`W;1USxTHQ(|GRV%@X+sDk0Av?z}jRdp6gt#{~9?Reum$&{r$M!)V|nnH&KYyldjpe`vt9O6VNY_%N3fP z#=Q3U<_1k660!aTUU3t8JD4yo;>yjGO^Hi~aBG-g{XiV)mHqnamtvq&RP#%G<7y=yo8_SFtr!0RF=%+iaT~~1HiK?_NfIpL_iXgK*2w+aWt{1mu5J zK4ggeJb(#*+pn0^XG#}k8X zF^|X&%)vdg`FYmST25!8ONJWtAUV)(Tyl?`fUfn7(2>F0kW=DQzL z^{M(ZxayKhUEQrFA&wg4&{^DG1jIp_&0?$Z`PGtqJIW*OhWzP8ekbJU^PBHi6p&xt zw<_>Ytv>J2y^qNIiT$r2^Ib&UlG8WkE`f^W@o?R)k!$H>EB;1!QWTC7j@MjFYo!m+ zz{T_$@mm^4?v)zOZD+NKOnQGw9*nwbE^iKa=1dcR7GPhmUg7Oy`cgi16bb&&M=?^~$mBsYKWJ19`(G}#Vy zL44eSDvat_hau6FZ3vn4hOwRb>$6kobXhxcsCE<97FFmwq8~f-TT;o*TiRA#2`52d zpGS;p)g8!wc-)7J&PCs%36pblVq*u-@)Uzc{=Thddd}QC+XQVpudy^KN&SZV<01oq zJJ@G|(r*9mOnXv#lze~xvlVwJFQ8{2Y$HMvG3tfNMOt`kZUhG@_}0(RfUj@mg^mV2 z$NJvY(r+s@o)U9Q?9HiI10iN|RLDP;N5a41e0Vs)PWIb2n2RX;stZUPr0_2ay)3C{ z9uzmhjId+)$<)>A#pw*=vs^26W4Ihjm4TJ-#ncQzV)AkXXU>1>2W@WX%v%ZH3f$a! z=@0?7@Wx!uux|!^;k{}h0$~Su%JJC2f-w$3JA3g@6@t(s+;sq(mWY@7I&Ij4{5oM5 zD&q#LHY9NY7S;AUCpH<4(<4~l*-YU^lkP|(9Ohqhv@xR{Zs`wU1JK#{gdR}cZQi?uTOU43 zo)|)gQP>7`%U;fFeQ(r$vf$74PDBev<%3EPm){+K=I(#evg(31^k2B&wMg%OPOeGD zQQ_QlrRmtk1=c*N^1^~U1~HP*t)&qmB(G$-RRO)8C$^jK%Y?DUHVO*~L$O0T))!1+ z?;-w@gh_FaQMUI!CKUVQQ3y_^E(umTHdxi4O}D&Qa9E3~6(NNT7eG{YkC3Y+bLR4_4JBxzK=AyyICud5O3Pg;iRcP_tMDW0xt#V^U&BiF3Wu zB<`FGJ>rpg1@ZGhvosvR3Byxu%cGSuGT8vq$%xy7P|JOp2}Ebt;N$-1o%j$TGm<)@ znhPHyyfCz4Z<3-Nsy(>=(|ZS8j^_S(w`iR1kN(_1EY!VvMyQ|l^=aOfMxwbAEgs@Xfq&nRKt-#f zXHv0K1HB##&(*-R_woK#{)=(6Zk#OsZ-PEiJiq`p`;Pq4+JZ_AXyHc&H3WLjfJK+C zWW;}@ME^0OGTgDplOuJLN!yx*&1Jd3!F~Ap1iE!qv><{Ns7ehc)gOyznAk5T1}h&y zMr@Ztqk$cxpI5c5)QF^o``mAFO2`4D9;WYEX!CwO&qER)H)2dERGXQF_P@5Nh4CvD z*+>g^HT+Z(2y%Mbx2w0c2Q>WmR=YbxlbwHRe4jIq(I{-urSWxY*ZMTGT*;L2US*B| zEZ3P`dZD9+C~Ao0YUl1MR~h@2*^zAAc^tXh%>HUW#Voxly_d2iNA*z!P91v32^nM2=~~>2}fdq zQga2jh}j>uVDRgsdg%Bm{^E-Lv#7uYza#X{6fmp2?27zok>95_k!g zD?^VP5dBaJ5kr5@Rt4`b{5eQtCst4N-=|e;j=uw8g4nrck>I)U^6<(Gahs;yx^@RH zp4P_yK2I`>bSJGl=XQCW?yps1Od+JudILTO{~6UPDck2`1*9Zt`4E0D@oazBV?X^s zeASEpHHa2`pMQi`_gIT#0i~aF%j+5)50gAw8A7mPX3GTK5KmNy+$kQt8^2I8pyOpt zDvZ~nq_PHeQc1U9<%ypXS>iVCy$KHt6zEvfw!bep(OCX~ihzx$ z(93Lu(Y%0JrJth1>xy2LpnuvAP;CPh>#!0zfa5j@JC z>$&%#gr8Jwe{gOXQPpaK#`UA#(XVlA{`6K#^E#Gyl~2`>X!=o5W$%A(dAZ-SAl1<9 zzGti`;OixK9KNpQ40_bp7WSzE{akv%Jl*+{I=6UM7^L?%xIubd5fZu=A990)#ZS%y1hBcP$6*@Bz6 zg2ygc9k)Q81*=;?B@Tb-c#pPejGNoaJL0(RV%6s)>#qj6E;XlaWZGS$Ty=o*c>%(! zutiwM31EEHmW_+{%GZ(7pKaNic*;(`$`l*7J$gkvDd5iaQ-AL6-WK` z5}V(%wH|e&J@8J(AodyrJr5?iU0sz%THs7xmwC!*= z0QuJSohAy(JxJySxrYR=jbN8<>~m3*6z{~ze*O}jAIV~GH=(@%;qg-|tLKZmZvX^V=BoUA#zO5#=dEzF|1! zX*+%wgG{jpC>gWVzZ{|+XD5nGu1<8*;9<#UYFtc1r$ zG@2A1&X=PR^S;E_Q(KdFK8rfNSk9wTvB9t9bu+@JkDR>{4(7-9p81Ss#NCnavxv>{) zZ7f{p+kLQNedG5qGHl079iKz(uEPk1ps4X8k1MIOgk(BPu$Z~${}%d+bU;FmG>N&5 zEJJ_a02;~;R?reY1^Gno5)I%FO_FvmQ|lS*&FBT>^_+LMyY4I0YilQT(~@{vdKS#@ z^tcgXaeVtJ428Np!#IJCv8o0xStsK5I`8(&!l1=UQfV?Ql%{L4NVi;ZBN!2TKyHtn z(Qg#mI*g;h)*3+ik)#s|&_!BeqvvGlbfi~}!b zS@bQwT!+`C$RUqlqik!|O(58}sDs#&9e1y&-<)s|N7g7xJh@Vo9&to{5fC9~h(&)2 zfB*(|QTPOp-~l;!;mgRSlWHhug<{g>qO(T}Pk+vmvlq~O^u(rq z0N!g{=-?lvLFMPtj)}8Iz)gT{ofMayq}IgPT2sXGe#2Q@`%(wRV(8`bah8B4Gh=Z2 zhg$|#=xo(m%{HOY&y{wEgCDiMcDYWrF+ zSzE3iz1pv}_BKwqZ%vL9J4qbWvu{y~tYJj9+Xe~f8wSD^Z{+xfehUJr7ubIz&!X;1 zNiEO!>8{AVupr)f!&WG|yeo${?Z}{O+Od$>w9tZKv5b9PwXN&S&}^w(!t}HOClVpi z{A>|SLA(#ZEm1>TRX@c|LXnsjfn`K^?PhndMtmLB@Jje&y+D$|oR-3IKYdmQ7NmN# zN99<~`^bpHb=G?P(HAyVw~&9`to&uXzWEtT27?79g%m9%$Lp?8Rw3kXP*=zH@Q2qJ zcCfqZX!bW?gElpUyA;whQhY(()le6KHz&w1KRlBlZ3zU*D_w0*OC{Q0ee`c-u{&bh zq_hww;t@B4>()!*Km$Ad?HOayOR8YzP7pN=@FLX_CT5IzPLNg3Me~0z#FTDNr~<`j zNeCnYQ;)YAw`g9C-h z6d=N>kxl>74{^rXnD2k$l8Qen`XaW+_bHcg#in7;P4eT%no)tMTWT_K;ApYMz!MU;uXup64RD*U%=ri{UGn?Wa5^+6Xmfrjex>k zoPE7-?&0y7HiT3;D9c2?#5lYXVB|wqmD*&nY+wM0ezI^i8QOoT_>KEoU9N_Nm2#;R z<0{r(z~fU@hS1G-KWU+FTw^P#45^1!=wFDYToJZb1z0SWtPC?ccTAl+W%C{kx;+)Q zXA{`=8Mx5w9-Wz69=h#|GDXoh-=z;|?Hf?y%-~VIpBVmZIB3bLo~M(H8W3n=XXN30 zBPWk14zxODf{%X|8i3xgGAdV-K>ZyRx^ei;DMtORYPu64`IFs7y0Z9X}3Y8oDccA3g!z$C;TEMrklo0gKfm zQXRBQxK2NyHn~$Q=%APEhf&yKOO&ez7SBBy4EUXOO1V`w)xlVGV_mg4uzKsVzrEMd zn6nRg@_B6nB>KVPJ$u=S>q5(bpaknU1cgT!UT zbd$1_(0?%VUkj~NAJy|&FaC~z5n`4Gj4Z49iWc7(rjwiX%&P~jLCKOTj;#UXu6esY zd)7Y5N{1lk=2E;1?z52w9U}(s8*Win@wFkQUEzP)R0lgCYWLQbKDBJLFNW;pBSt5L z81=;ziMVKNlDKf8e#B>3pet!;yV=7*-LDyYrAx8kVU1?tGp09G91)o#1F;3g-S?hP zXi|I7PTszL2ZpsY$qKKIQUhr+%19L}C0u;d_v;_ZG8nt(d|r>S{CwD&!5tH#=Xk>@ z*pz=(n|nesP@4>Vg8N_0;4I01>?wJduTe=YFi=vCoQLqDg`W{W-4SI(NS@on3Fke| zq!faBG9AK^)mGYf(u`|&skT%9+W~al5czT4*!@$Cz zm2XdceMJKm%>kE{8Z&`)(ZrhVkIFK2Ya=zeD{G|S`{*pthAN{fZ*>+i*N|JjA;^E% zZ&WMLdllZYOe$AHeoE=Z-$~TVP0(&hz>~(-hwVoL!QlozZf4;!!8lr(8x$xT%gEFvNovUyGk4O@~PhLD& zG+TL^jOJwMv#H*ld(O_|QJaM-1@GrBvDm_;emm<6+1MP)MpS24EddptAjp9Y6~c9m zKz6;$t#LelOvc#{wnMBQ7vGjhos8DrG4;6RT8+)(0mBO7{}U`FRiTMAc|(6pRk23f zc&{ZiLgOPf!NTSMGJb0Fai(62@NoQ)!$nlOcwAZNF=!%mHD5=v`-Zra*t8aIs|#Tm zXEPcTDN(JBvqGf1JCnUx{MvnZZfqJxw(VK0f)XPfp9+*b8qlT^eQ6rssqxd9T9YR~ zGeUQ2t2YZ|5TJ*4TY?{ON!FfH49QQn*8>L^eX zDa){j`&HmfrTJ2Ny(1)55PPH;A0=}7F)W?ksGB=s5H7`AmAO*>s4Ff_=f&YYFK>p1 zw5wD+=_{68jM8U(%Du}d|M~@ilE^^fJy-)z0OG?t$T78mjVKzk--K*+ zT0%Xdcd+}x0C52R%EHIc`VklQ*+3teM;)X){sJJH}R@q}zgekcxi=cr0nl!e^?Hvezm5Xb^y( z;DZ0zF}bT=YsEWzCL?)hJC#1&#?W-FY6tM7mS>BvS0J=Rwm=NS_IkVfYS8*&Ay40j2k0%?kkd7>92{|R@s<-jE*q&rf zJd+d^uET$3re&72iF{12X}N&R`<}zbOwDAH*xNC#zdbTL0?A2B`E)Ab*AZY0QlSHe zaX{>zqh1}j`m(i+b{GO;A$UF3jeHw9))&R=FSM=IeFRiY-D|_ zD$PD8MvGD`J{M;YORcocwZ0i*LvwcIpppf{+%SK6(}VqO`fV8wOV(4U?KXbxGWgFR zjyZndJ2S>x@id}yVe1Q?_GyHjq$U)6es3<$y7$i*TzU4bYz3i>5`r`E=Z+v=M^o>J z_ZvpJa_d1blZJ1CM(J!$?l|x1;f%uXi;q91WkX-2!6T+RSf6UdcyyDqwnjy%S)Yb#GL$sy_hCpxu?@VLiVSK_WpN{NU8=x<(f~K@KH0!nA4e?Py50 zLs$3^B6WPX>_g0XgbQd|bN$8CT5`m&OyHjJhzdfk zxpcyuSvLeq)JlY#z)UzS3~sSw%Hf*C%13arAoDMPsK%=pj~+jib_i}y_w1hJz>E+d zHF3jiQ@fgI01w`MDHc>qb;g-4K01G$;QOhzgeJ4av_L%bdh>*`NifS; zE|7st5W}UqI4}q9o@E}X#PH#y<4gxMvKv!T?es+I8ve&xEY8Zi>~~WUGLb@kU22Lb zkaY;>yb9;jDZlv4;>SrB!do~NZ&4zV-!MN-gUWtH{!pFdYgkHc%HlWEA;y1guXVa8 zvnN%I4oSUJfjBbm(T7f~?!TZJ4z02kCs7D3De-VVci-o;<+C}3Z$`f!qx=ZvkPaon zdDVPiwT>wqWTy;0RT)m|w5r+$L;Mqx9$yokr_1RzyQ9zpm;Z4K=XV)y(9f-o_8RqF z5dkk*)Oso4wFH;9Xz>%_DIR~RT*{By7W40$TpWnw;UFyyi(o}tyZGzJx=Jbwn%ONF zr>z~7pD#`SF$QCOf=w3{!eq}u5uVVAy4sW$0`2c)TXl*0AxhOuYFJkpxqFQj#Og=O z^m#eIk=5O^DS*HxUw#Fw@S>%003e^TC=mp@o!V1A&iGb~QAVqwl!bq9>@0Tf%G$6y zK?V}TR8Bm2D}ajub90=@%B6zuH0>h@ru^=4dJ%eRs=C?GPInhY0o5PGY9@zJ9whpm zi%cB(=4o4}C~Gph2#oSD+6(@p`4v3`)y!y{0g}jQ7B|^E29p%yla}bUWPl-SNv*mQ zkrgQxWKDc^WlsdgQ|fkRvMT<1HDq3<5mf1OiCJU^!Bh3^dQ&YWF=}t~xS~3<2_0>SMS`rEfeY7M9KF>mKLT=w1+*8gM#M zEI?zKBTH0`bKif`nAxCZ@CSroX#MtS(}4H}x&W+e4)B(M>5f9!WKY*6%DCpw! zexKv#texdAjnV2E5{EOZWp9)AlCM0!nvTQ9pxHrELq1#iz-C zO;o{=or&r}{V{8u*O27~I&2+AIXlFtzzaszv!61>s}3SlP)@+qh9_BXmFE4EBIN7i>M-+QCKOIYSUVp=KO zs5gHLr067xv=a^Y<4D}V{M&}P&EQ%ET6a8;Ie?C2;J)55;e+DKj2oaK40OB2bBGfeds%ETOmnbQ^e4-Xlu6VA0f&Na8Ca_xUS zh*A{7YU}IhGb5x1T2$CJ2h8A16k)cm`itg$0+z9j!EN_yas_?MGF$B}-@)Q8mOk>i z*jdnO%<23oT0R-h*TKAf_5vUYqd>y+b?Ji7noDxbI;t?7D$oOh^|O2|d4)(q{JPeR zWq_CBcD%xBv03D&lT=t4Os6Yi>@9y9x(q$9E!tGwo6GHF8pZd)-4wjy+v<1K5FZv< z0tZCL44Xt%;O9CG>#|^~OjGULstgc8LEy;3?htQYM2LZN8yTv>IAtB#pr@qr-W8z( zD7NpEg!{ARIZMm(DWhJ!{OeSIk)|k)0ImB(uR0xqH#UZC*QK@kBw4t7i5f3S1(b;q@Ni4>Q1CEd6TjvI}ll zST+hb1u;3DErav{228nvv7C{5qf!s8v}0i~A!$v#g!<+n>QhIIivaLYUAjMrH&8`b zL=fc}%Y(YZ+bPo#XMWu$2}Yw{2-JOKm)J!P{;ip{jGGNCC`a+t5ZfGWoLEz;{~zm4 z?)mR-_(;gu#@Icv(^(4uBe&I;5qkm?mk6E}50|_K0~`-HF$ynCWo~D5Xdp8-H#V2C zFcB$#TUl@0ND_Ycujt2J1V-N%Fc`o`4kvaF+c^ipf|h8TJGw$iIp)`I71=EwB5BLc z!vaavB-M3&UsYGP7$H0-j0oWs5z^qm5QP`QJ7TTY2_QW|w zv;}1bW@^th4B#(Qa*s2k;0nG8{}6+wS|Ny0!Vxb#F9!B`sDzT@3G#JeshkNJ}b6}=YDAI%13hdyZ(<8z-!l$y} z6mm^q5Cj0D&HNMx;t2`O~ovtS7^(u~Y{2ooet&<5|BzZb39u}kW z(PFY*wjv;RiNJ@mSEnC7Lj*1^`a%FaFGAowM!@$+059(m0qbfJP^un*Z!K5!F0MR# z`sMKa2wnNy=L)3MzBfgGg)vaMb>#~{`!M1v){AE{yQxE3U6#-#c|QLUhD)G!w)}gV ztZwO5lH=d;)udoSy5U0_*f2?_U{=hCk{sb;x*pvYDN^3WQE_XU&DKjgT~AioV)Bd5 z7wPP3J(;AdkV@z$h#D7sD!;tQvuR56WSosa(lVQ7lcZGE0?F=w0@A0W*GHc|0Z5mZ zy(tHDgQ}>ZMjCHwbmP1M5ngT}5<={ra8KzOy`Txbq9Zz{DZQb$G@}zbr87FG^I1w4 z^c&6TlCJ3L$DFR|kCyL#7vE3b9vr^>SorR`UDxP3bQ-W^81EnLx;4G7-)tPrOV=8X z;VQC&WABbHKOQ}Qe{yzlc-9B12G^9pHUirnQLCfMwCbp@d}BS1HImNAx?|@pM|P@) zUp~J5^8WZqzPw)cmJqUE^u0o1N9ig*8ubHOk6thKxrly<+NuYfulw<~<;PB?@c8M| zgD;<-yw0Xq>*Ylp72PmEqiVFXXkX2LDZH#`$88TfT=B{+Ek)g} z1A0i0=rN?;2|b1MdqdySb4bEV`ksD(R2)GXUT;z`-{R#?#pd(bhr=&N^)Q^LH|xGI zVBNufkOBFjIjn_&H^ac2VURsxaJm)+A-kgRj6SC?=u7&lh{fwoG%yw)i^9~~6O5oQ zn#^aRJHqOJl_sP03Zr*RZ+|Ur(;3vV|AtV`GRSqv_)(UR*3;`r`ZHvI=%hl8yUo)y zRJ!l<2mMKZ(SPVaX+CeEuv6JPd~^Qd^!byERWcjHvUc%ndfEel!)6PcRpznd;|7}VQV7Ag2*lsXVv*2EGQAon*k7)) zWHQdKuj%48qYL=6%xHc)hd$s2=(bAMKo*?+Giya@r+WM9`1IxFc}URn`SkVNpYETf z47J=sdr%aEv_=x6$6=X5RZ zU(@Rh{(OhLov-tv1F0qN->vj5Q?_#-Q0DPB`fZ&qk-RXNuTp3ti*Lq@^2?a*%k(=a zS!O@WUDOWQ&v#mi&Msd+KR;tKFG7# z%@)ot??gH_>_d=;1{;vCif&KMPN4{WkCaHKV+16fl^;bTpZ**{Zr0f{=^#v2O3P{r zOAZyA<_(c%>*-aRLnaqpZaJs1GC)1d(`B~22jOtP(8anT`W08z{W>S7Ss9^Tc4m`* zapdTFW9A@Rcj_2U&JRwHKXkAasny3=*i_cv;(2%64CvF3#SE zu~%IssNhyfs>xsh`hB&h1^Mc(V$;!TJe`ezqO%(aCah4vf!QcslD|ah2az(S%Z7{< z@%Hv_mk5;unip zS<;H^CEVMR!+3hUDSbs5f;+aOiV>k?N1=k-rYcrMXi?RKulJ-(O`23)grVbq`DBvh z|F67>2R}WWA=cFD!n<8Lqv?7!hB%Doc}f7b2k@qThJ^=Pn{%v+2Vb|VGZe!0)vCC} zn@|A{lVyre2z~MX?C9B>Cr4*bKNXwwMlpviwJS>oeU|0R6&6nH1x}MN<{WD4$85a1 z1;z-|vy&Op-##F3>-W5^U%Q%r0Y=pH!=`g*{jEdmE%mCcUe*1_Ri{#~cURv&G2YT| z+WI+ek!t|dEiezTpncH0Wq}(eKm!1|yZ-hWW=lUF5492S4Fi1L0I|CPt%JlZ{o)S& zwhn;ZU4Q$$Z_9u!3OZ3Uz|{dTW_SI)$6H&5Y%#&;-blET3Y)c}{KaRRR@o_(TWgoz(p@WDm zW3~!ho!ng2*B8fr3v5H1=q>Zyka^G~)y?C-#k{+AO>Gke8;qc@XQg$&#l-f>{#K>f z0@c+Q4ZNrr|Byxd-K)cY5AUCxfETmne3Gn^e=^lmw(t~suxyD2-8(R3yBqlQ{hJpb zU$hNG5TX0+veE8e7WcnCNQsfY6r#eX2}(@3wn0hR?LAD1Eq`Vsw#-?7e9fr*EG;Ki+49q= zhbwVGs8eNlT-kCFSE52(`6DLr{1M^uq7?3xDnCuQE;~%(ed!TrkI}-Jh+?!40~_y@ zZ+_rwL^2G-ZqSH^Dz1WHu2mS6tqOJx@s5iFFCL>RAOHsQFc85RA%g}H%@HLbAE-*` z;DdxeYg`E$p@+mi#EQ=WWzwlfr^hpc5$iIV^o=7x-6R!eD5i$Dr+eW ze7K{^WP6}0rGhGa-K`wNxT(l-74g*N&z1L9B^#<@edAijfeOxO69TAR(5bz9get=V z8%!jgkwKM-SQ#ziz&}P+z0rt4m@$qahIswI_tw6*Uv@vdojRq{ z`c12)8I@|f1>Iwq4wWtpa2^74Q{%gG)m@vXV8s~;{WA6STEZX8hG^xCP%)5rutzia zGz6V$rX|Qr8=?EAAsJ8GHp)vwmbc4iLra)-o#`diJWAasI;D&Wcto@bjs=2WGq97+ z8dgD>{T`6ou?$_l@OxAC1@MzgK&g#gzb(91lYx9A-ULl2^(ThmtEkY^jI{=3LiEKtgHIBfF385&YbCUe zlbGgJYn8100YXz6MYgTg7EOg~3rlZGrK0K8CUo*`)hu0;pR~i&q6cW|0SU2l--3y$ zWXOT3{viJ~4Q*%xBp8Ft&ItuvG3XGbkVY|4?DJ&xAoA5jhHWr$x1d3KrFOhzECcnJ z#!k|GEU|9*c?*yFs!4hS@$8PmwQ6+xZ7h2Y@$7L2ZDWrN%3GuB!0$Il#-4I!Jj?No zdLcIRQ^_{BRwdasYGTq_( zS>t4uOgdqzIxMBm+DB7N-V&>w?9k0mQM6m5TZv*@(~z~hWi_yTH!xmYS}&tpYl`eI zNSE-N&F^;v>DUn~#kDAw>|{$SgjwyCIte+{ckhk3%3&f$x#f@mAz>(t19g_9HnlSZ zlC43>C0X#lLW%Yv?qQKfqD|_MBwJw#wKvKhN*WXde3vTfyJ;8c>N6VpubNm$E@&`o zyM5Md;+#fv@}=eJGTH;A?rjrBPB@Nc&>@E*U(g&Mge#4m-KgE{tEF?eT+PBVtoB9- zlt1aai>SfD^YU~7K^Z55vT9z=LZ4%}Z_b)yG=-hE80n|3Ac8f8Z$wDtdJs2+37vM` z35zEEr}nUrs^LQ_JmW4`Y9`04zZSN5wNY^k8|jm((RWzY93m^<3TcWd6KO=*gkjfU zby8M>!yV`ssZmCwM%q*_x4eV>5-P%7*F-RPFmrWtF*ml)kd?-ShhS&R2$KCojmpEz z@n0q?JIlXgI>zZ}J8nvR3RtPzHT`W=b`1#!vFdV&TTe9bK-HxU1TWU zEF`Ed@A7PvG9$`iwxa)GqBap(*oh!mm=#jK&IQYOEp-|pZF7?RRc+mcSx#jLHMx;R z9N*JF`>O1f(XFJT$6|~)tv(RSfOLl5TrUM{V2kwn3kd#1Dcr$GgEg#O7#j=+xhMyT zx&-|bJCue65nczLMfQ-aznVu19Rjsqw1%!+1BQ5a1P&b7L>%Du67CcMpH4(iMJO0T zT&2KKD^x_nou_sP)Gk~>BTqvZg0MK>Dj94Ov!CU}h+}RH&i6 zh%_0;cM;*ig7bb$1`P?a>aS*q(rDgFVGg1U$$(9NM377^voJgCdyp)tQI56OAi{ou zh|T`89T~D3iW(%3Or&p7mLRYc5J?Lwwq__H4aV*{d$1*E&uqE8dj znO}7;mr2D5lMc|5l4>6caN`=V^Kny4#B76cG|;M(=LB&qx*n8Klw(IeAIIC@~+y!c_ng-WTIB+%)Q+&Dt7PPcCnojdAE zf>6&lTO*IN2*ZxL>*^+NE-SwTfv7oJ zPRNvO(aPb1tM4X63zkWh(4pvHgMOiX=Y$hWg-r_)_JK2l82J3AO5K0!xCCB)D&cMBmg92uTxcM2Ll;IR6c?d>>LKM>t|a3Uom z>c8)Qw81F(He*g2q|-zmH`dT^oD7^o+qA4uYPgFJ9KRMF{C4g94q`He&`-%|sC9lV zthEkcI{B2ul)gyW!_-~6O-u0lR_kOG5C0=y!NaguaiOu8>7k9LX$I)Xq1#2pPw+6t%4v4FAQb!?4U{4i-E zjcZDV=#d0-+0^ZiqOoYIToItCvarLdVwNAPYC)N~UXNKR0fN%DQ!4c9GV{JNsg1g3 zDEzeXR{^Tii#TJ_4uhMfmD=X7-TsPUZ2Qth3b?M^d$gv$0Rq&Ey!c!l6~__IY%vt$ zR-cYx8uEw6apRXlt!KRtB%RoTOgWAJx*n`3?wCDE*c8oYXLkqOocRG7u;X&-FNIxP zuIg&@pKXq<_H|l3Xddpk@Y?9)+Gf6O%&wdLU=y^LK0v{x*;gGyiLZ3p*i(g7fL%W{ z-9kMyBbF?t<34_Uk}q{+z~ciE^aT8(3gK44h}+8H4mhD==hnbD65@7x>y{t2=dgDj zTK-4iLj7PF84D>^9H7zCng2Avmt9r(%(6kAVlQND3CYztk5EPbLF-vIadx7?E!A(D zhrciDD`Vt_$Y1f#0aOfCh4b9%4_eo=I@+8EA_AUHw<*>&wnNR8Uag_oF{HMZ41I0Y zS<$1`RQCbtOjdXv3raWk9d+>|K%cKqRLcAxEkDntE8+>@>gmv7WjnoVZ2IQ8mhZuQ z#n5xP7(@up1)F%{!5xKWxpHiha3!J5f48lY|MXR8OTV3%fMwiO^hj|B4TjT zW2sP0S&E_tuG59J320I>cV%32t=r& z{(Nls8>>@I_&eRd3vgL!DH}3fN^R>p>%21b_}LmB&2O;Z2A{MLnmXfz|jyr`}|`fd8i@I`Z4(IC6b!Z!8_zrYo0Qa&hN#Oj_4g|?SP zhX^h0QxnwOKOHto^reKo`{Oxm7Zk}ev`B3j(iAc;N<~Oiu}OYbDfty*f|dD-Z8NTW z0ysf6n&yi+y#XV9{Y23bk-bc|QpCmzG*hF%d8Gp#4My8_+@qM~LPK}eD4`5?rLXGO zv#PCHVp|au$u4cHpeEh{zfkZ5dhC(G+V&tJeO|t5bFuZM7ttLq$XdFy8BfXy`P?cq zt*&c@`xR=(br@WoME9;51ibC8zwR@c#x%3!@;M5Jzk>dHpaMbhN;X)nYppf`rvpTQ z(~5dFDEZprh>_#r;4(whTj1~Sjyj`O2g3}{deqG&^N_8P)mZtu9t6iuR13TZ?j5Ha zS5J*qZ3^MD=Few0`~~kt7qVk)vqNP73dHNp+0k^%2IiknLoY7CsyfrWNw4WKq=9l% zV$)dLQU$%IW7S{PjW<+o9PAQ?QlYB}W~EoaM5WTXNM-cCjWVF>tn1}3gUi)07P^$j zo6`P;hs58Y;Ul-uwS0titN}7_z+wHZ(0-R=-*54cU0KC*1b)URRQ>RdIj%~ed+e7N z&C5%b;g(<>`2q|ojN}R^d?NEl>(;}iHEL@6{Y>iEbcLf(!0=m64Qo45KC_w8Z*OHc z+GTdr`#)eQeOtvzeo)^bgw!J#$Y=LaJiVBN@`GHEyf%;A;`S;BYo0SKU(_owkDLqXC&G(EsY!fhTbo6rjmMi-CAY_LXa*^ehp&Rc|(X~V* zJo5;RdA9W!;e&nMNzr-JW4J9y~b@C zPa&S10Og%JDgX#_>sCilI}GR$E_EZc6EhE|jc_f9509y}LkHvB~2z0+wg zRE?sH!-(2)e3UI|6TCP>HN}5SogORbObjq2#y+Wh5{P*udmwHdA+lq;sYps^R#f24 zV`ntUBlPTin{NRkGi&&m9V#6FP~{MQ-m#0Ot?aa50zE}vD&|!vaAf}&4F=y4&TRbhL_^c$U1v(D#jp_#&(i1P3XrxCWui#7+(5@zB zr{TRc2TS3x(3~o>JD^|vjGLr$p0E+C#e*M9TpS2<8rNsi)4J+&_``5SK4auKpSud& zP{q=;ehO=sgGvukQmlB1083hj4elxg=}>)cN8Hd}UQ(5~(aX{##8)K7!mg7h;oxvt_IlV(Y>4vazzVvvY88X9yHwZ69)?u8yhK&nzL+ZrV);MT z&6#e&);-B%iv<3#UN4F=<*;6$f`eJd^VS%TwV=1QtJ@>l@vRe!qe)6$%z(~#Ocpr4 zIY`EgKrCq#IQW_sdkllYl_F;{Xs+Wbbt2#jCryaM^rjn0u5f)w0uEqi|Tvv0SSljI0KfBnZ4o zo;0Pbu(LwsGWIIGKUq^c-j^tWkMLC)T=~ib@_1vOr3*%W>EX(K zjX2cPk^7o(sFGz#DBGxKJHeUQ9PVd7ihFMBlsKGsP{90|Q#CWR*An{~H+k+)4w(u( zfEx!BZyN5rAP;;6A05Eaf%MPB^(*9Lefnzq)%jQ0GATxiK$%Eb?~M?Kzb#<|{(TaZ z7t*dVGNDdLBitu5vt)idWSWEWahVKw zO+}6l22Ud|JmY67A{(j#PG~w&TP5VrMElS^St>lyl(B%86yM*ArrEr$9=aLx?6=p5 zUwtb@RZRDYZ^1FgT6i-bE^32BibTYa&UiVSIjlJPzv=6 zb4T}UBJUG;dA<8gB+1F797Bj)FTj9=gv@e=4TA!cql^eC6W-IxBE^=;$#?aq`#U~S zkj{o*MT;;{!${B^ph{FH{|6$=Y4)wqY9^y|{aq_Z;d1PyY^=!s{Z}vjxv2M3Cl8mn ze|0oIxGPTjQ#${5!cN1^n`o<br+g-Y*ek8jc{}Q3u0gRtY72T>#F^W3Lv=hVQO8NDtosS^ z_aQNXvtL^~{ijthP&DUn7{L>3db#fD1e{D9h?_6?ebwt%RcC6+RIE8Gt*^GKL{i8^ zst5Y2?vz}c0Xvv|=`U9czsqUNmEc%faxuyoBEz>e>>!Y7FJO(`KcX=W* zF`A)(l(b`ksSt0OAY%|U>nyaG3+}g^h(nh+@4@M$9kfkCRTgB8!jPlF91jtc-O*K{ zaqu5hpUGLr6kNd?(AmIe1o}EC>%sXcAP1GcKRNFl_pjRxX&7HNs>r*5b+fsEz=<4M zq97M%9SxlI2!A)E%hQKa=@B0W3dTdn1q;RluWAY2$*lBB4zY zuNpo`^-QF*!BymQF-+ptFP)UT#*vmjeDP2SBU8=3V7V5Htjx+Z*ho@QUmJv7qBa3< z;uREK;;sGN&j=$SSYKrjic~K@Nbx}Eu>ByVPhtBud}<{n3dmP2stD1cEC#c42Y%3CUOiH4)1<-$XC9?;j#Nq0@aMjQ+Pl2ma5H!r zRacd$@v3j}-GlFTIS}2G`EI`En$0!gyC)A+2fFBt97DBUuRyp+0w9$x1f?u5 zf*5kq#RUAa8Vv2}{IvOGpeQzqlysnL;P|5Cuv(Kn78Xyfm1&63T0kBH0tmD5B2%To znc{_Vq^T`#qwx41Zd92zu)OPXx1BjCe5y_;9Rye_Gx5e#C4-s8i|KjsSdz!p!dQ~j z3rI(@hFnsN*RTBfQsK}Cu?lSk7g&DROE-88Rg}`62?bh-B7_X28K)JFOuKn zCe{mg^F>2RNmq{N*pZ9Bo%J}oEpb<=Uz6`57>CZZSPrU0@ANOkqNq=oy*%poN!TJ? z(KU>U!$w=@`lb&MKMM>^NHK!LRK0%P~YUbC#T z4J%9As)Vi1;su;#<(4V*x9x1ODi_7;q26 zd1;L!@2N)mE9-Bp8I9X?n!JWdl%&lnv(Yrg=jAcYR8i-*3lHUD3(yLKm{=IZFK<^{ zC4b_Ud9gitw-&#e0>#U}{$4m@i0NcOSBY`z4$k?1ziQLhoF8N=PJHzTheqx_YxIrq z{L%~?gBl0RV`dm1nB}+HIm;rp=EWe#7k@C$(^9ye`pY6r_jwDUyF@lRopgA9@Een} zeRw@qu2NUwL0Yr)-Bqtul|K;kO{1G>cv-!BA5ZD?>w?faWIBWe((bv%D zHnX@(JPG4-uJ^;YQ^w?$Y$=tIK}-F^-|pm*GuFmkP%EeNy%n((6NZFdxaSM%j~E;8 zmxfWdnnuR)S~v8wefpWMUvBH}KkqKsSZLZo;8{7I@Sf0RP zaN!cc;?tt&uK8gd=vPHQafrWw<*k&Cj1DgsbcPpOX$(ZuutZg?_QaZTzH~^qs>Q>K;@g-!7KkqnQAT-dQwE~%z#GOy><@9Gd z7rrTdNd+QcsN*MpZvOV-O*4Gz#iY$6c4;^~hbtvm8T~Stw8*lxmr~=hAZah9WI2T8bO&}l>40Jy+l+Sz*juWG; z_|?j~vywE2%H|o~{%(H9kuEW$h)>HHT0{YX_Kfr3Cz zOg%7;9}GckXwZ$*A3Tcm0#5XHkWH5mPxCq`)jN?Jr@j z%|{C%_opadBz_u`dXdGBFniuM+LNQff}()8jfW*x-{LxYNH@pY%JXiWsRx14e?ppR zn!7$JSvuO@+vn~Vw#pB?-z^DC-y$sf*XaSNC#gq@I}^nr<5(v8A9mqxOBKc9)-)p_1FRGHEPmk@@L7@^PHzZAjMD-p&~Q;Heli<35Nm9 zVyZpEaNEMmAYhwFo-7&^2!JtJ_5`+_yTp>Lyr6^is3^nN!NKBk1eBqg|@p5#~1?MK8S$;I3#AzsAd124ZY6ut3^%z(tmW-;)HcEChcU%++{ zh{RAX{~kyo63xPdU|&DDg2fe$zM}=K(n#dMGeyrAiH|X$_g~(}sdv#4Oy=z#=a3t3I^h;3AabNhY{h%GY6rr%mb3NNCz|0l-99#>bwk z;*U)kH;r}Cw~v*F^6vuS5aH2gR3`nL*-eq)I1aVsFcIM`oQllw9Xy3b+TY5|Fy=)m z#yl-(DXglsCg6-xW$;8;ews+=k)fk=^GUb|2^jc=a84;Q*s2kNmvK&(#6l$O(iRV6 zcuhoJ7impIDt`OHcMR_Nao(Tmr{M2n_(Ol1S@{VWU&8dpg*&RW#s%53(40nq%eFN# zhQ|31t-m~3Bz!uAFsj_AU29fzm2cHrO&qlJJ>y2S^j~IIFPwR=%#KR9qv%xxIcG6P zSaZKgT=RYUVTEp4@kg|ZO;(;%2b6`SJG_K=FJR!4!c!AEMKw^&P!R=`zbuL*<4^1- z|6tKle54eCDshjyW!!Ib_xl&$iXZ+Wt_v{_d>eA*vu zXAGh&*GFj$G1~O?KSs4E`(xLutdU~q zl-*k~8~cgqW0f&g4Zhqn#{Gu09_AkDoWbNNbwaQ(%B-$bEXmIpx;JXghQa>tLY0uI zq3VVCgqzoo9YEN`h?6cN{1HYB`Ypuznx_7r{i?GCHO^UW;9K0D9vJ*7#sqbz@ccx{dza2W_5DC4%=Hu^lry4ej-a1l4$M#gE*`e3G)>;yY>XZ*UWh@RNy{;-{TtY>$#Shttkub~n2B&o8w^J6X{E+Q0X zWo+%aCJhYRPkTK>kpKzK7vq_GDrAi>9uR=frDgJG0`Y zW&T!AXWmA>tCXMTBZA7~#a9Hve5({BBf`89aaIj=h*I|sYfL{q0-9rA2mE%hRm0Jdl6>`^Aggbnm^~Z144p;6ryLX7C!qX9ym6t!}t> zl_M9^HSkdNMmyQ4Sdn43vtY@MI6S~d=D4e`)%{ggiE zF|T0FWkhR_dim{$O-q4ajK8o0LSunxF5b2_c&WLn*%V}J#CXYjS$@Q)rRXaT@E3J} zb1h3q5IE09aB>g8Hn$&(g0hVfFL`PzI;F6jsH3g*WOt2p;AJ zi~T{q#z$7oSOH?}3WCB_iw{<#u$Kx{)YIbM0&g;wkELe*wqvia#5J>0dqteFvn{_Uouhby8gY1aD zMy0$}cn78}M-*Oi+26#c^7>WRRn}#uEpKwL9|_U@!I`bIttUAR2W)kK-~Pid$lWEm zrHo5C(!)}KMg8n)g4Z4hCpMvXV7qSKVIkcL|Kd%%d4t2W%CY_-9$d5M~HpZ(%oV{_VlA1N!dukV7omH%pcjf6!w8UQn3wVLf%@MpTIL~#^3(>tP|ws66Tlnt+B3u%x<;@KuGr=&tSYxv@ZMc3_z+! z0u|u@LF7DSKIknPUC$ytG(5UmHEwXPzLZ%bS}SsXuw&ZO%3r;}_`Va`Gha58euz}$ zmt?ni{y@kt$u0{&kbJxg(~vcegPM6g+}66*p8p_#z0U6n z=WW!@j~>`sjz!!o(=Q&`*dHQU$Xj%<8I7CuD_&c~V-#fT{jIugvhF^8Qh(g6-rT-* za*@#-(p&{H{$Z>0L}17%7a+?o+EvYqk@&kJDOHf$cNh`1+bJr&K*Cp~tDG01$*Rr@ zhhxmBRMFBCEL zUuR#po|e}78sjTivKE+yG;JL_uVBLz^0OJa83RObMENn++K=e8kUz#%b;x}^S)3du zag1OKI#*ee_)hE*Rpee9gvOvwBu?uf*D4CX5%opzRz2*)px`Ph>@Gmcv4=(&PT_Vz&#bsYh-dLRp3HGUC1n>ZwP47y{>kljnho*n=Ys zGj$?V=%-yxTA=i)Os*F^ z=>%On$k~p(qTnNtT1LuIh9I?=E}*doBa@2S z(^|izenaP_F|At7KMQ)8m#9>_MP=6I^>J2G;#%#R z&5Icc?2WAurCvB9#dT5EE%ykWI{iN{X}tOCx#7=r0p(-mdw!AElTQyNY8$sP&UsqR zBSnm`_UKlIiY<`3`|1r=cisLtxH}epx?Jn1A_nWf76KslN(_TMR{i;xP!dK<#7f?f zhKnx8Ju~GTB}n6KSP+_wkSvA>GZFEoLjKf)VGr^!1dk|1z-NY1&IOj#Bc%@^Xu;bW z6NMf-0t-`hnw#r%tMJq+mzDq}hihbdar&%PhuY-NNs4%`ArHmrAa)~<1wJUv-K-S< zrG-V?#REsxtL%A>IEKeTk@jN>NXKrUv3Z|WFjnp@C{~L5J> za{}i_R@p6t4d~CcpPFX3&|GJ{{O$rbx>5IHfiA~P5iY;UaBl-spz_PxSG^w`jm}7N zm;`10zw4bxO$|1Cw2e&hr{3^!`eW;y;ivBK`O1tvR@z~FYHo3f2iMemg{TEDVKTQk zi@2wj@D+DyPqs!~y}+6G(i{@>zR0wY5R9rD4CyitrzjJxZdI17lQ_ZyKkFy~#y_^> zfT8SPonI@-ed(_)hjm!jSQX1!m2XYJC!ECbbh*~g4U|C5Qa#MKT1t1u@K&w)98&dfm7%1|LMT-7KCKY5<+ARTe)PM0h$%c)-3@(!N|gz%qjNfkvVKpT|2wma(6_N zDW@v))~)17>>VA{z`h#E{+i_}#W|e6rh0iVjLWUK>n7Ug$f1tcv8WoU)igtSniUUe z>f5?7ug$5k%x?v$NQ`(oGxzG6PeeYHMa9-`0s_ow~uL*}h9h-jArCbeefTLtek9UNEicH+GqMj_)kYF?}-IfHV`q6Wjt$R9-^2hF|kjso_#4^XdEtE4RbQZQp4`@frSUaW5F=gqob(pz~ z&m|X9icXe~voy!b#G>m+yosX#6Xl(e;&?6C3K`1Adv4=x3yBN|un8fQDU(_G3)g+o z1PKeWKXgniFt)6Jq`N5Lw@}W?=4B|uM&(bBRXm^yk>Geq5=b8y8lsIPvPLe95=I6~ zz$lO20QD7K^LlVH*wf+#O7nWqO$#T#R-7yN$~8C$3LfV4AnD+z-3tPMxy?k0?5YEz z(&y$302C%4)`CaAl-r3-VTzfgKVm+X;GujZ2<_X(`i#9n{5Gb)q3{0tJmW8 zU(!5qWk#C#U)(4RR&z&%-UZ@QF+c%hzPBwi0~|RKh)(EC1Lj^(sJnLf@1A7`beg+# zn}ND$DdA5m*e!L`XjpYX{k}2&`=b!nwLgsVLp0wCedO7)uIJCJmNI^Rc&+8EhTH7- zC13t%tz2bX*%*N56FxJ)vN9-T^xa0os`|3N6@!wt)&qAvif-}q({rv5{`-vK7=O`^ z;kkIAJ-3`j9G><}v}*C`(Q(w<*;bik9ZVT(9sYdb>HRezXK)=*NDVK-9^Q#ZP_m35 z4mQwpp~^kYTR4JmNCpCajog zg(3o&;e{+n9YTkHS@L4sR}&Y9!YTy+;5Y|m0#d_DF5!SolqfIm#6aTsP)kMcgR66+ z7Sd0ncDzF)D=Vbpv*Q<(;$>TLq(KCgxKpF6|a=1E~_X$|dxVo1g9 z)YzhVsHoqb2X>+n#ljRB!j)I}N9Wo<{3D6t;o~0ZOADMgKO5r%FgDtG>_d5PeDFn_dvCuA=~4OocMG&g~t?*30zQrts20c!hMf3M6xH2 z6-__OUnN=h(*lbrM8RNz|CgrnWZ6TrBn12^p4Epy)`FQdhOQ31uLtKEq`0;l^0^JS&>Pv^ju<`wyX{PjyCIE8& z$zRaU1oS_)z%BrQ3MypmGF!7eVw-q0RfbmDJfEj zawfE?_5Km{!4lH2Nj=(8>2urc2%-rqTFe0X?sec|$gSFYw!d?9H`1XwDIMe$YP*mY zvaISG@aB_4jRcvtofl6e1uP1KVE8;pNg=`UPR4@*k$ArB{xOoTeBVhJQ4h5sFlJ=%jd&J_j{i`va`DzsR$oHE&2#66;j?U1OZPV01l3~DTOhu?`(dHC*bPnGxTW)+ZM zhSgVw!)lXHaer|N12BY{*Asqpx)y4R^*+TrO>N_cvTCCRX=|Lz)O&IQxr(G~L~j>D zR8J=VI$YWQ!($b?%NX?{ti6TmLJmX7aCH1-FL1W~@Pvgh2*Zg+{&k|1=bC1?FJ&@* zW{8(3i%Rg1tn&md53=fR{>pFY$gYIRG2c32v0ePlpsYYY;G_TO{-f9Gj*aFDhIU!+ zBLdjeJ0UMUw3B%s#F0%5gRArw~mX$D*8wQ2rAszvY~|pvY+vW2fzD8QpRbWvhQ7WCkpK5XoD?FYXnrvX;}6-;8OL$w~E(`Rh`hLZ^qO|DLUk$(!N zMb?VBQ5IF1cHM4=kdkhRlEQ8=TAMr_+$JHweCc&h7;sKZzLMSz;3n3JFCFLjbd45X z>t01%*0o5=tIvCqC!2E6hkYz9&0R})3`7ZQLUoeQVFfXjb!jdf{;C`0cL+IjBMH=U zBMBmO%i8S8r&>uE8#kH9im8QjtEqQ~{${IR^D^^15BIrTB=eO{{_4rA`yZW;YnZOw zyleZOhA@MDP4H4Z0JA&@ zTaP}vc-T^QD{^l1#V$zR`qy5<)rWc?a#;`QF=(&~q9S>>&S^vR7z*G4gDr%Q*!}41 zVke~dA$T76vR#gxAX*;8VUfUT_J! ztO7x0H%NIyh+gn@yPVxYZKOy*$M*LyGMw<77v9G^R2%OwAID$L3OV(q(k-lRw`)<1HN z17_ZGws^blzK|mQ5#0SJ_feJW)$!(R$H#5pU-$nz^8XJ=%d2iTbne>^7 z(%h^Yd_uPVWtyMRHX;~k0ebxjcyNRjehQbtr86!M{l62@w`u5x(qb*(P~ScU$w1Me zmx~qrj|t#^ET}RIZi;d6F0%iXj)-q{~vQiu4g*45D6zwYo4Q3qTD9)Xc zAOjeIDMB_a0%~~J8)+DH*kH6BU~J!7Z&*^#rMt?i$^coiKS&k&&rhsK36Gv(0_Wi~ zW*&UZy^(=NW(HPvzp1dXj=CLq$;;sH!uo1e8X+uxW1I_^rmn%mqI&AmRa9bF#P=Np z+r$yFo7p}d2)eN_>VZL~w0)?|VXU%#CeUEt>!4pDiy_Sv4#Hj7pdV1EWKPEvyhT1@ z-VUKTke^-SrnbE9_vO1|&v^9-6HfVMQn(^0^py zNc5Aaf72L2d2qmQu>xv{FaNz8|yZZ zn>Mxh-c5YxbIU-2O8pOrqv-Ijzl7VV^V9w9DUAM%ULum=$-J4X(~Ey6Z^mD8-;DjB z-Tx3n`mkoL%zk;>T%08t)m&Qp(gSQP9`s}s4EiN^1UX_`WHn^XsSPyqxto_umgQ(|Y{TV|3oiM()*ua9SqLm1J~Y%VzVL z*_nf%lNex+Kl(P>^^PX#s(Nq$pi64oyk0f(fHLq6pH&E_72|{g2qh607J#*#=;AQz z)8cn@$p%Il&j4I{%g(zYEpguT^nkxA7dJ6qYCnRBVvRCQojXCAKw8+n#Mx&wjInsU zj?N6epk@1;Mx0W3A^n3)d?2gYgfFayU+rWAkQ+$u7*~lmb58q&p02OxJj!(HrmIuT zDS7U3IuEHiun^lrJ&9~;Gc&<4%9%S@x>*r3vvF{x-Q%E90c$ijV>dZa{QqfAn?A&g0mx-ofZ?;Y9PJA$$(wklaks}jIUodNg!7LW0nL% z%L`^u?u68hLO>#dO7fK~ZL-?G)Sd^X2s{)}!D`qe2Emau39_nRAb=uH3gqNc=nsbh z$#hHD+r)ry3L!Pm`}F~bH4Q|0go1;?^+b~{ID|Z)m}qbnP$AVe3yeA8rIsGK2$HD~ ziVGxEDd`4vDd*-VmL$MXOHdAL4QffFyTHSFCbq|b=8!5(CYiy^ty(-5(I%XLrk?IXtlRaCn1U|Op z7-+g2WJSg0`*O2$a{9iYYIz~(5ISCF&m3J{&9{M_+$L;*Czm`V z8wZ;_ebvo$cKxj_!NhuKfAx*1>TG=JW&EC6&ziDP%bodBt_vCDlzATx)8D262RjGY zdL=RL>L<7LTugY!+z~Ovn7VjahT^ND_*XQwpqoq3U8d;Z_Pm+5u|4 zAa~f~2y3Qo+L(61A>{d7s!lZ&7KpDtLwRp@@|~yeJpCD74STJ-l#MsFwl>ZZr$W-dp@tntNdQw*EaA{{L>-r!+zM0(K_RRSadFQ>q z^0iNAsXB9PaSd#Ak)AIeAfXs6m_xL<@o&Vjfln~M(Rc6*Jstc2{cl<8$D^3EUY*wo zkM%|TSC8Ew{6ARgmygtEzJ-eO`)mS!tq-ilc{+NhM{TV-JDrD`I&FXdcpD`s>en+L zpB&SD)^?s(3Sl}?rt3nfj+_dv`}7olT3laYd11eLp#VRtPtjxO6dns%2z93SSn=N6 z)PDnqWSX+t1~e`iqy7fizsz*Cr5{^Stz6H%KCYQx z7Up3ddIJ3w&nEY@9(jie0dzKpehJQ+cV5yd*Iv+zPIpFrJ-dgqjr33=T^v&lDe8xu z$Q~#}fV+DGT&2)BD!ox|+o0!oxkthAYos8^wgQ zzR34RnZ){*z-Y?nlrmQ}zJD~IS6PHh$ez62f#MdLTRH2+$5=5|FLBKLyk-&1@P zc9(t*ZQJ!vFW(HIiOjE>HAJS4^UPrwNEy~Q^77qb{L#CQgLMzucR!#AgoWa13z}Hy zNz>3&$XuKp|6j?ov!tO?p;7}|G&WuSN5`*fUYULphe7mbQ6}L^cJQ;+P)-ytDHsr= zCMv6jz{Ptc*WGFxV0e$Rr!;3oh@=naZu47uf}+AkN{LZZ2bif10}jGX5)N=xv&p?^ zJ`=ywPP|S4WC2(J)+=nVm2){5X&GZiJN4PQ=tQ;nc+?V9K~tF~FrcEi_VipxBiM(T zLdTIM=s#Ro@^Y!h45h>as?Y+N1}U!uWdbs-1ma<>0ncEZLxKiMIAM4LfR@vmv_ivC zdJ0n`!3GLu!dOaS;1n<(En zg#x_YY*4l|@u|?P3lQW0`_xF{NNARO8Eo7eiol5g8x>9B!Fj+KLx@4e0HlM;Xf|J2 zl8v}fY{o2PuaIv5KUHE_%dA>n1}#_^BM7nz)ficJ^wZ-lO3VawKn$rr*4r)yR78<4;V+ zK*FZ~AYmoVti&iKi)?yeSg;gq9k=d;2JRRlHThB*m&L4n115&pR`*_eK?)t0-UNIs z3nWgTe1;Q{Dm?vFb++IxxC=Z_ZMdM^>g5WT|4T@5w>>U4x3`$GK>tCo$)>t$?yt8` zZr;MO>`gJOYrx+XYr-Hxz+V{YPUAN<3$Q=v&(E+>q-plsU@-qky8`lGk?9z z_8GiRYisazXljb?HiQnZVigD5UA@EQEM2yIXjTqzjQ>u?SIpSmU%2fRj;W0Tk*%w6 z*Xwz=;5i5?9vvls;cX$)uDb@){(i*-83nK1Ne7`^(Exa@w;)A@+~HACIt3J9p0X zla_F3-l7xO7l{5-f7%YmD%IVO#_ovL?t2+SMj4Dl*FV)JB!l7|v?^Y0~Rbrrf3Tc;2(G(}z%L%U_n? z#&_3m*{PsPUAI7#SoaX`E{IOUV)17_r0?mv`ZCd@c4HNXx|8STrvKXCM@RHGy#fy~ zs5hgesFn(L*6ffTY|)@-EhdkRNMR(-;OFlz9bXswCfh9PuKi`N=MrZ32$@%LN4{7q zgeB^!0+QVpbyH8SMf@)I$NBVaH8MitVWla?r;8JX50_cM?}w5ayQVxALfZBq@w2g_ zTK5*@7m~i;+r+cbONfX!uHjE!*%Mko%d~3CGkWI0vD^$M!uP|RE^|-Ym88par+?ge z^=U=*5}dlrhMtBvS@!1}oy#b`#}|tp?i_#0kiH@r);-7~ZaJ6pMA{=_wnH$|c=7@D zXAZ;|SF6xNzv{!_0*u|y(#1t%f>9!0H{_jCV#R>N&aLjpy(@m5o1M(%(mO0bV*w?9 z?F)TR;^>6#6K5uNWupL;_YvE(M^D=x<56(dJF-&*(b&WL`SI=WKVhoT(AU6Ao{W_j zvAm0NR#`Xm8Eh!Rs2v=ZmisLJKPz?5%kgq!Fr)WO$i8l`sf4BJ0)ourSC8v%@w=h_ z^3rZ6@`27H=XD$H(*%+{sC((aD(fdDCQ7AZq!f=W^{dy5?aPLWYHnERXjVG6FvFhK ztk$}f2v}#Lldxh9WDnNl^^LkXwrT%xV?ghqze!YOZd38u`>na#+4ruz`iwFujxxx4 z0Hu`2k6gy?`302brgb{_X#9+B46KSMs@^$XoxP{S5BT9T>y3G>iau#`(byEv@rzQlcIPC~P(0hlHa z$_2w6;boVE-Fb&Q()ssUWpj_FF6NSYSF7uedqmzgMw=%u&k(P801zywk~m*%ix>z= zp5W9!WO01g`=KWiWWT;l^ht~X<~r#uWZo~ni>4Vu!SHyoNdsK2(wqS5URuNX3e-+r z2Mi(ojQ0CjfLojxDg$|+LB6ewzg;;Lzv2(}OW<43!%lgl-WZ0bP`=q8O?imE6nCC= zt#c0LPokSFkw%%N2Vt0TQMC}~?*`x__Vn%;jQ;KLvk;=;$)@$%_CM|wn^-M_m@?+V zL)41gsT7jc8bgysBzFVJ7@%ieVaz-x&Lw~om+G7SqlpkiHbaaNm)-g)&p|{mxqFA* z+O>H`9Vlpr`#S%SRrN7yIBY-7m#~L(hf2YSr5oV+XdcZ~JMfYgwNCx} zmxSjevCyc|HZPtylB;_V$&|Szi0~D+pRK2#$_f%aT)3Yh$IY#KD)fGDl}|mJ?NFZN z0zGOz8Sp6=w!Ce6){_}LHtdW+da7{|!mq5hW~wJ2YmhViIhp>}J|Wx2`H6otE84#L zyp`t!yyXV`_hXVJ_m4{$Tlce=RE?*)B=4M41~CS{dBD6wpOEoMCG{g?{LVyc%R~d! z4F>&xR_3*?tnUUF#`dYE7c9JYD*;Q4pal=(rQ}AP%0LlJLt$v=WTF2U0gPx+=V9WwHcRyH7?E>4)IzafAjH$>gA1vJ_*_7CvLk}{6D5dK z;z$5q_?bH}FuU@Z=_RScA#DWK@YhKjD1-|Hf1`t+5aKi~bm(&bj>Pw~9do0V8X|d0 zV0~^ny?}g~-^{ou^Q6Va5HU?%AK`!E>{l7LNHXo}d*d^>$6}1sf(jg2=@&-R;dkjG zR(QG7#VDSzDXS6;e)OY!`y-zF`>%qIun z1ex@J!k`tJvpCquy9T1I9#KYJLPxpG#bXq5lSC%{Ti}ybw<-&$9OR7quxK_(`&#zn zgW$~tjDhkh;#Qu$rI%m|l2gZMAD}%%Ypn}%&(0pTM`n8lX;_$|h6QZoOVBi8+Ylz= zNnPp9t-MjY(Lvaz-pNFAq8TjWj4Fa${hkgKsXBq_i<20k`3CAAO7({=%{?60$?5DY zW#U3Z@~g}PzaP}ol2!O2mHE^08|1c55jnQh0UdwbW*P*delNhaPl~`aY2zV`(80TB z=*@<@dFxx9>CE{W1Tsi6Du*-BX0g5eoD8WAduAntM&()`9ncG{UblmK*vZ+%;%ba8 zQ_tPU&^$_q-U8(ci7*)SwNo)~X~}5r>U7%!5m+}|&-kw>^w#AmRY?*%BRFRZjT@|1 zeI&+xQ5AF#{@kRVJDKz6K&fDe4^iw+2hAx?-sIt|h%dtJ(gOO zF8gAn^X~IHX?LV4LE~hCf3{#6&lxoP>4UMwiTBp3r-b3unYF8DJG$&ERR>o(tJjua z{>zVG|NYARyASc9W@RamWb?6`;%J=UVa{-aiPFm({QNm_DU-Y^Tyyj)fJ%9n{gG@3 zWTfP(*BFQ};33D~QGZBLx<;_H`&N&r24`b!!b-tg2EE*X;7#Rh4$`W5psCAZZxZ`# zjpEtQ6BX>HSkC&ECx953R+N!R_9@WGEW&lfQ*hHd{dZBEW{_f>K`0L9Qsb7GvH2qX zVy5QMYO(MF)jh9f(w9meEXN@eIm1dou&japrT}OwioIgeXSa=Zvy}cglQ}D@7+1%^ z(yD_6PBX$`Ydj=HJUbFiRCidM5Vi8q!0@HE;=Zn06(U_G%%|hioKXU^sRq@+-rcpG76%DM#qY>FL8+sGjw(Om8A{%>+wZ^F*3 zG9!@Cnz%L&k^GT5?svh7nXx*j@js?_XRkKU7@kTevqA*;HHOk4XSa_ZNaIum-NG*L z6@)$Th?8q#-u#fFP!t&>ZYC01N(XT)#X)WDm|H37oA&}Jc(;Rv!ugDrKN6Dq#XEy^B_lvfKS@(j%+-!MnCJk;{HBaNA=>9-UVa7 zGV?(}(QepYY6pRk9ACek}<1(G8%Uxsz@j*_9MY2vys?A@hUqwN( zZ*$lz<;*BDhTZWWl(&Bob1qcR%1h9|@qN^OFg!Z0H>-+%K<7;3kkjb1L8-vGxY_@& z|Mfac-*bZlXYBTax;+G5Pd3%e*He1M&9ZFMWidOaY3W)76ml6aYJ$T0{hU%eabRtk zBi=&3BO*rG?v+38doF7DGV79-Dc!v8bHHv7c_&pe|N9-B8$UhivaN2`(V(Xn-~{5w z_+rY`-hmH-;stXkd^VOFw_I|*H-zFn3OmvGN?NL}wu z)~_t!-eiC!V!7Hg%mPTZuMorh$kp_3dXm$6x9lsW1LlnsPAA0-uV;+gL5 zdJ8#kaTGrqU!FH0hk{n?)wmKyn}XX^pP69PRSX)a%`IvVX3k3#K#R8jNy93F2L>F> znqWd7jxq@lc%l#IW0D5WgQJ$KBKRnGCmxuRiS3CKZv=Cp;wrXLow)k$Tf>YI^I$Ov zb)$s38w%bExGMYVw9Z^ zX)bAV6;C9Ce}yiz6>o)Lw@pb^H?pXW;k&yZRd^hV8s^Oge8OSJp(;qa*dQDa-{b9XMs@v%?T}+|95SNm~P+poui-cM;ruRJR+s zdE!UbL4*rYMVS^M`ZlrDz&V%7(ihBQ7TW`Y_pBlM)97RMe%a?+WWJ`weFvMZh5p&T3Y{Izf+)R{Ld2>B8_I-ME_*B_b71_+W98U6xhrXEUNxi;R z?DC^04&#<}BB3V&?%Sp#Y-6I1HIQ9#Mhk7@a41S7ql8}?IbPHwK)J?g9%}iJCFf52 zztkU_|BNT?q=%LWD@_cl6giCDNlExiLEq!Ss$T+z@lURZ3jk`HjIMFz!E9#%+)7?u)X6;?sJ%Kgj^839ZfkGX7>VD&JiY& zGPf_Kcl;YdoX@@}x9kcZyQ0i(V-Sp-@zsgjbw$;>5U`o0oo8LGlRG(MTe^;O+}@6Mzy38QEqZqNZi*BuB_GCZZsHQ z@{?)9?3)$2NeZK;cMO+sS;hPeUj2_+cr^Ep->f!|JM{-IPZC?sy7*-!!$=u~3-))u z;P=`d@W(#o$nTt^=E!egRC_j6|6Pyjy`kVAqe{UweD=~rSs`hO3(tymgp8(x_u%8$ zJ67cD(J3^Er$1;<6Kj*LCPh&3gy|^0%fKGseY<+0760~`9F{XH!c?d`kT~Up4B6P0 zw7To=0`*pV!G=+{jYf655pi(;B$wRIrfqZ#sNs`t8uIymqft%Ewe-W7bTI7))rPjU zCb)5f1nTAz(IOkdPf7KX-!kYZ^1GMu*Pg=ZfNs~(wuDTbfof5b0L`be<7d!_W21@0 z;~$#%HjXlN9ly5sHrQqIS@Z-2Z)M4qGzmj(k`YEHF{fIcZZ zVB~QtRF^|yQoe3x$MTv!4ab*u&w(MHhq&u3lWy$BdJz7+^D@_r2t_rn@or3uFjui zk^?)LwC9o6NJ+g5PPfgL-byJ2T)i1ApjF;W8;cY(Vt(iK`ddlV%uj8*SyW+<&O%iW zhcXI6Z`%vUz}K%XC;ORuncv!N-<46xcrNxyu&)JetqHmCshRFZ+CRpb{*XG`q4rLK z(f1YW%O*iKwc5S#h3&8F$6QJi<^*`3e_!^pvNV4{c?hko{?{qu=3;Ja4`-fQ49bYY z#r6Lqqb!_k|LYDEj!H5?c_AwiqK-GL(uOk$G{RAmcy4a`M95^lxRE%Rme zIA(kM_a(vWahSbE3s6}IG?4jxwdTr(53`%l8sgX|`kte(9Gb;FEqNXl=W`zL@*WaD zjF`tdB+K=+9p7)G6wSuIT33R5rN0GJV1l9N9zy*(lJ5s+Q+-XCW#kDfT0vR5hyd?Oxg_xAjIE2Pab5qIWV^Fej1Uc7y^`X451{59 zg-MzbU1u(M-s*n8F*4sOgTd z=~f1H5n5)AXacnz3zcA$GH|4Qa4u7dDbuyOpTvMkc5+dH$1;T54=u2}(SniE;E+}l zky@jH=29X8LUW1n$V#PlMNjn;JJO0w86n7SjHZL)PD-KUi{SQB4=L$f*k?L{0w=-b zaIlfakHjFVBJq++F=ofd5WkGiCrXozU-Rjcv4h0)yQ9e#uorega@;up=f6kSj*5|K zOj&`=3_{hj+T%1rX*sTRjiK*GA4b2Z4jI=GLGf+~tmtE7<@`-93^^S+O9LDNHuUo* zf3CH6?N`*RMUDwGC>5~;zgpkcY8a+WR_aWSRSV^w_nYd_Hz+ zyIXcik~w|#w69hz*>~x2Sgcmprh4%}#l8TY<`}Y`|9}Ln+0E&=wrbzLTWkaI_dUFp z2eSVDb!RO4m|FR4S^u`?Ad)kkbr5pYChV8>?M|EVXwmkxJgKwj_&h*Ij-LHk__TJJ?#T8V12@>-uF8GZo>{h69ou^;p|!gkkG0;NZ)Q8%Zo@s= z{(T_B8f*#sx?%rfSMwWKZ=>5qGc>yQd(G{Cw_026GTtcRjWS-8WziooO`GomR~aug zpIJWxkNp_0W_=!Ko2nwUUhQZbvU`(lnAZQ$$a-BLy*ERf#q>N{`un-D$te*bA5)dlSn?ylcCWRqMY?L$``J)4pupM%w(WHNIcxfT${27%C|Z zr>m<|#~;4Ck7%9S{-Vpt^ky5biFX0J7WPxUGa9;OH9E`HSnO5eGd9Xi2j(MFk!hH9R0hi3 zgra%a^_UpNJJdqhmY(FeK#p~7+F??pMxB@1LjS%n#W{Ha1<+y++0VVeR z(;n?7#DVR&a*L@!&)m#qTml*y{g(!H%8=UUky^Y7G6u|Idknwa_ij%j&eHmMP~@=I97@Ogz& z#nJfah+0G$Y&Nh;&MjRgGd2=}osS?#Xf32B+K7^u8+t%s@}FymsO99BpR81)Si9&g zD@P;2h;WiOfJl&^sC|oOFh{nL3>HI=f{iB{AjXO^S>OUFi?1*9<^oM-atDy)1}R~< z$Ht?CBaY=csdL8wFep3|5C~VGxtD6jvAMZw7yVBZGk|iAZ|Pf1U2TLEidxbruJibJ z2m*=wH8t68A}HFi{p25oLvkl;@=mKNid0O4;r8nTL}r{K>P&V>wxW;*!n4;66)fS* z8c`E*0Jh(OFu9uv%e3_t<1H`@e5VZ|7EGKN`^2F_1@mb-tMvSTaLt{X}`4Ieri8G2pKT;x0_#UwfU-$0mJRv-O zba6ULuB>tV-t0D&<;YSgJZA_Wonk3KT|$cxW@->J#zlkAe$h#mYA6;aK`C^2Rq1`wEz@|2Y(gSm6$rJI{u`srRNV`Zca9E=ESZa%-x)Xq zFMAE1Y8+yiC(06@V2^qWDI@yUtClg=p_*&%$;}1p0pn4Bov`jjM2jbH6}xS2uO1nO zIE^_W4*f(~nh;W|I9)I%x_1a?VmMq`n>@*%Kiy_#ai_}=LE1zxt)Vg7f(kB9*w!#e z0Ngl4c^sFAc^E$es4Eg){Q8eIVP66=S1L57s4!2LB#4V&l4zL&98<96mJ!}Z#Y7jw z2+s;+uro$M+35ZXqMr!XLBx$_v;QFl%N)Vu0t+w*wAYDh?-FQ{OXxJ=+);WL1qB?3 z{ZZ}FM@bZ%LgO$#Ug~IPi$oP3cUK4MJor$mVE=Y1Ovtfo^eYHeU=D8n3$-%gA z%KiPpg`nVtULp4~qvS15tmvc31*Nk)o!9?uQupuK&G8~SQY7@n@mMNS@YKbBFjV;d zFKKia-!>gI{x3bu_(o3sFX3ZwQW+?9=X(j?2OmI=z()eHF&L=~)cEMRp?ZQ*p5R30 zX<>xxh#~0Vpn4)v3Jo!z z8v!jR|DCdvH}k;A1o=p?7@`cCF^QEK3;yYU7}SxdZ`!F5tVyuqtTUhhSIld znFO==0IsAMLIrO#8DG~Rrwthruq_sXPz-IRsAZrS5|iW`v~!kTQi^I1LK!~X;4lk= zaaP%9k{$cjh=df0W-MwQ#tYfow9=AzHiq23>9LZS14L250Wza{t}u&=P``?EDB4uZ zRiL#*X`^>)Ng_+I-n63kopHEy{$IYt_`D)Fs!6)G>wlD*FthPjVF@7){;RuF2$f4| z&ds10X|HvlSZND5=+waLOnJvmE|k#QH%uNGXlj7C%)w3~n?r+Dy|7Kb&?f&p)-}rC zFyRI3?!Mk+Y3kPFxRxc-+9X-PW{{lVqs>W9!R&`;+dQtOWj`)&zxOU-!8besx5xCv z_D9py_qsQu2oeM+BnHn{0=O}bkw`YqJc!Yk#)Y4I5eVekBMA_!zbC^&rkM0poP09a zJU0%;NixyZbrha~KfV1h!&_hec>H(2xu}8n&&!WP+M(a`P= zR2fL8a^sUjT73~N1iOx*D|tExpQt>#70+s1BsR6;myHH>F1{Hybr#h=$$@}Zd^^@v ziBSsG=!tmUcRny#^kbdVpFY5OeMz#tQvvOdq`W8M3eMGFXOIm@jZ9sy-j+7MhRl&% z%3?R28`g1cHS8DM8$q0nsaL*DgZee1CS49D9rn--KjMOHy-&eV5Qz>pMswVW zG=8GSgFhpn_DJr0xtb&V>!s9E0qVF}Dg$FXn;`72xEV-zGYH2+gB&mJQ^9&O4}zaM z!U;0(MU%1UKG*%$!(i8~Fw#WyY)!p{GzU>6s8QN=egJ+JntCIs%AQeK8VH)~J|YF< zEsMh|B7_7ZY35*d=mTyS^uP?g0$KFR%@f35*Ja&IW>^e;4`9;}hyCD(A>z?j$oPfg?oGxx7JRZ- zsZuj4$vw$RF#2Rt@wXToZvKHMd26$c3SB^nvM853+`~;|oo^FHK@hH-C9FK}B)5F| zSm7U*Iei|V8$h&o))+_;n~#PqMQh(Xq6H)qGywyXzUb+#>8}+Gmi&m_Ps}}hh90Cf zejaH^LcXu);`jWk(5+)G|MJt0(hn>w;Ye`8rkHeo=v-Hz2uSn36LjMz+LzdX+cT@TaxKQkH!9_{5g2l(f1s;y250O(5R0|FTAgN?}PL`eDFgB zw*$l|m}$RXD2*|Vk!ti5D~}m}&-gIOzHqqtd{=HGJFp&nQIHZ)i|KgO3xR_EeR=Sg} zoZS4v^cyw^F6_CriGjz}ixM66X)pP;!2{I#CTuQb;{GL9Fz{6H*5XY|mjoSlJ-aTN zLy&=CS8t(&pP))$yl^Lk4PPJ~*Vaf-A2c4)*tK7ALO0Sc+PP3Ua^_g^jndb8)Lv!H zbt`^dU(AKb-;&3bbxTr%9%X@$?MSM+zaIV3|um?&^^n(xM4{Jbm#XlGL7eYoQ*~ z`Nvm7sJp$kct5=k)e5!Qasyc%&Q=e8s|76NMHm&u%i)e@j|+?K>!}!B1irQ;5$&0h zBF6@7#Lo1bQ#uhMy3!`@t>GW8;6rOwc3K!fRC@X*g#MA+rxi8APAEg&CgsX=NZMOi zS0OWT#%P!1Ob_L>m$e!^Gjcctc-?ur)#0%RUG>U33$2Qqus=*n&uR!WX|A-B#U{Z>FoB0gNLm_|j@(6PMYX#N2l+0y0bOu53 ze!}HBj#Q9PpIL#~1l}w^Gm+dA3oRC=IkGl9!K(}#lVCXIqWmcn2(n)sXaSFCVuFS~ zpL<)CY5?J=bcH22To0B;yE+WCA`Aq-&W%y0&`uBH)NQaLW=YQqYtV-YaYHL%a?3C0 z`_=%rp1mkz@of+{C%`mLm{t2`$(tA?jq3hA-Grb7cA9ff4eXi-WkPpp<2qJ98bB(W zNo!)7csSpekC#p_Sqk!H<*PRak#k)b2j$ zk08dm5Q;xb?u;-K%tb*?DsshR_yq?-ody%k&mHCRVHZ z$LMk5_o~(zdpZwZpzcwAW8eSSmhU34ixWhWrvuQE#yxyf0LIyM;G^3SaN(pw#WuxC zKs6zbjTBSxj;h@QE6Cq77%;PSD*VW`Rihh*T~r*Y>hMbnCQgM-8h-HF$QsIcXy1q% z^;R;ey$0R=5S(RVI0nw~Zv1!ttot?45_emk;S5J_=mE)1{i__O8*HvB7^mLl#7y+E z>B6p9fFdp~BYk4BJd(x8xx_6C;%E#AVENIyRQY!i)4h6vl3f{TL^iT=qZpf2={bmr zXE)0N{76hO+8ws9qb;u-d16RO@1f5WVvTdGuu^O+w&KfKP@X)p9{4j2q8fl^rk-@a zMq2u=)V((}8P)r>>NMqH;Ahbo=bt?hvZH+OXdMYaufn;j=l91UJwk`bd%NV5pnfrUN|3;N0t`U?Zk-0*$qj9|zAXXPyuh^yhYjk+3T z-T{q%asjr}l5bwz?{w|vtxfozRmxv5p+T7M@UlAil$>kJQ3_@^|6f5tNS%q(xT*Jn z`}OOGe97G9Sx}W@X=w!A!5+N>(?ok10Qh)veRTbX$nP#&8U|%5W$gU(ar>E7V+eBp zQd;|*Dh;L`@_kvA3YoPE6d{4y6&tt#N9V4&G`5lPE0!Rh8$ExjRyMenyOd*1TU&B) z1c_1c%_r!e=Nf&)?Sk&TWxf^!;qHrpnc63=)43 z%S*;+>P|`H6bo;#?=dsJU-Z3rb`HK85wmJexuF%%!@Zf3=by6&{-x!;yKF(8bFRf2 zz$rEOFn+71XGe8qXXL;4%lF+f3YK?CO!?E?56Uzd34&KFBkFm@u5sj>VJuWnNb?WZ zSjb<3OV@oFEdJp zIFw(gR|j+o4T(I6yO1f8e|?+?b(1^F=d2L~sjG%{|HN3w%JtD@iDUd^g)oi!0eZ;H zOftGGT3esM=`SV<)1d)U$!eVPXAob}*oG(QUEiX?AN=9o7rhCj_;k z%F#gAhSlk98kXFxbf4c%e}am!OM@R)DKh0!X4LJ|#H4q3T@CNd8-jVi{!fDCRW23( z!_CAH#gEuq+?)=>9E&T}DK%F=SL8}Ep1g2qt;->1ScrJVDc`FOJeNHdjgzIS&T5`S29iLO^RxBUI4e^}U z+d*VVAp)`he9zkNTu6Eza3K2NxJI{@)(}fYejg^WBkbx!T*;k-wnh9gJXE1Z*te7C zqvJnIii`iTgV57hdqG8jwsD*7_aEPIpkIaJrlAL-abREZCoTgm@;>rdRzb4L12-qPir1@1{1GZ7<_Fg4YcRM#?NWDXv0|vOS8ZbV zfmlj&Or~Uia8WOke86FXh|iw{$*h`E+fS&3*W0`s2ZL`MN@24Qjt00J4`H|~E&SmM zObt*o{7im#)VwpFgMpd|?7y7<21P;zyj zXV=dF^V#EXPNY0+u!OXomHiSyoD+FzuRVulXL9jndi0Ge-9>I}N`Wuzs|S^!7n2&4 z%B=^{{N507Giwh!tk|*>EExh!3MiQqw4_E+ZRYR&$S#;$3D!J6?4)3b@l=R6yu4d< zz`?fud!v6SPx04`a{KGd$H|$HbNcQnGQ<|@LxP2PFZUfqJP}<`h1ZV7d$l>8T`EXi zY}-FXffauHn#f!zON)G)%(-01??vb%1kMZic~X0zoEE2nH{V-EyYTNElhkr?o|Uv0 z*h$nZx=$~G96Tn;FpEo8)cxCi3_H*orF7I6T2b%{++sIGkWV}IJ_s1Co z;T7qQ{3n>KUUvQ2*$?{&&F;bx3YPU9^ylue&?vu=A=X=NtP9taq5CWB-@#H4DK8s$ z5|R3W#k9W7$nagjgXauP64d&3vW@B$r)SZ1RGo>c%~FPRCZfDNg}*~iU`(d;7 zGKb`a*xf#baI=$*yTf!lf~cc@q72W7M}8j9`Yif#bqCfkdry;-a>bcfpj*oK&tqsY z12WR8%8q>u>qtjb~)kS%`t0sSS1$W{3mmn&FxX%cKAL{>sY~_1@aUE_zu-t@NBz}-|5@ki;Bw5(P9Bk}Md3zsY}F%5BBnd01oVl^a!^Vk zFt3jy<7r39;ecNu9UDj28~VR0d?`jZg)r#aPJ^|h=yn@O=$h@b)8qm>;Fvm4SQIQe zc}^U7PUJwR=+nMHLtOdor4?XA>JAbWGH)jO+OK7-dv*C%LGOO{3|>8euAI#P_(o(2 z=*rN+m&s9SFV8F$bx>#|z8K0mcZ^FnbpEO$4YT_vE>fNrxM@Xu5m;Wj4ua&cD9%(F zzz`zTT)WfDq)@%@k+0$%75f`~4SHqj9s4{jnicD-L^gGY+lQ2H0on07m5o#@i1&|B z*6bc$npUHVn9PShV;U9EmgG558S}YUkZxX1ELG~kup+z=qBSVH7>@i|;tM%I1I~ut!ac$K%EBEU|{+*Rnuo%xM9^RT-{3DY7j^34DTr z!XtwoylVX_O!Ps47ZA|Y;FIWv$z5vaR+Fk$V&B2PS`Y+_^4!1ogY+COb+CAX!wz~j z!77P04G*fT`EyR;(1jY~vM}~Uxnq^2rT)<>;+D~c8%5t+Ri-9(?)*72l&vJ!R7gA z#$ohZi+-zWnCyI1)J#{uobSHFfQulXV+$?oMt-F?$-Jq(j)GfwxZl^?w4dGI?eS}` zG7skxiBcgtm0j&8rsBgcJJc?m$vy<-4uGXkg4YE@K4;*h3%7q?wbIY~#dcSo;QM!( zZ5sdj@M4-gUCm-p9*)d{>)$j=nxdxokNRaN0E%YwIwVCaNznKdfx$}wE$*AvQ`ji3 zX!HdX?!nS_^>p|eg2D?Xy0wmgS>?cT-T`9MO{uQu>Ti7(gEJ+Nd1os6&eDr+cN-Gr zC9MJn(vO|n>kpI1bLadp2U{4wLqS4Iqy(iFJd&ODtB$_^~$1*D4;Su<_69+On%k|0Mo@A z?TeWX`vKp;RgeK=a3#wlF6-^KzSNtLo+kO7k6z&YD+CiH^5o2}?YaV7M=NgOh=+6) zF{qkN?gg><;)2y#&*K~S@37wI)-4i2UYNe*a$XAmE(GQ&T~maVJ~9PRWYNZH=G~bpHvd-LGP%RgpL z8;60#^?RQ+IWP`xE2&NRV4Z$MMq}NVCn$y(AXFydkK#;95QHb6QQ@>j0GEvy5Tx2RVo^;{nyP6z%(^(gwqhJc{u)edX6NvuEx91zoW z1!4m}5E186D)ePhaH3GSM0cXp@g$N}nvGspB<*8Aow%1R?i-PNT_!qPK zK>&ReP%2)B_k{kQyt=@Gc+7}ys#b~~P+2yXNORoLqQRcn50cv9Y^VKP+#T2XpH-mj z9JnZE#=XDZ?90c92^)IDuWmIlJGSdW11V#-PyJH{KFTxkWCW^1-Pv`SKhjWNgR#A- zH=3zSpKa@t5p$ks^J2O6DE&k4pP30bj)0qAq4m;_*#QMEmin+^aFKUjO0P4GL((xF zFkwR56`B_Qjxcdy5WUrp1tPd>e|Rvdp%$p->B*Z<@}5pZe@<>rehiOv(~LWi(9^;u zKyg5s{%?M2kEU$gf3>5%ADS>{;!rjW()T3CD-i1-*2-+~yN&!-<{KKs5wV2K!K6Pu zqKGZ2tvYo%5IyPt2XjD-zprmT&3qgV>6`W4Uo6-)3mWVK8oYaKU#}N8w~7ahl7uEK zSZ@Q(15Fb`1&lVq$FSxUGaS{XY3nqvS_I!yNgHF9f3M#!7z9LvdKX~l z?%g8z*xM)~d%zGg!~}N!vw7n^Ivk1|!|Htj0|2jBM5IVihzHy5-Tck1W@EuPBbswS z_oxj*rkchi5`Xc4a4O8uu$WMt44`a|Mvz!U1L76@>iHz^1;=Tw7Lmy$B~Bmr3lygT(7atQK6`fN3N=%V&?E`6a?#I`B#8o% zNRlWO)F#+2K3u>$qKtY5B_-r*G|&nKS-_;He}6&?rX+ziA1?OiNT2vRkctGBwfHV? zK>(S6r20e}&wF_Zos6Ka0M}Kb&fceLQqdqjDFY=q5!#>H%obl#s5+9;@Si@%&|sQj zzaU_fZ?~p4m8;lp>`s_#+oK%-u7YQ#nY*>BzUcR`x#hlQ;W{N8JN~Qo+45j3Q?+lb+4`73`8h9laIg<-AnY6Wg!r?6nl#=N8y~~B zXKDC(ng|<#jU2PB=A!ualNDI~fCTynV~?>(yrA^L;3rG+i7Z^hVT!Lw`%}hdbAe_^z5)!c(EaAD!hJR6NVhi{9zuQtuDGFt7WOHhk+9GekEQkT9ZO`Gl|+iWuJUXna$Y}wXEmRw2B%}dy?ORy6wjmb1HeTsOb6E=dWMCdAIm@ z`)99z8z>geWB|rVB`T&xn#kD-HXS93^!h1p^5tTs(qMiM3{|A&n|ggZSJI;9PH)5L~M15Y*$yzBXYd$tfBf3sshc>C%GmWBi40pX(n!HJpw zTror3H!=a0S|;_kXl3$~4i8@7Xg>r&xH~mjw~+IqW~Gqm6s?;tEaDX)HD5?Gf9Pn+ zw!a9?5jFF3?LNWcAU@#Ic1xLN6g1zkaE}m!3G;r(o(DNCNpu zM8a-uyr=Q}Ll~-}g3zk6k|-yX4rGmgpAo?jkUO`cj}VsNf&gb{O+K1_qRrqdZU!ga z?~C=GNW`f;zxBvcYw`;9MY^8G$< znBAt>qK&sez`Ttl+y=ctifu`J=H|DjprJf0OMzaX=kIC^79^gdn}{PdH^I^?hb z2m{kCv{RSELsPA4pL;j&)Nr5ywFF1A4haJsbjY)%XO-uhe1mm=WDw7vclDuIJ6UzJ zDXPpKD$Z>3jOA^c`Y`2>Doz9xe9qDS`LBP|d`8eI*VK{FkXL!dhrk3Bjj-y?%NOJY zI@BVLL5--9ou&Kff=@a#)|F{NVt2Pas|o&fjMJ4d_~q&bZwxG;tYgC z9P>+tW zz}Fsr;3w7p;8)QgBgF;^Xzz;qtU1&bxc0OQ!e!Hg=w^~#B2s<9?H^!`Nw1FaX6||3 z6q$-dE<4Fykwpb7O}BzyrK3&eTdzZ%e@KV z;|+%p$=Yq;zSzK7eyK`U0fe#Nu)lJWR4N`!ztUQgXS7}~3K_a9GVt{y7t<@b9!_#0 z>FY$EZY!fDIbc?H`}(xobF6Kz+_!?Ar01PnxpQwR7u&mDimX`au61x02$_zPT0iNS z;GA@ZwTKkK(%pYjDIlmf;{(FDA_@x(uDJ$9c*)hs80q{?`q_`M9C$*UiX?U$v?f^YWAxw;vWTY&=eP48Y851kF`(~G-t zQNcy&yCM3>WCmkG8qJ3khC_S;a~o_t%lHs-k5a)xgm@48{ zG7Ur^<1{OvD%)L1vi37 zI#E!Jao)QSMf3VW{?fJ$?VWa#a|EuJ`dvK7wu5#O?E5Ciz^eFLxwfzN7xGAR*H}}Z z1&6qwtcK-NWQ#rf?3HNPVK8$3?tJ&f34<EgqEdSS~L~*e9q~o*n8E@q9TYC_+T{UI~@M6GCFB zN%W);h}&O@y_M*zxS<@A0D$=Y!C%eBck;u?QCjEp-MAo=iycdo46Y>VAE*YMaM3q&H6=Btr#4Lctj z*IRWuHU@V(7aJk|-OaJFEglvt6Hs^8wny+ILj=T^b)O2Zv@Leq0$m-y-+zMe!2;2K zeWqI)z8d>L$yPn*ym)P$}p9VEhxZ`!uQtu*450%;C1kkp(i{EsP;{12Z} z{cAYRaJr4^B)E~Di)sfv{P$=1RJ{zfsS5io1LWN~nHBxhL*gujhxEihazJ$d)8kD0 zkH~=AumuPs2W|lpAf~a1qEUzaXRZ;j?_ld?{CD%5I&6RDoIdD})a-GL=A*l0sHDBx z!8KJRNkWq1!5qNW{{gW`^q7~g*#SzI(HIjcf4y7LZWTEaeZODf$C($mt6VPID}=`0I*cuUbB zf32{SgLJ;9SWr=RN>FunJg6mhYEVvAN(<_(Zc6C@ryh!@pdJ4emylBjE?~-^yk zTsg)DlNCBkZ0cj2N1ot}fI9IPZfUQ@89{80_o zo!{V}q_WG9K?9s#kVus7*Le3w0D-@1aS; zn^Ou+jU5RM0@`@OCKpkBqv#ZN8nzv;a6Hf|q~#D+>-Y~VKnHu8(Exx;4n1Yye}`at z!m1rWx|XzY>7g4o$u)&u0LxWEuZiDa4Bm+j9`9TuG)R)@C>rz>;&-Li8MMt6YL_TV zSLj`;VjItVq7}Z8Pc+H}ZRZ;^pX}HN&s5l?>fHjx;|VHJ2o zV~@b8#_Iq8g2Fj}=O9r9+eY7x7$!=_|-4TXdML>&-I9_p?OP zqpW~Ou}9^Pt;!nvOf+rOm)nm&XDx;0y~A_67%AdxbvF@J!N{$5It` z6p=};;8(!ZGE{jEmcBfe0%AgSNpO;YQqj(E1G>B$P%B`2P!_mr7#J-ctIvTVixW>u zgVaGtuMpoUe6{Hpf4sm1Wcj0vqXRUs|5_p=TOkYH>x#+>widw(oB-tj+GzBS1sY)c zp)BtdrGil++RW*aEYRe7Df^-1<)OeoXL=xnC%F(>!?E`LP?nFB1Wpi9F7qLobT1bN(OJ`SZWs1EoP-*6tc}!v*n`&M@%W% zU=Rd$vH~CIU$gzjX@#)P;j_5y8AggpcL!C^xy+Ky8d04itW3Muge8Wv;Q;u}A>*?lS?cphGZuQK>>29X`oZkI81jSs`Bxiys-!K!Kc246&AV znTf|&z=LoT41SEx$2wb+*iB~wT0Toq5DhnYe=RC>?W_cX(stc%e%9D4%b?G2TLq#g z{U{8+=5fcehWRPlBdfX@sKay?8DMu{|CnLgS2??eviy;`FagIq0()v^*HD(vyIohy3Z%k9 zfBv3o*)^2DUZITHYnxpt^F`|~pH#{aF{#P?N*Up-St<*&5Ud0SrGnO{zRm^a*!>69G{+S&ri-YN&aLv+Wy_RI}YTwmxAFW{cYA*Cj*8s?j6hfC!Ke!z*dtTLPbQ%dTfC&8r$^)4hv&oJpZ&srKfK-T-e3G_7)}r0y?cKVFAmROQR18J zZ^P^D(eUPc`{BKwz5W>A?%tjLxST>^`IQ$ep{FF)2wE-i(j>TkpKTa4yFBGx|Ff{1XoCImtp+Li%#+Lp6y(&Yun0208zBz86TmH=0FS_Mh z@8>P!9IcnV<7jR5?z@-q+_wrtbKUs2d+zZL{vFTVW_fOgn|D07PM$lbB|R_VfM~EE zSM?XNLXo_;{<2C^EhB_0e>dt2U;&I;X4e;P$K9if^%diVTZ(i;#lBWu%BSjLU#%`S z5jmTPoJ~Z|CL(8b$>2i3x)DV1mjW&wV+E1p?RcS9eL1!`I6Zmyez!f7-pi6U9qyUG zVj+&uJC8=a3o8wvm3i;&oV+BbG!T=717_o8)xuvxLD&T~0@Y1YO1|p><5fTC1@FsN z@$oK5LBwhaHo!lBzK*u1za5_c?>{H6cW)OIiZk}S24cMNfLP^gfbf)CpXcyyj@#$( zJ~Q?chxa=)aaa|XakK#wmu}<%N`LT3RxM#X=driVI-AG?_s6Uq?JPat8KazV*le`Dzpc1h zn%kQdqsyk<;Z9*5tjmC*;y6z#B2r*##~1Z+=-qidT9#KorP;Y4LXm{Z!12nj8EHWg zDODKptFFvy%@s=MzQ@*lpnsHq^3=Wi_E&zG6Vf)jUiY4gGfLxDiv?mTCrLW4S9pn{ z(_3>1$Cio3nhBz0?uP!@)V=xCe?PYenG&Irz|Hq|qnf?w#_aIm?cSQx zl%gIy1MNDmEKy(sBWZLB$XZA6`=?)o4>1&18icfC2f)(5KS(3$;E+WpXY zCwprdnOOEkW!5`$H1*EZ$TE}5O#$+Dz<}XN!wtN&%R*15!R9OfBRX5;Wi1>!blEkI z()CSiMYF^GihquofMsgk-n!1#fbQGgbvSi;W;boo_r}lN+|F(0%@4o)^7h?#9&?+3 zXjUA=xT6;l!P(R5#zSai9`+@z{on> zHCzEH`3t*wm4Q)%RR=ep60ktkx9W^a}4bPt50 zn~UG==6SM&bj3AX(uuyV(g#liPbKuB^8@^h)_`^(LKwDvG!ssF(>3MLdp^3yI34N7 zrYrDl-~y~=!a-X*t4%xC+5)!;;Yw0}IDfUz)r5o&gU;6r0cSF^nF_RuE>rl!gT^?E zbDzco@nD+D^fv#&v90lAz50xws{=DP`^FT9tFhAwxb3a(;deJwuJN#gg+bsW<{d0p zB3r&Qy;m<6A(;XJ;N)lWen=9DWaG81o4JbzrzA%IU?U7`>5>ab6-0zv))Jy($A5Nc zTbH21kFtSd^7P1!*csZ7a%T#S@jl{@joyA73o*@Pm9D5xcL%wf(ytSk8oj-8t=6n- z)W)U>0qWEg3NTHhcmGcjiva!RW0^NqgsbfLDDw)H5|+uQ1uS5>yRQsacuo?YJif~N z&V@AUG}%^?>q=`a2mp)aj zjIIGVu|PSgzTIQD3}T{`jiv#Y1dEotH@ZHU>!NFeW08 z%2XvVe@v<>D2#-3@sFwf@r02y7t<%c=TBBS=qb;Wr(u7O#kCiH;)8g#tr}c-Ecm+m z$qcTiIl8!k2h}~1aI|7>_)4aB#u1I??DsjIKy5)bX45r z)r?cZP6qq)>sbtwAnCX}3`Frz`!2-10awv|&*&MCE_ zVWftQO0-2>#hHkCRrM5|UQzyeayt$@nqOx9rDV_VdiZXAhvHcf*xz6sSPmooU*pll)9uiBgOnF{YCIljF#7Fqdv5LhBtfV9vXO9pFHveKoGM ze50y%n*EW)!!)!*BNX}}0(k9#8oKbV?kSx) z>eiQdkbLVgmq%gPFu~lWp8Wf$YFba}j(Y2x+bdwW#Uj%fc$<*U2K|n)jnm>O)@g?_ z)Zo#L+j?g38$(U;Kf0U>_^;KxDE z*{-KACjbN%yNliZ?E?4Y`syuP+_aDU#m&NBe0T5n`SqhGFC)HSzL)wbTU_rJslSN* z)bj)AZ5KZ;f8jh_{p0#CcFmKQF`F##cr4(Hn*IGsgiE;+{_=EJH!Be@x9w^j_|Y;` zJxQHBYvsDAT3NM4SKLb6V9tLC6M+{Qy3b%;5-fK>69^z37A}9y4#!en=*7`^ag=&V z$js{gc$Cfay05lbb8_t!hn@(ynOW134D;_ShvX?C_$Qnr>_BDRFllb=*&p_JMMOji)9j-pwVIC0zc6{mG zc&l~fhs!EEfM(4m^=`a*Q>;~W3l0Zq9p^viNC#umPr+}6_GYAAA7w?B4xLQ{D){)GDY!Q0pCitpN7GPy=Ae4r ztmxPB)2h&dEj(GR2=oaS43pliz;aa7JKe365pKbp1WzC)mL++m6-s$GtS)5+45+hX zaH3**dNppwV}F0y9+eJwlrHmq1`6q912KaqKJBkQl(n)kwLmKk$ImH^#Q|VQ{Anje z)DPK-Xm2!sC=T|)Z%}?3Jk}UrP?>7VuER)#voN@6?uP|1?$BUMi>DeSb;YR{`fRE& zQU-*XK^fto3}`BDLVuV@M~f{wT5PFUs)AMBQA0R zB!j23Bx8Rq{6sSXpB(g@Uce$R7`y=C$>j(<^!zX$rysaShJZk}QIv>yGz^DcY<1i6 zvnlHwbn}jSN(JN34`nwEy_8u-^18f5Qw!r{`Mc+NPA85c4>U6%1?UMpm#~aBM>{9{ z@BxhY49e@i)A9t27>D0Nd2pZ;J{%cm948ub38jBNZ0o!~fYnRgS7rpiqz-6I93E{m z;Oe6TKzRc4aWRTg;;2*Es?#xR;ANcmx|EeLFG(zvP#UH(Ficd`~J9QQ~nw zoT_YU@)!qN?fPX~o5-*&@(eWa1-|}jhY7C=DEQ-4cK}I9Bj5K0<&LB2o4N-0si{t@m`<|&P*)$irgwTx6nG-C6#{78MNy0~rm8>GyWNK!=*dlSibxPD ziG3;v0CSoe<-Y}c)v{xhs?pGuN3wOYgb3Xv~WJnD`_+#H)9zigH?Karvd0xf@a zGgo{IW6zKI5b+NfI9+=PNQh!C<)C?9u%1r7hAKumF5?% zQ#W^o*=Qqmf|i2PlNoXsH&xwyJm$q8Kc*in8pXPv!`zp&(q6a}$oynnVVQ&m>c}5o zyn3YxpmIPWs<==p@NZ|`#eCljQhR?MI#0sLu63m_4M>vJ!xs%5T8Hj57azN_}pwb>rOZ~P#9>FCEZn#&1rlw!5D4bHO1Otf0cY4yu17Wqfe8O5}ICn(1@v#U~ zlwgByQ;6b=Z^Jq61BUco%d(sMKPqI0E`isMjz4dHH|(^`Bo565SRb zN9}2BGr!+nKYIU&w9OU}&IMy$nuTFq2>pUAu7?#> zN*o|6%<)pNbM^NSSeUbjv@y< zsPG574MI=M>ihP($^QKki#S>3CsNIWS%YjSnefF!k4H95+@Hx-hopM2q{&@aug|&z z-T=?*M&E?(G@pNDOq7mI83IetVTXCU{yk&TlHA~6x}8@a=Ja>jv^ zff&+c-(Gk?Jag`$XU#Tg^QJgr0C;+)yiQ`PMG9<5IC+0;;)%Y%gK?Ruyef&5p;{w> zFPMH%76~1i9@($}Lyasm3LP;1zRw^f=nBe2(_mTb%q%b^3^7#b<6H_%@a?WCx=vQq zf#gC3Db4@=J7FQ1d4_Vm!35r@K2Q~?D=pxFQ`T`j?VBDtfb*1~G-Y=B>~>60#BDWe z2YYEN1k`^WojkT?PE+?cbb%oZ8eju5!@g9J9O5^G4s{nanKANH>=v4$ub+yTfVh;* zONd?_Xw0W>9rNK0FD6nrM%Uxe&}ZRM*7g!bq2dRC35@Mf{ALpK*gzD1B1Nk z(%y@!Yw0*K*U}*NsmehmRq>lL9^6}H(1!5+QeuBwwC~LId#Pj8-CoY$0UEHgtm*DQ zSel!=jkNCxR@_f7V!sNM;X8a742e^cc!>~S1I(C6p_Gok2+XcX)BiI(3j`#1?DO&L zP;dLvWd#pFGRRtn+sHFW7JxdE=qn?cA^d-ZvhWL$?DgfFH*bG*K36ARoLZfjQ*tS9 z@~?jt(-WMzzPZugI>llU_n4o2B78!QJiL8h)5|bZZ(?26>7EHL0u@8A>1=oh#g4{F zoM2+)u&|{M#|F$cmwNf;M5B|eU(s#!P8Ke4bPh($*I+~-N>WTD9|05#EI{FtynYI$ zx9|~Y&_^R`K=^}i>H6PLU}(gXnDK-$fkHMtHJpdo5WRsQUX@1QtB9DWrAbIhUMCbbHWD*4J{{nTfiXfMv`T-~d zGB-Gv@fZ>*e_C6w+_n*ZKfhw%x(Dzo5+&+l6agGN4&2m9>YO44k|NMb++EgMX{*aQ zKKb>X8+F+uH%?lh=#wat8V)(bZ@!t`&+guR7i^B*jlVf={LNS6^NYKi&tAuB6Zl@{ zXTj#~u*ot{CE+IVGtZBpr`-Iw&2M)qi?_$7DY<1!e-+y?$OA1WESzg2phSA%(Wy9@nvJJglwWO8jxX+)1hBO<$t zDQsTxOOba*CcAN`W@)>8Uzyv#-~9;=U>Ag*jxyQg&^PD2w*}0M{Ov<)ds`p*r8&Se z%(l(Ye_w{4`+o9$Rna=|l2?6mH2n#-sP)!Et&{B!a}h;;8*FQCcfGADZte{~ZG9Wz z@xd83@9{8bizr!^%WFK^M}Fz;*|0|UHkYoGNGh81Ij>9HBG@*b+xBY5#r^G0`=CyK zZ)Ezy6~fdDQUzbpY!9c5p0n9Si5F?T*(v4ee<0>LKPjab(?FQs_+Gl9Mtj^WJKlZD zj4$tQ{&^FCIDZp>dTJBv$WtoX6z3c2^tBg6u+iA_b+&2E=5X_uPg!|!36lBF13&Vz zG=r5gFH#9_?rU^P^Z0<)Y1-KV2Ov-@{4Ua7n79M8b!k4lw(M=cL7&fFC+S=n&_M^< ze@Q*9SxS3R6uB91U|sZ;58w~l`6;*gzG(ES=FF|mRHo={Q@h#P|LPt3;6I^=x;G#C=WF`}p`nhQ z&|}r?;m)r~mWd0&FN(rkdb<9!fqTLne*l?ob*(J);=nES*KgkZZGN0J;MwZJ{MBOJ zSEegkd%-haT_{dHosIUrBh(C|blY6mEMb&vTa%a4o!9)dlbP|=nHguJ5r=NbtLl*l zA8db;uh(!v1qyD^=s+IWc}-EJVQ=G+@Z!CxJJ6EcfEVakhfCX(LxCuUy?apve^F{h z0f5UG494fCS^hbHZ+`xWCQ9Ks(vS!dt{tAcPP- z3?R6nvr$()wn$NIBi4Fs3sMspdS2Y-q=sW4LJ%3xkwaabYE!NiK z+A;3U7RG&5%d<2!giOAL*YO2Tl|p_JZB1UBxP@9hhmSRTGH{KpY1>BTk%8dZ=C-3l zhjxQu^#R^7tfmU^jr;%n;_ch-zJDfSPXe=K+a@2O*afWN=mJpO!e1K*H=0TRjccwBN0lJxHE4yMRP|*Tv z;FWg;MvOGw=+;0iAgUIHf73^79&YpgxLr2M`DO%7*tT#Bi)N^#$=oXi`dOJC&d5lAYmcX%oB4rRE8=a} z4Y=wGd!KKv<(x;DzccG_j+n=xK&pawyOvE{|gkkCX=G)iN#&0$QU=sS7kBaXr)kSz9oq zuN)peAvK8?XJb%Wfo#N86>q;K+D(gg!{ySn4A-Cy-ynj#EZas-@pBi8<@9Nm8op!$nr_h zLrdlcPr4{83>Z=;4-VtsGhh`1a-`A!0R!Fx$ufEU>7@4{f9d>uo#$(i0QWKSNAzsg zmyk)njaX|cVYsvi0W}`W5;4+bKg^HZ%YE?{m^~a%$uG#GXSE3=xkNVtagjK_auMig z5TZC(wY*G!a&Z}kA2{=mg<--|fEFh<+yh+XGW3GmvWa;t69QmSQwLPF^Gb`wk7we) zEo);-2VBA^f2d{UTlbuUCrWyB6UAFxK&L@0R1CJ7@X+0bCDOU)0*4Z{33cfCfP5~6 z_p&S`Rv$zo3SEhqeIL^FFav}MM<|Qp2t;a;buGk$ONRIXk2O(Cb)2Xu@=^$yzpfB& zDDeELCK1KyM-+MTu?|zu_mkgqBu`*?!qYUw<|c&Xe^M!lFyKMAyTJE-pwL{#LaX=8 zTc=9F+>8KlCew`2EsL!Bcs7AAVaS`L#lFy{DC|U zJ8GVF#c`E{VHg3Q?VI*-S3*`+W9os99>y-KO@c-F3Jxy{$NTR#3i76nu9Up8iJnZs)n2YSc<0jTLc_*lnt9NplfVz5qvb`{76Re{%f=0tO)4y_VBOFD64nfE!j@}d|>f1FFZ9OLIykMvBUCu`<%z94y8o;QQD zdvoDdJ)HM&%xgtp;{BPcre<;iTJk37ust3;M1(sxMdU(D5)u9i91a&pMD;cib^ zIg*35`fuhX@t9O`?Ep_%)EBH$e}Yx8zLZJldmMw5Lq0mc5Pv{}-0FCe937HJKfAI$ zRVsZ=M-lqqSC1DLys+DVtqF#FaZ%`Fi1S@N6Gnu@t`%|87?}2$S|NV_?C$D%)jmn% zsRYgIv}R{(i^yqzkrkK7hq}053TasCz0lvdPA!JVc;9()A{w}8sIKxkf38ji89IWj z>aMo(GrUzeCTEUK6bxQl$t&G%Z0x1O-DPa!{iUa)boj!*JO-I7^-$kONEv1a`E?%(6M{->T`Tc#8af7e_r`~?bLT7bPjv-yhO^lPa)DB*_)pE0T-I} z_R@5n<%Brl0wg}gaT6wPf62tH5!T^L zCLX(A=n^eO;v6|Lu_i^}2>!y$Ugv-b|0M8H;N-Giw7`!v829Y z&`|$ijJyy@eZo*-wlLHPLiB6w=7mD{LqHlitS9bytynbf4-Q)De-+T_v_)LUL&@M! zR_pP$=3gh}XU)u|-CEE}Py8%%F*qJm-3g`ioS$WES)Gl!v%oSuhg$yrfLhxMRYrp% z;4wvmIWD--OSAunDf;eOJ6HK;nG=+hYr7nPqS1HG*EHAW+pgzcS4f}{By1j+%3n6} zZv#p5p zn`&F&f+tg;@!xl%MSB}2TbWQcwS2V~z4+X47gFp`nSo>1Wc}=Hu)7uT7iE?=dS2p+|EgfbyQZ@EYz9IAq~%Pys4nX8 z0hc2fSgQy) zf2~O4{13a#AU32#uI<$O#Y2%CFyUG{8$7 zS#tbDu+eBV8($x2zP`TviF^C@Rp9Nt!299R^N&{?o`J``Sa?w^8BZc_cX(xJEKQ}S zB9?IFHQKv<_3x+FOT!-XgatwDWT;57e}IQp)=~&d6b|vRB5I+I6QvYO1b>D?_(7cU zRE-jn6N)@q97_6(FEELFes}%q^?4L~92SM4@UCyYMB>nkl7z`L@~(65gD+XM+43L= z{P%r#?7PiYgn|Ea5QtK@n_sT~IS2%4!s7u;gOsB*#nOa(TM0rFlJ$Mx6xE(2e`NG% zi$h;#T~Sx`eqVHVG}_f=sdrtm5uyKa!$V&a{UZ{xrpRtk0Yl0)>Qm|b8+z~VEblGI zsFDAE*tffDw4JS2K8SQ{EXRFQbe*ogoqZ=*If#_E6>!jjwbIW*gmb13+YoGahQ!zB zF`pWSr%WaZu$iT8mvy*Z5LzW@f63gIGGaWA+!FjuuKX%H=zMJh;Fih2Z9kKwMpHfk zAR6>wVDOJw(=t+MMTr>1!iQV_zk?D2?OC)l?O`1Gj#gCkJiB`H_N`+JgJYSw8Q2QW z_EQIBPHS)L=8$y^UeeINUJ)M-;_dmMvfh>_G2`HQTP|6sQqnT(7Ld?Ye{N6zb}`c) z^{&8OwB=~}imjP9m~UZKgaz(7h^(vffktnPaW@>cIR!o%S6b&zfv$G0P<2Js>l2>C zo^-=)%0w&yu7Zg~J`LBmU=yh#`T(gy|CluZvQ9UKo1#y%_h@iwHk%r zYJgPJoj3ZAURS$^C)MQwfAkfh6M-g0jY>3L;_pEdqgZ#BRW$RbZfbA{8KY%ZPAiRA z91SWp8yWkg4=q3Kb1G$FB$tXf$Qdp47@V31XS%E-JjxIPMH~}YLXvU-t$`bOc?w6^ z>0|pX9B1PE2&oPYICiw#zAWt`Frtl#7zayTbwo$7nCG1yYz3boibIzt_-ZU}801@yp(nd@5&9$8;v%#f)&{$2xqWT1RV z(Zp>)h0zqVggW6Ae>@FY$cOLf8boFG8|2#>flRxea*QwmCm(Z>0lSjP4CtqGlVIWK z-Y?Bf9awr5A!azqk5US9SsqSYmPdYWYY?2EFbBkGECrmz{(q{n_#F+dmz?BBNFxK; zy~tUR!#NAGI9gTPn7}0myQ_HuaUoyA#^}Wol3+8$0Fgj$zbGJPM1LE##7zbFZ#IyC zd&{&l0TI}4G!gpN35ASGQ^&gPw#TO4>9!>+p!6!I*$kq^LtC_91C`j&V3!}Vj(9LQ z7(MSO5G<47G?f)YdDiZl;>KmQ!j^ii-mw#22i}StlErN4#*f_p1?lZ9&kHnPhQTxn zO&t{}f2W&{>XC^1w}0S?Jy_q)-QQ_5A)s);iZgd>GRv#TF(^~e?8o*7( zHBd)btl-FjWGJQJNRDgQffk8%)!Nd3a0yc>wX=$8uPfbPLZsr(!4$WkoNRbY%h0#3 zB7;z71>G3VeNk1zePX<@pq#aU2ba7wQL7P8oQ!zK#@uN>F&kci&s{lU;&>1HHB^HS z$m8k6)-Z9%9)D;6z^G~79H9s%XO2Y6HUlQE*WF#68{2}}HQSrBb*BOhXWyM$6&jKR zE3*6nOjhjLnGAZtRCdzm{fLRBw|{erd&?u1%6N{Nh^eIj%!G_$*2NIgh2r)b6ol@^ zCcX_fAOO-3+J%x+e84gbUp^MQA~h^vlN8d zo*5tlL)-7}Xk^d!Z)*-SL8(3LDPGsGY6cExt3`rR=BE33SM1i zj%>4T+`!xoXcIXU2JKoPNFwlop$s>n5?8n$&wqUVcwIK+f!n6(@_}CAYLpXi))J+t zOt!<}jb*wxd-v|AD@HF@-3H@yM-?s*Zkzf*BYRhG@nfhU4Jo}O17u)n%dGNfdpVWi)B%1ntS)HZbCgFcs?AVzUqi2Biha#*>){MOo1{h(=F}48-*`9HB4K_ z7zS@Hw-@KGJ2iZBYddyR*mYDbPphY*Tjrh%$bO$}6Re@KVnHdajng_5P;TYr5ibBEKC$*5fQ(|g3M+ibrME42Hf)yqbs zX|)*A;25-??pf2)b+_i`t1f*iQu7FZ2ZWEpQW!n|uZaMI$>gj2HCd=LiPRw|`WrxDyge*eGGb6)lzMTIsIoFi>MtUYxJkW^HiZcIB7->{uc z|6y9h+(%eEJGiY1Af z$%Jt=tIceE@y`*(M8g)&VxriOe2U6a@Tmr2z_@?Vr|6!`X&eL1cpw@(cE5|DRx#r| zI$!=DZ!ccI55t)Ne4dEe?Rpl2uv*U|nBpp$-L7Vz=ARZz&H4PkuJ*ex@=KX+4b6OB ze7^mM+dW$f#dMI+7RDH^^(VnGa(v8EN*0F!d=-l$MVlTrrZ%|k_4`PSu@z?`0FenT z7leP~QxqU)EIOQa1I*rUCW%EXP_id>Gf6C9fsQ(y6u4R{$>(Bumo{dF12NCbRi2rK zfhu6>U7BrZ-l~c4NmB@I(YgDP8Z2 zHs2M9og^r&SqMFUq~Y(J%K|yZffWvcJBPfhE5!YpuTWVy(^kMaSj^k1__~l9RN9~{ zLd=a-9OCR9WOAAO;e9dO)zMSJtk`yfA;y znq>f9lJrKzQ2WvRb`gXA?CHEY6GU=5`q_#tmM1d-?fG}d?! zLNh{j$ym-e6{_#S;O|#t!qok~#^G=GO-oQ(G!;R$+0}qhx&^qIvdy!!aCmLCb*Gxb zWNluRbRd{HGh`#2WYV33IWux>B4mI5*qbtQqiRiG=O*1CEB342KH)ZjeXZxGt?(B# zeXx`SB}_|#NLvV9eOLs1{>$|n{Ji}QZ7K=p9p31oaM*b!faH%!ry+#UcrBJGO`W#Z z&0)B%Q8h@_ii}hLy8elPtlDnVa+rGnsH6>;~Y)?{57BsUh?yap>nV^im!kCbQE- zk5ajgBKRhUxqLG9BBcaLB^`fVH<~2uv)d64BKQQ~#W1Kq#+LR=HNrXMx(eYN)Oz?m zT{GwqjEqaV_NLm`nJW`U_VW73T3MSF6Y-@nEp3K?M8GEuQWTzOqOEoWyn@I!6eS-& zek1@qlK`7@5!gJf>I(e()#vevou3{%lHFt{){r?^xq76jzx7PL`Z<5UhjU&%U+iFQ z0)j0eC553o?eEUxetvU({p)WoEZqF`k$@q;YF9iU;KKPRiI0Mn4I4ICkwZh!DN~p8 z`&0w)*F1gJ*Ok&t@V-E@TP2D<;p$qjSj0nIu;I|J{JQUj@J) za1)$dd~#`d2j|pC{Vz(2w$${k2ZH+`5h|py)v5c${vMX zM|9;7BH8SyToL%#nzF&PNL!>-Qx+^$$fWAi6?=U8bIN$7XS{zvEMQoq2J_nuRh$R> z)+SvMbob;jC&pzhZQ53=ec=|nTn}JcQkft%+_=_W#PdBC4})R=su~v>Y&5e)y;a1{ zhC#1>fJ|FZb=cPy>#E+S?d8-n2rf{l7&w53Sm1*84V7UDi{pbD<}J9kEgpps!F;H9 z;Q1!NKRn!by|RBH%SN1P0tkF4E(^OyrI=z0Qjm~vNdwyB1hD`(4qhe(yakaS6MH&A zOubA@#7qY9nAo3_#N;`|P>alp0A3{2S!xRjOTM7C@GP}GM{K0F@GP}GM{K0F@GQ0Y z#EycFVk(xt-oR-En0o)2-~#F(r6!FO@SfB5%{OV=BX)nR?VE4X_7O4lGO?4|J|HHi zi5+P>g5V?ofTStK%RL&I^e>E?6D=AY4Q(9kcc{QUs{knX+dKQ#0~lYA_{Ewp&j=o} zirZb`acR^(u{stGw=)u z#Gz&|9oa&hp1+3=Prorl39n1S*js4p(Std4WLA|qq&#$35Hr1Nx=w?m;~H)DX!lLC z%`?ulYQKL&i`2)rz<|`YjV1!b8h)!w??sg`v3AWM7BiOatXgKaW!H}xP zQ;oMcnre+Uv{K{^y$Aue)(GFm^!=oX=IQK{Mbe(xxDKe4)~s%-)*bBpFOCLYsF6np zIwtP-X`Mnz+c8p=1>ScY&+|3Sq>eL?v*>?FKkYh->yGbY;Qa7@r@F&X!N(MedE(*> z&R7q`DcfF$@3yjCeOPL9YOgA(sLIA=>eIvOSPoo(1X$9_3IqXDSwlj!VI3Bc|Hd7- zrm68Q!}R2>O^8NL;X);waOuN}GGD&wdRLrVkzwJsi^XMu!8%%A#V)A;AyEh@z z2~ym-;Tr-d0y8j|5m^-}f9)H~lH<1VzF(m#AIzz&uy~Mo zY{~~a<#jm~yIjuXl;psnAPvhBsgTr;<*!cz4L*k&X?ACJXDc}o1VD77U+8W$-(3It z3tMdJS9Gyi(8Ukk^SkR;Z{A71V3ZhY*y4J<(3%(_7m6A}W9V5e{u%w07FR5Zj#o<_ zCsCd6e-7KU$;$%Ycec4LS2ez*#j0(j+hd)F?xrlap?O#3jm74_DCJw*PPt7RY-MH9 zqTgxo&6McJg*>Va63tqW2EV(Er|bq*b2YI0*l~{_A4Nq~F?-36jJH zx7MULSDZ#}L)Kx=Rpj>t&lDeNR{TxD%Fibu7|dp4BZ153d$Kv|2~bx+A9^kn=Kp z8J!0)L(tSMnb7FYZnxNKdwLat7a(_2fe1HYcHZ1#tK4^dhc^)7YF7qwU>AI2-9mtV z&@kw%5Bq&tg~iV9W^OaYZ)T_f32x{|e*hssYU^@mT}wq-TH6}vD^Sa7ixWCYadUR* z5qm-UOKjbQ&nug*!dQ*Zyx1Qa9CRYeDLC|9!HOGCPrQ7Wh`!}|*RWJlF>RAij<)QJgUEjcDiC~Pte-u=H zBk%L_P~)_IGmexzj?n_Z+*MwIxk88>bqjifIpfixwqYU~z`;Qg8~{%4+z}vFrAW7VQC?2_ykZfff-e z5a?I4Y*!@i(E53Xeu_|7z|&6#wR=CeKL;shZYCp!jX`R8667u~W@)Mj)9eya6CWgM zQ@Nfnzh~kYbuLIOJGAcde-#{ZGwT8I9krfKQSM_OUyOYVu-KPy@Yb^nQbNrOr~Tem zdAZ87*(DRAnR)>mm}-au#0(#s^_Qn2{EJo*{za<@|I$^2KcR{wt%fWaHTRF=r7%+6 z?@cJv_j@IsnLFcUeFk-e19_IBa(XByFiXkc^#J!^7BiDWd5n~Ee>%*96AfDQpyWXO zz_flwt$lf$d=Bk?dAocbBk+0lsV25UCPaae0HXoy(xDI(+KA@e+o)P#F2iW0nb{V@9^vM+fk z3{b#1kcODBB*Xyge^Y{`2ypPx=s&~r!b5^EtgN~=)6)s zy=T3Yi4n8@_7a>c0Y(juZ$fFH`rq=xCzuU&Np*J@kQW8sf8?0%F2T@{H#02CZqq8w zu2|Ig+_AwNYaqqM9bzB@9fQ7_mx6(iVRqI*!<=~!mPWTWU9|vxCVV)ESy?ihWdkV@ z=ksjw1$j0G%-3o$n3vZRM2f@i2C<|8OE!OJ2;(z%hJtEB<>WGNH>*wo*;!HglCIW=Mm#DbZ}`I-3~fjCht9@6LaoRGIjw zYKr&iOtR?#;%&2TS)rnk2)1=IB>eUehR^d6TW+^Gv4N@m>UP~McO@(y(##Z$Njw&n zoAOYs(#l_oQVcZZZg&*&nxMwF8sEk z9s63789IS~%6f@A8}sX@6kv4`sm>(+z|!{G=Sc+{PjSz1u8MSnU3a&5qYcfWVS`!i zM+{&6e+dMy6dxV(&tZxGJeDAE6Ah6Ne|&@xeR=2UClRBLEGNZB&<8|k$|!d_$D9R5 zB_G15FYt^tiJ7u0OSf59-U#pOs@zTVt3e`$LbjXI5w?qqk~W6w3f)$ZWi)3%SJny9 ze__9WjKNTk;JSbSH~ARl{47@lPp_Y~4QF8!xXMC#;d;Wvve+KGp;^=FSdct{X@wvY zg8pf!4uA*##8kY{)_@06e;terN=a~bY_PXYo%qiSeE#y& zJ8X0%hVCURcl(3aUH5hqR`sR0%)}p7ii>NM)p*Skoj>2@3I+oLm~Zm?E6_g=gc!T$ zeO)W(_v%`q>waA;=N|j(AKRK|9zmR*@6ra#_xOiaxmdn{cQKQh9Y<)gGhA=4ma%}~ckOeE4n$iE z?2+k6e*Z|WP^wOjs1JZqcm4K-k(;x|Dw~d_-jKM0#L{l@S^uQg3e`D~ZJNnJ3 zTyd8;Cb8~5^Kmb8mE6v( zV!J&@f)(IKIqKpkUHzy7ww^#ogWFQn^#uEj8Q_>qN!FfR-elh8bvURFMRuDO8@sw+ zZQp+RE$S0jaR3jE04%2df4)W2ex$<0r9u%HeS|n;JNz$G<6D;ss84)4{pAI^9;$^F z!Z~mHY%O&1d^Lt=tCMH%%9Q@FYPkz)p*6ka&XZ}P)mc|?T#x;@i>`~SMdWEtg#DC7 z5D)i51?J&|v&-Y(MMA1nvuK+aE+HOM9<)p|FO(Ig!>3ZDB}vRvf8F^|J#vh(WV}Wk z`k%+(rB92oD2$i$ZZ7bO^5nwWd3lj^$_J%WtN23clov^-9B@-#D4j+oPg=|L;5Dov zigGWV;jcnG6?FJD#LHA#yIahbk>N*xo~iX{J{@H}JJ!N6rxl5%xcA41lW+c@t%F0H zCvsxyrW7BTI_GREe{kK~q_k@NMrhP!73?d+e|g+sopqU4<&HhPK!s+w)>UkPsEcva zx`9Jr=?|9fyRnI9kw4iK??0_v2!c&#joo$dUzT-q+**I3>!}2hvesRnG_|b^Xf5*e%{Po$p(Z4(HqbB&G_}02BuD!;{lVZT^PoCw7aIUlahZA2 zhGi+iA3OUPn7J?nfG=GIfeOVlOpGRdfBoveTUO^)m*E=%6BjZzATS_rVrmLJJPI#N zWo~D5Xdp2*GMAB15h;JoSKE%;HV}Q^uMp6O%IKQmUF5zsMOvUJkT%#pb&Eo4(Y6X% zawK^-+pq78NNFWoPMk}F0*1xQ%y2m5oHKlJ`{q{`ZJH|@Z6X@|G<;v)UcLBH^N3Mm zsb$gaIV~@iTW+(Y>ql zD$7@XHZNOOKPw`sUK3I+t+Z!dmFnVySI zLO9&sXSw^lY``OS;}>R(m;__4h&BAu>&?GhrYxDEgbo*g^StIE`48@JL8WM53bA?y4Ij){00fVhoFF7p<>;J25fR z7oE5;hHx!=8&XR`nF_X!jSwTTiJv)BQ+Ik(Qh-C|0*7!zoCqVHEtoTooG2?{2&KuV zgk(y!6Vx`aF@P+gEEpC3Pz3>W!s|e3{QA)D53PR(vbIkDcB{6kpM2kgaWgr{@gL4ssA*GH5x#PGg{Wf`y$QD;POCE-pQ%M%_?_go8$1xtCm%pw!lqZ zrrUo|2jo2AkX1*8f&?zxl1ZG12FpAg|Zy)T019p@qx2W)a}6%d^mi0}KktE!3C!^M9F zLo%#YW+7R7_l78ktnJF5XRn4+`G89TD1w`Q!LIU}cMM7rrpJ!mOpzYyWWZM}_-X{& zq4(w#{W=0Jlh=szZwr zgqri0^xhSXpFlso@NVZB3_5>BUb-;9N`pY!G&wTFSSc_YiY*vOxaI~|py90u;}cYe zkpzR<D`%(FaQ%KD#th?0(gWYB4X|Q4Cmj~!)UwdbpmUb(B7L;BX zfs0X;0q7X8`#(TY^)*5CIQ`zY^_M3xfWu&hpMd|!b72?&EmH;xS8hk1TR1kANQj3~ zmTP?5_fwKE2G0mBWnvi>wBOWOz-I}tJvH#=0jtlY{6q&*=wA<}&Y+j!8v+vnGnc_D z0}}){HZdTV@fZ>)f1OoJZ<|06zWZ0~Eufao>=TI8NJ-U3Z7*r$n`1@TUMI8|DBx7- zukXMvwsCCbaj@sH`+Ykzni)>VH`k2Z*CQbJ1jyA^QcwgaN25Z|*1EYG{TVS-fG`qr z5`v_Pllf}Yxo8{$t4^WO5Wa2Sk0Diy$z++TsDMA)W zA+_Mzd;sPLtUZeHB^63!LLrzm!RAO%5r$mzNGmC#SRso0)A9FBC>RIdjUy0(a$qFj zf<~dRaa`m{fA;h*&F?W56?x5ru}U&4e5Sm|_OElr-Yo#n-0|PEd9YgDB>5t#77kw& zS#7VUwRM$6U8l3md_+@&H}g4o>&BjC_)L`+>-x+O1P{H$C1A_{oAla`5t(#=d6D}P zTv&N(^0^DBo>ytv4Dxr7)WuU)HluW57VSL}Fim5je^CmmWNhoPEUNZ8U?nUNJj~B3 zmC2IEIHO!wn3<_5M$W+d)>!u{d9upPSh=oygu$8_$DZ`uR?Lgl3ZDtGGfv@3f0 zmi#Uc=6CsWe#e5xe(1gjF2~+v)4}K;`v7oUcq%4=5-73j?T1JWu(%xl1E5yj-U?-I zm-ICP5tq?V0u%x?IF}J95h;JIS#6Kpwh{h*ze3--hh`a)BK49M1zfuhlA=NC-nY0Y zbXxAM8m+VzC7%~T|9fXRq*l`Dd~3Hj;3QJR;cz(f%*%dz_wHvAJ=hx_Jw!bE{@Le; z8v#!qi71s(l4zFYc~l;6+#JjEIMRv?Q;{*w)4+d2C5myOJ+CDb zmMMJ2#|o>3IDwUxAW(jVKzJbF#FGn$>={9xEY>j{<117Wo`1f(`Sxv+MnbVzB{I6( zM;VBtb(Cb9X$dpC=$DPU-3re6=8bvJxooQD;dU!E-;`}#o3gKN1>bzce}?AWd(lsJpXqadFf{Qi2?^ZJkNDblI}{J3N~Tgtp0Ny+z)2zyGmLUi{d>l1*m$E)zW*}HYnu7&=q~vHbmH-@ZE-^H+@mzDPVug2p6$fXVF%~Oskys zdaU|G)%a@|y82A7_gzsM``t|EoZ(6EfAJ}T*vn{rVCj|reMlCPrgc8Q~<;eJBX|*Bjzis7r`nGkXclKnqjpcv-6AX$AqtF0ZRUs+2|zO`mZtyl3>b~zQ5<1driZ~vZy^FM>WK-bn7ow z!!eVE#hqZ^rnf+;fRFeF7794kp(+pX%B8wV#8p0t~PHma<(1ubYb*Ufx356$Wc4M1LJ?)!3%O_(2c<$lo+p|JKEjaO-aQ0 z5l>K;R~||~Jr-(^4igdwORA5RW-4B&o-TM{*xus3M~oz0+xFgpOyR?{{V>4g?1Im@ z#HI>4fF`?m_qTt%@ls73Y-CFq5_llCST;Y@7VH?H1-&azUhpo+v|=STjT7Y&2Xb*X zoH>7@A0S;(+m@#84b4EJV*73&iSPsJ!I9Fih9m~#5>B-p&7Io%+_cB4r~{AVebsn1 zAORj4pYG6}!dtz&9Dl&+&5WiFN(o8P%T@tIPfdNi32V%YYt`D~y>k$E#gN6-7O(Sv zyd;M_5NiPGpqa zF}~15Wod`$z2oT)T{}D+e1!n&N|k;FuAaf)6=9c((vYO4V^&fQ7OvuLFt5+07m(25 z+YF>%b|?Ks?gXbzB+KJPD)IWzwmuH&gi?{@V&XJJfr6U^v`wgp)H*0Gfh(Z0D!HVK zGz8GA$m(#^nGZwdfj!yuEj`11E#!Y#DQdNzp)Ny*$TmOpqf~fUKEGVTVpPkadN_pY z&m|s5)9eBm_MXU|Oj+&Ev-FJe>Y0jHBixs!ZmwqIETiJh)ko8bch^wN3RA&lBq90D z!NPqJm1-uTA{LMl^K2}lUfy`w_L!Ct*ow%bm`~33S5$*p$y!|U?Aj%eD8zqb1Hh@& z>EdcpAhpeA=}pcOIWjz~LK0JIbjqK`Tf8I-l^xqN{vv%6J=-ZunaoB$z9O6}Wh(s{KzI$wj}bP@Vso^2m?d_7vECCX#F8*2X%!O97<1E5B<3T1yc%DxC~&cxGX zYT|A@z?tr=hoK#8ef|T?WjQwA;G5orH6A;W+B%?wHKac^qk9j3-N*yAU7d`D1u4+jl~zERDsy)1(sD zeY&1MT)C><3a<#LxBJK-uPFj^v0P?37$ zkk?Une42TTQFeb#x)i$LF%!85!yhpHJm8Ty{W0x5*dIuD=7|WP3a5#|UuyrmTmZ@7MUcQ1VNgW}4#!Nj$ej ze;$|>^ldf&C+<6_!1{5wahLvlGQ@)VL=%e`n?Z&>u(hbN0EuTiA_B}gnrHz**^Ol*8HTYJ+YMCs4aayr`AFHPA z7l??hZzs7d#)cAOXm;OtWb_>x({-Wn2xMJRK}e?ZP9#v=C36|>4r9p@OndTUPff9k3HV}Q!SLo3OYDJ{( z+o$doEwE{jH5QvRePAqFVj+uOigLRB`jR4LTNlewBBkhybul@b!A`vus;+;NHr~LrJxAk(oyTEFMsfqxv_*AkbPC1!&Z~M_HWq6Bznp zJZvnAn%1!n3B$OLyS7&*)X1StaKunLybg)1%tacDsr$%O#$*60YIb8?(}KNzncC76 z|8h2Hf2}M&8L(4{i?V%2%1?GOohO7vM^k$f7LK_BpHZ9clJf4-sVX}FAXbl9)gjBfOMyv7WR?Is_F z7L17YnK^w;_$rwa@DwSn!ka%MytkrE%d{0@>hb>;=JIn_#b!9_y`y_jS+RM*Y=pjH zq=@D?UB7z@KF>8B*BOMbLpweavFB#(8rFpBJEjl)al@Frr9u-7mWs*To&AUyjjKpK zf6z)=oDN{;wmOA&WSjg9rY;S^DCNr0LwAsWFA%FV1fD~8wj)P@mD=*=^OyGrU3uWA zj%1E`gU=Oj&(hXDRvcp$DTD1X{o`x2LzEGmsUmt_ zWCv$DqZaN5ob$!KWkKFwuV0=I;RIAUe_ESs5#iy=dqs1S9o9z9KktGQm;nr4?n85h zpdhwyk6a@2EqOxTv`>)&yG9xix&kRrXsmiu`OK-jdgVcpe3l1A>W$2fa)eAXd2^g* za=;l1ZnP%lD*LwUR&E)GowJ^cS6elSkUXfchr{i4hKWC*qL0=gEe_+bn z!QzUch!l-Q*;{)_`#Xis5`}|t(%&c8fe8Z8Z1?F#RE)aUm9dwAbo^4!O#$+5SS(8! zG7?ICEB>uCnx3#qXpWm_)FRZj8J2r6Fhkc>E`1TcR8-h(X(k-gb|bCsvPwNM%nMfO zC(&~wHg~MqPnwr=Xw3@VeT=-5e*z1o1 zbz_RNm?zq({aQ!EmG|$-K>b%_U)uXt+X56mNpE zVY|3(xplyfCYN)hc*Xs@z4`L7E`XgnaN)q^M<3L;KgYC!{c*^Z8dLX8Qrx;uaM)2d zm2I`@IY)iwk&`XQ1bY{X=VEn4Ln(L#Y+*T6c8{3N@OME)jw8+8Z~A(xYmAQnT}KF^ z1xgvcfT0-#fieyJ+Mo~1i+=&q=My@YakK#wmm)<1HUTh~5m^-}f7M!TZyPrf{;pp^ z;J!2;!X<|YjKL|RY*5~-7`#eJ*{rN16+Ip~su)Q*%lI{cD51?NfGkF%n9v_FD#l5S zL1hyaIhBJ!w^cb~f6|EQtP6OE%2JSltgLq!$rfME_ym)((P1opi3x+*;oIaUk-aeC zFbLcvg9jE4gG34kmKYDthhe^zsC1P$i=wS$z4SEv(1dA5i z$QGj$<_y@)>@6td0jpt~KxIKyJoZ;M*W&xe$Z#yr z;xlX^3&PS_f0pBg8w(Kx?1YSr(#;}v4q?J1OBNak1G9^^Bs?%!kQp!+lb5N`i)~@T z67ff|m!BNCjq*nZiasy|#mtyk1eAl&1O)*IO;m}T%)=^)1~6Vyu+o#EozMXG2Fi`q zVtSRbm+uf179wY8bta+-qc@X?9Xjl=2Mk5V5Q%%CjC!uBpMUukjOvW7ipFZfA{OiU{PpC~qnl`< zu-aj1LuiSt7W*AUYl4OVwrT(Iq5I)QS9i_PQT6iqGmBPe*!kMpZ6F7^nCRa@k=N#kWPeFl^2*1lto@-vS-V7`l9L7D^)%F{#aEnn-873 zV&>(?iv~Z`XU(K~iqAHSZUv_x&g=Q4dfu$s^>W&*dbiVe{i`{h)lb?F>XkuPfpiZI=C~ z%#Y_CdAP-F8OfIUY+1}FBiS;a zLoJ5QuEnH7Ee4!!EQN2dlzln?#G&jb9q^`5*Oi_3&)op49U{r<>Q8%lfzDW%J*4 zvzUI|(d;}>vv>Ww3l^M&VYF~eh+sF80 zOL>YeGM9|gCZm*lZFNdZ#4CJTUAaB7l@EHsy5I|8L zBaYnDf{oDzjxm^x?;NE@_u3d+*ylu<(VcK4ga!qs~Z)EpS!p z_2v#?0a4++Uaaf6Mi@A+r>h=7AuO!VVa|0wV!B?6ZCA_YZG(qt^KdhydOMpp58t-S z^SWF0!Q(H8A`iAbcecYkfA@8|;ynSlwUnNQ(8j#kfg!Xm0dN{Wj20Nrg<+(~z>OWY zG>3p=fPIJ1lJPpnVYD`7@Zi2iX8$EDc3_NQ!=J|(DPRqWF>LMUF(#K7l1Ggp-a=8N zU?~|(kcu3zG8|$IkhU4*p=XQJ=EE`UWJI^@2>B9n=wP%*q$ZaUe=pz$2qDhh30Fzs zafo$p(G^w0r*+zcnfB7MxTrjc*20GZ;SQrU20wgH5-l-eo5YOv{mj?mZeO~bPb zNn7?;yf{IFa-1-fe-}R@YOzj-;I4R)dWW2T4Ccj}5e1W-mYhApl^G`|6v)otJ&~(Q zC2jySBRVp;QA=NZ{Ih|C+&K1S}(_h;DA7$q@sfsIFpboNZfaQBnmfifAoHK+Pxc5aU_$1A9R$l zNpehur~?@}FU9426DRA7i?1OYZ;?M4s7(r*uuG7WPLBIxvi0tp`WpiLl*3L!Ucls( zvldt!ydY2^rrgo2B-+^l6_0W1YI3+|uL{tFmrF84VJ3Tf^+C=HS4*#DOci8O|cjVCZKqNx>erEv&E<6W0xkr4C za-gk!Ome)An8|l9ah}b(ck2^9ZO^NM#H&&ysZM~%k?gLzW?A~Www2k#rqXV7 zK#truZ9%1*Qs8LlG9ci1Qw(y{ryb!U*|2yz9BJ`HLGeNN(HcZr3 za#rxxf0ytRe^a>#ViS3|2y`MBj8f8BkR7suJP7Q1&7t~v2Nqd;99#n3M;kM80uyhhm2Ac$P4{uof1FmZ^q#WnUfLu#kkZ$`RrCpNj()|6 zlivxTi4F~*zLZ^j38bOChs*a8SVIY{p#;`)HHpjBBraEzIF`U#E~s!U^Tje>Ec2C% z8eA@Fa4hqcvwG$-AD8*K%*SQEB6lw5*j&!Bnah0Tq?38nYHLnNWN%_>3OF)0m5~n<0yZ|65rP#dmk>|_1b^H% z^4(vd$8Nw)i-)e+hak4sLG}o|&H%eWybo$Mr(1|x?C8j3u-Jd!Di*10G~*fD39v6C zl1)|>>#pLwy8iH<2gmkB7#xEz`0n2K_4SKa?_v?~kY!=UgX^0h3xg!gSg2rj2!7gp z6e8OG`}!}#84iELpg9IK`0yQqh<|4wm`Ei2WX~VUw#(~6zt792odH^6PVCU1yV~v~ z4>!MVd9=|*XPWI!MB&EV(D&STeO}SnqiAXRF^s}W*T?R3h4@~*OZXHGk2&Ka@_2rr zJwQsrvLqx*SQyG+$5||6+Ql8DbP6eAS(XKpT_3|xtf96Br04vgqqb(KMy5ySyt+{itkxQ*aj6frlJLgrhz<&pEM>?pazqXC0i~^`abw5HDFh%`f+%Vm zs0DUPW{&wgT@!2dLVUVTTuDowu1m==R~8#t6TJ!%>#W{28=K=rbPs?(?}PkdvTIH{ zu$mFZvzo|#52>E`6(BsuNM5{r8;M0%Ywr7OuJFZM>VknR`_dVhI(JlD6B*M8Zcbwo zAdi!eD&B>8tQA{fmUKn0Fy23!Anae5n?H0?>|!zfLWuZyIX~EF%iD8|;ERms+T~W^ zkUBugjy3txF!LB$b_x7+X6m%I_MSl&QE>}g^+uL12FHlGtt?@xU06*&^_4^ZRiA;e z_w$l}B(Eb=MeW|!Vu~Z%;TcytpOeD0ST)*F@>Njm2zLbrsfU~7D!9G%V-yZXvWn?n zDY4SPWUPV3(SX8tHynXq29Fk(9OLd`Pi}I!Z$4K9*EbXI9|x@PZF?Ld)^{X+9FQ(T z^MyZo%xGkE25kA29-HNs*%iz80&T#>Or#Pbdpa>WjpLW z24gCX{H^n!OhjYz4Zf+kxUpN(h~RBVax7T`*mSbEbN|D`G1>cJoTRC9VJT`YB1}S5 zj`Pt~O{n5xDyqb3cdiT&E{_GYMNGDLl_bu?B z<5KVEE#DeJ)8a|Z7e-DC(XY43yc9j;s0y_Fc>zpqpjmQnFl6#3Pf6svT%cL1Y?s=G zkZiLhx^cO?Y)clz+MSfRif%Wfg1;nqY@m~h;Cne1xN6@VM;T7?fjuj#qQO@)T5XIbwcl+EQ- z5u{=BLmrqoiPTEJrH+)BKvfm^pd-srVV9N%6I4pXnXjVRV2)jGz;#kGHaWjRLuVZr zbBV=qZldtZmQ?FSi(`m9Y+}I2K^r$!F~{7da%o5!HMg*HJL<4KDymc3ZP%^xy}n}w zr3Qx0$9wPYQ<4RVl+dRr=5zVCWmCiJs>#GGSan5UsRlafFY*~S-$Pj+x0*175qrUD z0Lvd~yB6|pe@VrytRfb)Qsr}ZcR5yjTw0hEX?(W-2~uE&4x3?4mbWi{R2xvp;S!f4 zwa3-WGMQi%&yuxjgMm+p>Q`fh=R&sW+yT>=CQX;Ct%B@f0R5Vs0gLi>Iz*N0W9W&4 zdd`ljpmNjU3M6C_qIjMs&$8H%CikH+Izc6LHI{yqmX?_L!&@g6)C^%BKkWIxl71JA zthB;<7cPL&a~*Uu@aD&16j0$O#jsO={mQW!x&elaIsTU+mV`4+x^49bs|1c2J3u#u z1JbiA*+86hjXS{brU{p+&xdntr9j-%S|M7nl@z^18wpe!Sjt}LWH8`+i5-+b-eOEd zj<>#cv2M@&I;&okm!_1LyixTzn6l0C|7@nYFLEB$GS!VDO_I~JW*F(&Lc$!kK8s!S zfiPu4DL&j?kw8f=skU=;1jUOj0vZ?|s_Y_*8{O(;5x+^$=8&Q^*V2bIu|9GU+ai53 zxl#JLkV5r?H9NKZy)x8_MPh%Tbfc`!w$+LhvIV=H7!rxqJhb$}j^}SE7DinbiLXw3 z5|2wAMzLeFaopAX$jeW}K^YbZH<8jeN@5`YbTxxriMijnJc2{tRm=lefU6(fFJe-- zf%p^IJ2YGSm|TYZ#Jo>cWnRL8x95fUTYlFc3(ndpN1q+^(=RI1&VTF|Gs~56QL=lJ4vhAGw_NKx=FTp1EMf>X^KC0()nsrRwH=Yj*B@$>vLB&pPJ7R)@Zrxe-idw z`Ul}ZCx)Mc-b@OrO|S`_H+tU1w29Kmr=|x}EU`9SWK`S7x@9WgA$W6{M1wYT(DZPX zVW02`G;GL8{87lqBjzqW`o1TDYj)J!TN4r^5LMgmI5dor{(7L{4uH3DHeubHA69#p zXgdFJ`EjG{)!}j;d!k1>lX3nn-tXMz3QDrM3U2FGD`SYu+)xbB5NBpG!Kz9u)Q6F4 zLltLSz=5y|e6Q=Mqp}Y1s5eFHO4P8vw@_NTFJAzHXWlr;Q zDgD=^)v4DsN7>umCICnJ_#)YC#oU$~8j0gd*zVwClA|;r*+4#~R(u%@(UHN)lJ>b*A!5eAjTkSmux2u9Lj=_el;U%8#G&-0?_Xp$8u2ePz!Re{&BT@UHu$ z8U1Z%rA)mcPD}E8lG~xqNfb%T%1a16hjFT_NlP@vrO-P$I-n?C6b``E&tR(AH2QTL zTm}p6&S-Xj53KKB@!7u((Zk2rJxH`IF@N=Nm(jL-6}9OqNb$^{t)!9(#>R*gr%Rq3 z6_d9%?I*p7_A;TdIKUtl_N!E9}EMG=f7pt8#;2% z>n*5VXPOg^YBxO|XoclITKsj^2?~pKuCiRvKSRhJCrO(qsO!0szOwBEqyqwHt<5Nt z`Y}WimM!n^tU+p~g?&vU$1j7Jn6O=Lj6Avog*`unX8&atO0qZeY%$eGIWS_Sn+M4r zuP}Uez5CWpKB)t3yAe!Zo@2)VTg~I(%8BsQ7fcTI+%zY3JRFIgP$fP$RjTm;R8=a8 ztog4PyN%=}-;nIOW6dmdKUXk2-zvgyQeaZ~?o90>nYgg! z!lVm{@8OPNK~*uc9db0ATWwc4AK~~Wy6JE2wy^Nuk~I~4PtqSjcU8v$;|=aA->>lR z25R_U`Iee3o)JGDc_U2T;XMV7da(5yQ{dO0?{^?P_8*07G>`pnCS;0-zC>2P$EsB* zpA*&wI1?0f?6PT71rd`nbB<6-h4lN3|p zWIy(G+hlxjM$*bS*4M0TOGhJ zHNg@1)B;N^!)+pjnCWwE7Zk!#V6R8Rjl<2Z2y9c$2-FLr(ASoL=Hn;ZXvuN5ItHbc z`i9B%Phi8v?8h#*Mq2Zq%`2ve#pYRos=Ur$HQKo|YN$hLnriCvDIZB6mOoN_<(t?@ zWf2r3ibMGFoK_AW%)*g^f7t7)!8e!s`VHe3dv}k~*(+(cbuhI3(vs3NP`kXUzl_8} ztk>gD8cQsd52f1x67_SIh9;A=HWN{tW-2khQr^3@#Tw6m3RL9ga<;ENW)|mn zzCTlBr%teWbPu~+P_HRa9+72|RtZGw%e|wC@P0#y-t#yBto(xTm&32yNOlLPR^vQ0 zNsQ%jFL&ct>E!TWH4255d`7Ibgl?kPR3GMv>mWKZ^+PM^5sXAyDQm@`LbQzMu-Npv zJsG2I`8jA72>9=~%F@^8~=IccH=W2`YT?4#%am~uA#ijB5Kn6kb^(YE-`){YOcOADp(#Z=) zNO(EO76xgWIAa87R{m+}_;1O7;?wj#BT;UzQU^=WD&<~kn99vRAQMF4cCeh?ZP|5y zV!_ZF*NYr?*irxWbDw}yK>U0g>)O&wI-`Hmyd2U4TI@k#=9#S8Xc?M&KrG1xEQTDT ze^<;7YU(x65~qVreh$S4cE93dc$@r?54f2NcwR{F+fjw>lKkE5QgF!RNEIEKkRG^p z&^?M(zlFOAF=DzB5RcwlvL>x>gH@ujs360TE>96&tX_)XzWJ*}l`fyjYGoD;%g4Yl zv=i-n_*l1c<@Tp~xR2o35=T`Xk?JF3MLyOV5F>iGd68IB!+H?8YVWv+te!Yq##>UD zvm4{Pf=7#FZkQEL)F&QFV5V|e*CB1rpovkU%_~dYhJmhTtyj}`=3Wi(65oXVa~rL2 zLA0`Bx@>gI4==1oxz2)SSeL`2X%rJA9i3)ngm-a3cK&=Hiz@nS&`SnRI%YIhp^=OL zAPX6NUWrw_%z5?*Fj9+Wn8f=2J*@g~^@WlpXMxj@;RFl5V}b|gxhEzoJQHVUBQn7JM*KrrgZEU=2{;XIc>e`b^!w!Ze$c2Vzb-B{dh+5X=-gigQylb2n zvLtEBb3u-enL?zm0aTs}cLxN_(Os<0!qp&;QzcPw(vwv8Lt_gvGI6D|i{GynP)c}z zmWDP*m|E4yz=3FS$^?y1o=eXgig*&Zs(5%LmL3S$gkivmrhRJmK?Orl z>>Eu1kF~wZZzl=;P{2;+S8EUOf%AtKUF2(4uYeU?K&G_a1PVH>5clhmRlL)5Wczmn z?w-M?{t@JR^<6-l#}qnv5%k&fjn}~GC{B7JJgtl+Vl!TShO<`?(W&BbZ!1N(mtNtH z6j?OZoV3X}@Ahe5-H!X4o*=Z+kH^(7=OwE%<#v4%nu*v+uF4X83=~>G!N?a&m%vh_ zp*J8i*&)Mrta%Jdy-O77p9sitTh(oP3h@&y1667r|4&j*hDIfbXB3C{>>&a7B?m}3gL!%Ao$%An|Yi{T&;P>S3E z6Fpqg!nt%_D!P3+0mbjYJC82%g2F4sM$nn~#)yL?roxlP{oYOdyv0u3UPKlv=8(x;f>VtFR@llu}|FX_-B1^VXkN8&qu!7CU zLuop~izMO(%NIm>>hclrxtEQ(3o1Mbqzg%bdAouAa~y?!JIe3CiIO2nfvRF^rdi`? z**eDgBM}X9`!M)@bQO*myFEmI!OQ?`Y^7AK7oeakpe*UWFsGvb`eMvsZq+#|9EC`$@C?YgmHV zG#>4A8DBSQ2DW0_@1zb5AH&GrTSOgyy}b7+2D?>#gQV_s6C4kz^{8o7 z?mb;QVo*AbLy@ud@G$?+padHRq{w4l2$>=FyQ-tvT}Vzqusnm2l5Im)S~e(Alo2Po zJ)-dYI+i#(qAR>F{r_a&$uqk_^U^|_b4&nVa~XeUhx zO&8}{qbuF6Yp%TZgHaO80;+d?bQGF^Sc?t1{UCfGi!Q!UDF}Zrsjxw+AVxdW*tA2J zhXAUb0L4yh7&#RAF9{LM*z-nNfnHEbsbmhK3^)vqEii(5bLNzARvvicm6L8K3x14# zoQtA$LvUwSr4YCVezduaF<@JkjlHI0GUqWXB{;b#;*vAo#WRebaix;gy|9n-jk z4|^LYc+6E}r%l(z{rBc!m!CDn@Q6Kw8}r86EO3>F!q#Wh#{Ub(%axKhhJpdk#=`l3 z%^)e#=3ts&l+h`9=3pYAaVfjzV37di76*I$R;Gg+p*!VGwbO2E(g){F3fAzf+rpbm()xFT?(vS2o0uF44az5LWL0y*DfHytT@3PK zK1Lyo1A&ifkGsK?1UO9?cRir7Le0u{52>D50JaclYkzqd;-ifTL(GeJa&SG3eD zIJ7IFTdu5MgT<1t+5jdP*Q9ESX_C^16AfupbCGJOQpaETF;kyC${R_@wIb4kI7wZatlf_9TWMiq?N_a%2Kz_C3ngOpY5+Typ5JW6gyBJPF z7^dhHxHOS7pbC7W_|PaW-y)s(8p$TKlyeD4i%e?9Ysi}%2dtn4Ygd2N^L5gnntrSf zUC1;-G1;B5v5YS@aZl%}4cd}IRR==$p@@U6?@P4$dlugqisM1xt{bnm^K@LJI|v(X zgAFCifh;VJ?f|yRNYO^dv6t*q2DuKVE+xr=ZRB{kvPedQB)yh3+ifu4NH@jt1rs02 zwXi(v?e0~g2AZ*?42lrgzrBoLUaj)1%vU=s8LTPSU-#=LiJr_rF3D8Ve)AT&gv>zP z&ChC5kPRbqU6ourOjj%5A<{w^62{ifZfcqcLxurgF9rI45)DLrK<&N42ou1V!WYnG zsi7qDHvYI>k){IsEq@75-?b#Fc^uWS7sU=bV@2n?Bm9A-0o#!Md%-A^h`ENfFFjh~ zHd$LUSPtk4p-GAB_Iz7VxDU+e&ErBuGrfDyW54YCV~Nz1+)!n`TxpmSN<2m38a0vI zhgyhwA_d4wXdR2T8jV+sY$T4;_*_4x;)=#uBIM5?z<_D==&KjzeG73zG3E`y>tc*V zs_E=jCc~kFocTv&&c_#*eGN4`b^3adpz5ltq#Qxad-sRUmtI&J3_U_^j|kzqHQR}a zU?nQfH3RWYr0w5XW755GJx;|FJW*c>-2%Q`9)RGrOc+$jR+prA1UxCp=Oof0P7WVs z6mAq%Fpt@4J(T@?ls#oO*#gBtoNryusFH~BzAFx%L7XbTu3n8=y6Jjwr0{S)vOuU1 z$i@Vsjj*9{?yKY*5j?fD4C_-xy*%qX*|&9|d-GmoZM2YNH8$N0EL%+T$l z8~L5*INn%f)iGVZ|A`p0TF!K}>7iKe1@!ip4F{%RhoPcip1)-|+BgKrA`#=WND|&$ zF8dJ!HrGooLQU*sH`^0_apJn47k0T@{vn(qFIvydqU8U?jJ0?wPPCjic3L~V?4ceU%14M!i z57Q*!jzV=$(^lfJcG+8ROUgO11s!Wc{=Ks^5UjjmS>tF?(#0^rJ*y3S)31}PQsG46 zumfh^?hClzeTxMh!0<8yNNa{_&Lr#lg+Y04+FQka8?+65JpS4hwY_xe_fS}^q{h>E ziwV9?=Wi&lQ>b&w!<($Mgdimn19>mo3?He4E8uNQoiWADa^bcUpzQw2Uvh6nw_~p8 z!7hgKOE7qr@S=jTW*D>Bj2Sd7@PpJ`0YrXBi?Vv6^IXhJaF2Gkdfa^1DgXSMPm5CL zr3T7iDq4{H4HoT7khrWE5o!;&B;-)?^3$NWoeU#rFd&2VmVj$%#JW)Nff^G&l#^><8eeF$UFB4yLbc$Ihfe3wzRLc4QL@jD4$SgjQ zEdir}low)_{llOx15r`W#VtSL>finPounep*UY&*U1eV;8rd`R?cEE^^P5+$^rhmQ z^YZL(duf(jgS1FpkhLGU&`mm6l>bZb=1$p3N5ueV=lZYS4P5BRIIl@!{lmWu?M&5Y zP9Qfdd6LA@_{%6%vj=7;A3@1T;gBF{K#nO@@3!t90u~g~G)x!N2Cz>G9$4$#tU0z%~*) z@wVJ@!^{rpq-S|UK+WuE%Ah7q4>P0MZvCOStE;Rc|Fo;8DZheS^Wbo-ZiG8yxA@Mc zoqoD}vgTvu%34x0c;|_U3r&g@Ju^%`9i1#;BK&m-h+UXmWXX3)+8e2#U>}GU4ajXS zC6ga5Y7>K#g;1&WFY&?Hg))#)siS$fH0#^x&%&7ZisvP5%-!yU?bR zKhih|62BWO1iLI4oVI47e#Gr31{WV?45CCm5#aJ3%wm}IHUKRgCnZ5#e0=$vZtbVC z{5p=4g*P30Wf5CI26J?RJ`*g~Eu*&!6k?QwDT5!x^1RiufZ}QzMyS^cCnBEbsYv3k ze~~JO+=`G|ZxWil|58aN2b*tyo#8Web*=T935q6thQJv_IK-f1ccTR3oaj$iEvC|K z*vzD&>IXp$WQgCW5Twj+L>b*U=UtQsmWpZrnP9xPrTYdqRA^0qHUVPS+tkp&@BPGW zQp>|JkKE|nP$Z&KR#^OAD2q`PSr9Hb?sm=EyeKUBbwrz)4SO@q%q9Jn)1eaMO~MeaYh*h78n=XU42n1aETNR-rPy00 zHjFgYBoeO1g(IulcQB2Ka4-WZR7myYF^si13~+h=jIpdov#rzKxvv-YawsLzR39=5 zT;UH^lB}lr>(o{EGTcZ>?M`7mnmTQs&eFI$B8P?W?=Ml@Zio!cZ%<6 zL6#8Djoi}=kYmw|ZHLtX%3=58;e*Se^lQiY3<^HPj{-B52*vCpgP?R> z5INHiGf3H~(Pxit()x#SOqEL07*qZ3-zlS;pRcID&3r38jxOo|n#GxP|DG3Yq2$;Q zq-RtgQL=G-{;fE(62Yep$W5J8*7CqgFoZ@gpY!m1AnQo44mL+(#1k+YuVfDYMh5O@ zqzoqOTB_--l?3YCpDxchA!tG_%?6dEnb#>3DUTES$k@wMnHHESiX30=ccgHlMP<%& z<)5*N_>wh%5c5d~gwf|hpeD1&!x3A4Va7sx?Gz`F%GMW&uvbh#yyg!35UTA2k>JRs z?tXKgGXw=&(K^5GVq*;l_u{JihO*h;KRDqhqih^j*Yx&pGfuEen>1somnR3M9X9Jz zGQlaE*uPj6i0qj>2l{>$uB_&!wQW0Ex(63tx&26)9WByiKs{%ASZ}JMa$zyc!QC?A zv3S{~NQTBvq!aj~QJ-T+gc>Ge;^bB_I_vZMO2y0d5mSb>`sgZA-D1n}Ja(Z_FL*eS zOkyiyhFh*S=P1$L9xRw8(C>auDK;p!7UxZ%w~m&1Un z?cIJ!4uPW!Fs@^oLoM|sl|W8mloc1$t{gAK^GuMZQgt{EYWTy zs~ZpXLg(Se6_h-jaFTA`MgDi)H-4Uc>O;NVcR(s zdT^5-4G{LU7HSH|{_c!ZcjH_TX!j+!%gFfPAK9;-F>+NvBJgm- z_Ox~nQq5qly`K9L2(O9k5ajp}4m5x7YVnpj0Ma2AuEu3YQo|P|V>Z!R*nedXq-KR0 zZ!PS+=3Bmhc{Vwt?fxEznqFI*->Ahm>b!9<$ypn{uC^2edb%02_G-25qrN7vS-HGw zyL`FG3>Iv6><#8ae`at$juZRYm{%(3w@z8H+6z7QkRo{mpM7QuU4p$e0TjcVf(6oka zJ0m;%6Dx)cmD4zrjqELtCT9to<@$%gRTK4pImp61z&QVtSAc{5Z%fmE{1vUJ|NIrb zzb~*O_B&!BqCh;Ys-f?ZB#kj_1AJyy@TIEATH}2b{NA6v%{${S_U)P!G#mpV3b`8g z#iu6N+4s$ju=TJU<6x`W)Xv@AGAkJs=d(3a$bVToNT97A|7_xF#Tn(>Hy#rh9mAnz z%QlooJu8jWf#+Kp1jKL@A|usVDL#vEZoH6~C=s%qUBbmBsaq-hlGs}d)v0*dYvV@4 z0?uBt%e3sN@ErVKxO2*95RmbQBA~-&QkU0N??Lhmym)ekd?&E=IwG|R{EE#4&lK= zm&8}~Bk_ae#;UGq*~F}(u_u=gx{RGRhOp2^Q72u%4pj{D`4Pvv*47&KDLX1sk$dzl z?=Mn7tkQ@9#k@B4v|Y$fX?lEQY>6KrD69v z@o@t9G(EdEf4Z=4*;tI<9S$GV0B*mD6t3L`cvL#mSZI3TE3uPdwOWy8;>zq&fCnHC!cpS7IsF*WMv;xKM?T8PINe$EOAO)WY+kiaQB-GUY~ z;t8trAsm&g95{7#cJY8wq{92F<<~NAgR=mIq392yV7V)==lTs<(Z8XZ(L@yZ*HCd> zVIN4+=iKjR>sS)!ho+I>`>RoZzSeRqMIQ2K8Ft%bE?I>;2mC$}Wf-1C3w$x&SrDy>%;vYjXEuu3!fM zeIxC-Bm?t*7ps}<@UGV}h(ZQGM2#IEbm{kkFp z_F~rXju}|FxYrMR&X^Ecq>9|alx)DPQ*|`y#J@JBIlc!$v+q>9-GQtOi=|J8JmAu1 z@L??=Jpv{eKOsmJv28MN8#>UqMpXuEqFuv`QzhD8vm=%*P1hU_f5+|hakffn)P6vEo;_Q^n4dz6kRg&g0?xVzcG`O0ft?+5*&%qMloo*V{BOlYX` zEid%&2vl2_3Z^a2Y#Y+1FVn8rpZH8=Gs7_GcJ?YVN4wpgHT6ck^I^+eApp7AeV9n58ZMx|#S9uJrQV zED*ExhNsx8ItcWGoAYse7Q%WDOST zY54cxY4_yo=&6?{t1dv`=-v3NZ1!84=UK-UCjYFW!i0ovQG*TZ^rr|7OMe`sRai2I zh>_zr7R+!>@AD{I+7Ups(pZYBYV=E#Y{O(^`?9`ZQRwnh56Mn{Fote>Q!LQ5weJAL zBeoKAsR=28^3lKb2N!uZgoCjx^g$RqoHrj$3LLnJ0K?MZWa!Nx40(drerh-|r0}ic z1X91-m70^=)eU1_(n;jZ*bTjS#fI2=(Aazvw@iq>=z60*%>keyUbezvAzCWtWa>^a zLQ)o8Roig=R@eA4?TTM3kS~ujyFlyJt~V1^*rZU3I#r>c3ZdjOvjS>908`GQ6k8jC zJiod5qK1HHtT}rHXEy9-lMT7ItU{tIqcit}cnE7q)*4Z2H7qa_yV^v48!6@}z58%- z0T*+7cX~fMhYA$%X>&?5^(W^wJ^IzIMknj1Ac!^Ta4{dP9ojTyF=pfUP4`2U7#ZzV z>q)KPfkl-f#beIc_+31W1qeaz%t#-^5=5q75hOM^Po^UOmI`VLa#Cg@wWyU_t|@tH zSM&Y7d4>8VSl!)!oP#Pnh7tYtY?#visxVM<3wcBD%Lv@aNxlC??RFVpUT@Nmru^^6 zFqVnM@_3cU+;4gIckFBFAKX+2){4)mdvZ63U>eLoX4baE3gkyzknid(dnlT~Ked&O zka<<`{-ltdp$AjEP)cKGmIGRBo)ZC-)kX&)kf6l?lzdP*>b~vwhW$k)@h>HhvOtFA z0FucN13BJUwxWne&%uVf#+HNG6l<5$i3Ac=nk{pl>Y|jD67{+SQ=|K#!qH{(+AIPo z9wmC7%)wi9GEmG03Xf@)Q$Tux&}fH^=sNUjs%v(SHO!U*N!Mj!&kd!CghcD_wsq{- z3&S|5W~6E3Z)-75s@It$>YcK0S+q5N0Av1+aRH_3T#hrb5MH}_A*0_RBmefE(3T>z zS&lSg5w*PPoFkYQ*1!CwKj7#6dvvli!s$}|qwqT~U`tn|50})gM&n+lzA1S1y}}Oq z+`1t{<98fe*|$WQHfkAl6aRM-in7u(lXCC)ZxOrj!W2@nLt=S-gi^8!4t=lN1b|hz zZR14lp0tXb&&wC(EgD(XCO@o%MhP;yC#|}Y55A{Dk|+_??d5z5+dLEl|3eX-<(_!O z?|`gGFeIM5zST8)+&2jP<{xiLE6<-+@sJ^UA;GKOPPx+okKEc^XM(^GlkIV;tT zcmhk*WZpQLl>E~hm)EU!l4lgkv3Oe<1)Ura{~lvvVyqtOj%=T2%>0$zD9MH}$t&(L z;VBR~Jkdh!!bTDhuJp}Jb=v_QB3PLy|5At9g%x|`=p%J^#1Q3jd|WYDG10~P#b6Y2 zp9O62{Ka{zZ?HfNT$&)pEfg!5jRbCkL|k-lJT!auc6_l9Kd-lMo(n{x)=$!OJqakp z1h(%(`O1U}@yC0uB$++Ocl*Oj*fd^6>=xe&E;(Ex8&=kX?R?YZ(ThFjE+#D}{1-ci z<^SHvX>RhS1QQ>)vVu8Zp4vB@YIb$#qcFFr6CN2>I7g`#eOp?yj7o-wG%6o;E%<$U zA`XjQT=S@f=lO|Ex_{;MO^I(P36z7J>FDJiUPp9Cz%hr$EKN5k$8j-{<}Qg_%}@|F zdQO0TkE5bJxl~u5R!=_#B?ycWc$$YJFER~|WOX15M%?-tTD(%}A8743Yecr4*Efs& zFBny?m7&A=<2R4>7?x>HX`$6dW(%q`#@;$u1}Vp8(Sd7v)nvMP5&b6tt0&QPpplSj zCC(5pYH`!~UhYj0+v0sLO$uu_j1OoCl8jk0jdccTjyoKsc!k|W5@n?uP=i1SC}KCY z-&QF9!p%e8_{d_uCDTTjG^5EY*6-eoi=@K1@rlzsV>2x>#tI$_eX^JxE{CR~p4Dx2 zeN#7>CyS?GoD&d-hMu(hsG(!Ae+3_oP>;wxgW>Da2xVP43-OZ6sVyk~K9T>cKh)RD zM_5~?aZ!UMDHV;@`fueRkQlZJD&xR!b$5PQ_Q%2?H;TojqcPPc6=v~cKW{0xL^p7I zj^l2RWv7a6O~%{hH*{V;8O?B~N1>ktOqp!SSVekm^}Fyi0_S|XCh_RZf5 zYHZm^1l+q<|C^~`&M5-PI0arGSY6Ufu(z;H`Wy<@~pMODes)*l?1Fyi1RcE0K zn7p4tLm$DKpA1MIffab3rl5jQpWE8q`B8BkdF>f0|iVRIOCw?34}b8 z;>2>gX7~8Pbi@RjPaBH-yDl3DVLes&7-u*r%^9FFf7g62fv&ZoK$&Sp0~_c&LM2b$s4#yKwBX0Gv(ZFmCYo^8+|l) zAi$(ACTS9+KX~|z%$PA(_p^~4$59-r8@IfxKSulpM8~T1gN~MHB4glc^h-TPD)V_{ z5cd@|4!D2Avw$*N#g0F+Ch@!vR~dSj3`=>~0}7(@Ee)9|rXBmkWm1WSQ{@Zj%RKTt zV({frtCxmLJW_+oeeyg$yD^aO+<)+Z_6I_tBJBq6yg=a)#d`cvnsCD+G(K2th`wyS z1otbIAfuV};=TYQy!h@}X`q3lO6pKo zMznLwlmqPye44Y6LO2;@Zlak4|%JI*ktDjS^w?c{I5^qQd zQn|ZNlZgtllgZpE)yH%Cb7ulsZS10bHj@MP8Fb+O^dg?+6B-$gMMx%{iXP3+(8^9< z7XQ;A|EE9lvi@hqCk8kx`+ti%$RfbFfD+t^**W*8P)*INt-Af|7F=q-Ky z4zCK&J{rgQy8Tl=M-J9`RJtAOB%f5@eZ5Jb9Oc9rt?mJ;+Kzua99B|0($l!qhxa;I*S6j5?&XLgNxj&HQsR*RlOKO7`1 zD&EP9d~`V^S`q0FngH5TI0Kl3r|kSoRgM7V>JUAo2`+O{8nUD)Y@zQG$n{T(sEpqP z8tG1{Hq1S}9cbdH#N4SHZvP1dfje7pmrxrD_-cQe4zOEP+v#)DRjt0nmq*3oDv)4- z;nC-DKJ7LI?gNF^nm`lIgTz)$%i(1ykJ$jL#JQ$L0r#ny2z09{BSkYl3*UIoLHn8X zBQC0?0Ulo{6Sz+Vxv{NON>WyKS3A}3vV{k;iBY&T3|c)Zv}j`G~gD5rk*_c_Q$H875#P05$m3O}}Z>C&dz zH4>dnwPRb1-E+!L1zhOPNT2jS{}^6%ju-Wn!i+zbGe>-cCMbLIKKy^$hi^1Hr;Vh_ zrY?OQ2|PkTbwL>!`2|2F0Y@-I;|o&oXzBY)ctDRx8*;_mPzEBdH(jL7 z-c1qVO3X;p?(gZ(EN(077f>U$w)va$10Pb7zW1c<$&*L(xi+s^fX|~-_eediDC0UU z2_<%r%l0o5?wlr!AC0`2!~3(12~Z z*~-X^up=<_N8AJf%hiUUye*S(_MZ4Gai3IU{5h+Xi({W&fIuR2$X}aJX5qEersn;b zWL5)H(;41MXjzF)Hp)o+Eoq$Ufeeq`f#ms|S6M6U=sUsvd7G^LUG1&{vPsg9BlVcH zHGnJlkHFN}<7qR5gvJi}tKx4zZjQDJ%m!b=QF-X>pwl%um?eohjI|76fmzrGhTRwc z_c|g44AEtEAP89(4*=~9T+?o~rl+0YSMq;Bb<3l7{4R7p8-rs8?Fni_TbkNwcjB$| z!P~jvDST*{!e?_{j`l|go4&?PE1bbdaz);P`Tc^dO=KK=;}z3H_$BBr;de?pND-`g z+BZA?ncXUn8IV$fQyf?Fq;6VnQlE0H_4CJZg}7i(An9tX&2sG2u6iL#egPD3q^anj zW`^EnBZ^qq=*ZQwhpNejHqUJa&E58UTiJL4(Tod}Bvham5ckQ}M2&J3w z1E+a1>q}hFCRA4;fsj%;EgR#u9EyKLBO~JO&)4rQI%pPz0uYL~^TZYUnF8gcP|5=D zC1qCFfae)4;76qHCVGvxi4fAxOOZe-b1czfdLzbqPz)bZRo;5^t}OJ+j)@u_Z(e}& zoMN-8#OjaKoBuW6_^o~dlL_)Yu6m~3qo?3YYG8|nI3qJg(J(%ipyk4Ak~c*&SY59l zcwP5Xv>$TdxXkVhsoT!8Zw+`KKz!C=A1zu53>y>>`)<5&e?6~V->107RY`?<>6>&i zJ!Pn;GOux#hOGPo=X8)z48SJflN!#3W`^i7lluW-5Vh~&bKzgfiOoHO~C<}RIt-%H@o?SK2{^l$28?a zaVAo?E;@ExL(3s@7Ec-wlzC%uhn^b86r#Al$8eoZ~mRIABwO; z9=E>wO@o!TOj|#`8dFYls-?jAZe0d)M064oFsXuT-vA`v!F3lnlb-2txPD&c5g@0a zw&ZFgW{hRbQ89$B0PR5FN-ZR8;co@8-@PGQfwT%_;dX#^q zASu@7f_yvhL^*t&f`B@3U>dYL1+)^&2Apn*gJyt!saY^QBJVQ0R{sNe?!yqnDy5y61-mM(XULU)3uAGO?^Y67o-rJY=QNphW6_vW8O7}$VDFa zv0@03a5z|Ggzzdd-B@4QwCr`e^0d7^ShMJEY*~jwb?U?eI!ZpN#Mz5Nz>q)|*+Tjn zcO{{h=l`&Ej@@B~T^fyT+l?FBHXEn0ZR?5C*tTukX>7Y;8{3$?GxKd`t^33M6V5s7 zy7q3?jA@dqDjwZ#J~D)gTp4J}yne+%1Yu`7O@opuQmS#_3>b6^$c8GCVL?cNFk?wG zU7Gv8n%KzKh>%4iSNVXR`OpY8wCVx9D%BIeOz=uY9Zjf~!Ie3`ikmbNOC#TvHLp%% zg!UFulI&*C+HXwLN(5LhQ+}fjLdi^=VVU(%3t{rOG*Dmj$VHy6rM#pzZIp*^6B&l+ z6Nlj)dav?aYZ7N?4cIBjC~fZ7epUz`E{u#;iGk~Jz;gMw3Oq1f zmW(p?(bcq~<=Uy)UHr5^_8);^zVTHiCYB4XyO5VO<*C=d9a%uupP55zd1(N-I?~GU zZ9lr5j)5k}hn|pYkc}?#Rb?T?51DS)Y@W^U&i0oyheRzlsb=ra$8`)BTS1v z8jOtTZoa75j5dxfM`bc><+A!s>;rM5sRb@YJL9cy7_|+xS?^jQZhpM3KzFc+GG^Q$*S5(##RM1@ldN;tIQ7Smp##gFgICorq-lvb! zq^7DK)|Dyk@Wg|D!h4l)h^2eQOQ7iHCr6ZNY&hY%_@&c~i~*Q((fSP`BhGcUwh|ex zcz5opm2OPq~GeOw}h!3gk-dd0# zJ(+V;IoN4Z0vf$vk51+)p9af|V&Z8+z;r^o0|``ys)>@|H?+n!gXEJ70ys-2fAQrQ zWUNgMRasvgblCOM}`h0oD_5L!G=HwOw+% zRiHVseT{~R7Khj6Z_0G;JlL8^lZ#Y2|g5#T#E%% zRd(CmP+g#Zr(?Qrpe(q&T|T4FllrxQQX(JZ0rW6L9>EP8{R08L@R+?G%%@jxF_V(* z@Fb}Lk|J70us^f}!X=zE;is+@X>S=rJ#gs`rE3Kl&f3}xjegM8F~l8=`0m-^vh;GE zsKyO<0|C1=ywI8S8o-L&A-Jm!lxsIK=m_I!LtyE*Af0VL+yf-CBHg(3^34{PZ`k<$ zB}KP%Oj%_{G9|P@P-^K>rK)`#d&>9r$oP}S-pLJ`nrX0}GWgzjB@#uSOquDgKueoe zDB-ikk~TeONxMu5w124Xk)J-N|H3kXk9e>6l~#KoQ|4YDaDfBUK49(q(JTO7{nMz&WdhkY}9!H2>YpwbwSHLtMkrZx8?xtpjJ5|h`#O0?+&ZS9;gCFI1p zV=6S~+d>sR@qna=dAxL^&AaqbjAYHWI&x;&WE=n2zb()oM~dc_a@12orOKW5+1vj4 zo&8Z!1@E<*{=6x*p zJc`3ze{>VSu*eJuKMD{Y6@#SBIHWu0Q4aU{F$YDDZ}L{j$T(s{6X-y!R+$tpM(MEG z_?V3hlZA}P@y~=CqsXdhQQ?Ms@2Ch;w~S$t8U$>!LoO5o#trm!c~}=ebm6BkjG&XY z$Q^9yw=Qg>Wc7UYL9;eiKyY_4TdR#sU@Xt}?kKE~q>7&l$AoN*M6_x~J9jY-H&Qqp zkHaMETOdK?`rU9C{_}9vV6*?;ho7#X$lhYcA=T$^(|;S3(q`PN5ZkCc7iNZ6(}bhH zyw;6y9=(+a=SU@yCg^`%lU|T`S1D2f9DnE);)KaZdV`uC%?K5~gy}fNM!eAqHCzwj zLr4iKy9orhOlx7mOJ*DC9k3(4^qam>!w-8B-Wsaq#Z3eq-pw=6owydNH|YIadWtlz zrQZ5=az#owdmk}VEeC=?x|H)tjV)iHoXJczdSSw+NA}amW=8YBlm0fIJGH5*t&EFp zE7Ur9x@)y@ann`-prWj2&S*~kKsrTel-krAVh9CCQ6OYT|3Oa~1ZFbqPBeT+B%qb8 z5b3U8yIJ}Iq<&=Rxy_$XwRZgdz5)}`YMDg!?f_Zye8SUOE9Mu@V#CD^D0J}8%&XOV zYW&X&jtP01L8${UIfU^Q)N;=@d4uk9#Klf)Jo$0!vX)p4Wuq(Dv{#ml5mB#S9@CyfF7&E+Rc*icBVCEZ%Sv@WX)up=?1!lA)u>(B81VNbS3(D^%j9$8A4 zImrAruM)~km7DLEC_Cm6wL1PQpUA%e4wL_9nq~WMJTy2fE9?JA*p{?q6ZczCdoF8t zzh}_Gk0i#*uc^hH%b&Fo{LVROI0gSE%<3ZLDEA{LyXaJ=O4H9OwbS$orok`ZO$+SIpi)Bacb8(%`hwsp{Xz}<2H2St^jH!NNW*3%m4*llg&Q-19+MP?MBgw+fy{m~u`R$mJ#FI}P9 zU=~QNwOX9pS~s@w$Mg;cca-8@to8ff!wqBf;`0=!BEb#2`#~i;E2?sRrB+kl#rKIc z5;)->N1Pi?wm|iSs0(8!)9ML)H)HI5-71w=Sroc-$WH0jWubSQni=}xCXG6%D}!_@F6+pq2V!dH6ibIuwk7m z+BGEt)E98jv~0|c*c2v9I)W|>)`yLFB{{pEuYNt{{y{S}Na6!SzdJv|F6V4h;WE10 z|JlbxlK$~(HmE-H{w1`0X+xOUtvlP&aToi|m{8Tfd&%uwRLj+GX&cGYb5KcVJMae? zSFgPdjOiwWOPp!LIFlVrZlOcJd9C9{p9MUtm5GWS`+1zi<%s5 z=;m&dQ92{!$6SGSBiVn{10t3^XgGO?1U=(dwZb5UV0*`vRJ8Ay<3fDjXP{v%;bJF2 zAvF){MePIHA0LESdLl}Bi-ABlRbryhuW$PD2}m8$#7*Dor%yt|Jm`9^p6sLzs|hbA zIp-?w?c_rT^)9PjPJ->5uPoPNWYQKyoH<39a+8-I^hRQIE^JiLoF4zE>YyCFxy4OE zd$9@4o_}Jc;h@6Bf4^P!=tyfa+fIw#;d*1LzzTcpAc)BhWg=y1URT@5C#V?A);;Ml z1S(5-R1rsf4X0tvvMB%cVf}F^A;KI$x6hs z?j72C?`SSKMesU0TCyTY?8u&z8A^2_3SUG@4WjYO{rZC1LuRg}MMuj5W?Oo?tF0^ekC zkHOwa7D(BxlbM))m_JX)@HrauB z00nCw!ZM1^kMH;IGz3KF)QJ3$l+0_8xsbg!uI;PXSc6eAGh$2-q# zc*zYSMY=}zn90V@wg{L%WsYR-3E#_^O~f4Z@gFyrOPrzhQXCdjB|S$yozRl5zK+Ak zx%U7RUBo2}PF+OkF70QR%Th)c&}NnwBIU~93bD|#WIArq>Zc>41pvm+4rFva0Jd#! z1EFot{88X}7v99qn!@axCguTNP{-~RyQo3ojXpIDzRqElBm^TX_>fMwTiG&^0TQtU z5@pi4kxjGy(7I<+uG*eEA;Cl|CutI|acK=S=nXp9AaAf>g?RKCs-K>F6N-BXJ@`lYd(SYLpyy62>ljtS4m|Jg=x#i4qZy*M>{% zTo57{>4ymt4}z_VE#V^#jTn}c4K$eu4UVQnHP2N(a~e@Dh~;M8W?HLft4O_~-Sq<( z$TV2UCI4L(4=ye|8ZM;l)JWP@wQi!hv_wRdb|f@Rr1m!&7~rMo8sqCE5l;_YnX_y( z9%~yFk(sd5?mPUiXKnS)vJGSZ3cGf-y0rj0ZkEsb@-@Z9#@}S_pgjghRNZ4 zr-Z%a@un7@1)anQ{f;ZHZe}tz#7-L}yL+!NrFiqk3fTQgf-~n3JyoMc$Ku3sbu7JN zlBovwdYG)~7-0CdDNA~Q(!jYso;xxe8!x?}t)i2Q{OE*dWo*)LiR_Ct+M2?~i5Xcm zTmhA2A7M;zRtZ@1o_#mUN1x61pvq=Sxc2GKTC>{c5P|Ft9)QL$vB5ZQDJf#NIXfTa zQfoaA%7p8feHSQ~tM(xg~c`eIt49tM91KgSK&LYZ`nc^px^?u>8%+y4w zuQe)*_8ZqRVx?&Hya*#xI%?gJZYl@MKMVeq%IWjwwiorqvqdu|b~p(zoRO{?msnAQ z4<8t+jOyHmP)Ikzk$7pDb2BklaV%xN20sGXLNefUe{}QGQxjOT*L{Xb%&`)D+5@I; z0!=LI0cxtt`{lrZtyN4x$O5nUS>FLYz*X2WI^%2Y8ahHKQ%VX2Taj~_p9(ysYL9Y{h`iO>Vy5QwREXkjFh z%z7oru&wfS3_KGZ0v_+ws}qFg8`QOa-Es|E)*X5YaKY3Z7jP2NGWG&PJug1efKALTJjWs-6Vo#T-Qj9?*JqH19dx6N`)j z`|cG8eMc_EDy_Si);Tf`A_$t$wi)^3bvfh32nI$;ppy^A3!`$lsWSXMic1KcBWToR zfJ*(I+!AIBN-(Vb{&}jrM;=?wcQ}j{_n&RoA0Dd`45Kmf`-S~CDGOhgCa`=b-C;7-!xsYq&jS!q3h%et77+S#;cv_m;tOGGFbB^IziRVxT)PR}Fd4Ep1NZ z;@WZzkL;dh`MYpl^KMeG&HM~6G+5_>cIz9X`8J|b055ZJjO|0~jH zQqePP%EO+IcuL;1H#|AD0i;+n%fy3S=MwdbL}C&^!cU$PZBTXQc0xT>*VyF@95>r* zM&h?X(cHCpw1R-S%Lz{*x&~f00Me7@^h} zom$Jetd72bBbsX`YD6ylF#TV6#vR-#hvIcEk7*q1Fk~DS2R3Vhyo6b%kLKYT;uQb6 zLD*z%JhdKeOSeAzK9%6_*nN+<&ut2<}jIS5> zlCR65dS#N2vO!k?cIwywh7}7U|sbDN+ER*1{6o)m2H+ANtC6fjX-B$Q>6CX+phJ zv9K~i@<6t=91XiX*E2CNMSX&rvyY`-Zz7?CadZ4Pbq$=AiRpik5pf4!T;TmL?%HGR ztTJL$yN`?sIJZe-ItemDL(uku0+Lmx9Xy>Zk#tVZ8p$WW8pSuQhRy4{!A{Vl+3yhr z5o*J=IXCXDm!D$=uSXFQkEqcfPA=~s4=0_iu(3GbLh-P+YRE+kldK9bW9>BNX0D;9 zm+pJ*J~_H%qavv1;_(+B=KznrcW$~5AMg9?2vBak`ca$#70^z&1S$0Itr}eR5QcrI zvcHt*D{Py3UaqscB@>Fn5}3zfp$#SX-rqASSN%NO%-Cv9FlFE_zo8lnp>>nNbx!ypNR0xupj0~`bo;#3@Q)@LSLuPlp_@i>i%kFn zem&}U4=^!9?6}ypyLoEa`J_JmSQb%DBRz1_@FTI)V}Ch5Y*QH&b`)Rcq%qjc*a5kY zKNACTIgpL2s8&%y=_tU@Q9djNjThrF{){;I~2ekCvA69)`ijNqzO_ z0X$8&n5(#mZ$w-hbyAr&cgcn$%%8%l=e@bYZVN} z@&zGv3_k|OpG>qoLP{CNv7W!Ae0$p~1DV7i6z`;;QTH@Y|QB*fMASqXQ*tsU(5 z+!B*Nq&w^VcIU0d4%RJ487sStR5${o)u%b3r+RL!UGRVa#L~q44HotmGO~jxZ@fk-SYnVH+Q~WYw&-+Y=Ql;`T{}r;(_YRo z!O3$r7W4~6`#!kMCi8S%XTIZZ)B-uutS`GC%w%B$(SYspBq=f*WDWjF zUHtg=JsGjctdP|=k|Wnr4}=9slu#4z_&Blh&tgF2%uc9hQrc)hn*}NR4-Xtb15G6j zyCj+;9`)4_X(D<-|57$y!nf)uV-(pJkBOm0^tmIKijlniL1APqqC9gcDgp_;!$k-X zLg^}B28Z+wj4w=0_UE*G!ARyqdv5MCAd)^qF3M*l38xsyEx=t9Q01q&L^QnhRddr4 z<^ddK(prK|IdMoVx`bf>Ep9>mtqqj6%eY|TwTFJUg=$5fH$;i#P(Hj2Y`9hPUHBpj znmo248D8^y0)qT_V^Sa3S{Sp!n`4s+4h@HYWjOucFWKbDQU9Y| z#^dXeJqiNB9<3U)=L7;9!ECx${dmUn{SFO*g8{fnx1zV)ak5WH=_zgIHnOpMEzcH* zF=fr?5$MrPNIfj$z1)@MkSWnta3B_C#&11y*9WOTnAGX-z#S!X?$tz-{YMTD0wT`8 zMk;$h=WCY(qaY>Q-A(gvzS$-k5Y=(Nf%6cgW-x{Uv5oN4ijZAm2>I~PlTAV?m{m{_CPnsOKX+`QgUa~^C7`bb>@QH@ zAZQizUb4u>dKO{Blrm?o;h7d2FPiG|o!|uI*Qz))(N~OwYUvj~DO1apN}tNvWZ8r* znd=X9REGKJyK*|0)-r?Rw72zeOh=UP5E46tP{=8W1ZV2I@0nF5(^YR7lACYS6iRU> z_DBs7l80fQ40n+2&cFu!08DPqW#W^1Y#KHE>%(ihUe-%SNtb&nFj;DDM~G`VsKy!A zUh~~at+~Y1kr%)h;QuY@SdO)kx={>w=hYXH6IN;OT$>q9Y@dI|Rq!&DXWH5)Xu(D5tiV5AsZV7dZDN4*jj;fflBB z1-(Ikx~VlZ6|Un*9gD08x+z}gLJg5Q7XE}V+Kw{%N`WYsA{s_#eN+f(a?rGc96Nu> zeaeBh{+$Ay7wc&(bx*^hu3S}THG#XxE%5$b9ovVdw^AFbS`B2p0QXP_suou*A-&NFz zA@>K1H4nCa`f-N9{ad5iZJFN*(bM!YNwOJ?cm-~nA9~Q?9uxU~DgJUk7!Ow`wTo#H zHz}H48T;vAk|rdGdB<sXXP5 zpZay@fX8S4uBmX%%qy5d*#y+@Ejy|Gp|y7))Yf`fzu;5Qti=A)+2FYAp?5jh`6KG$ zQ=@W!^bG12wi}Qj6-}%3#TGS!*{s&gp9dNmi>PY&8c6y+Am56J9Fxv3N%{ar@*%QJ(~nZ&fhW{&!8Z z2}U~x0nd^~+`^$B6K0(5tl+^k>HlFl9PCExuH%!wkG}ujls&9nu67gd7nLRr+!dr&V!^wy@ zVff8(A~S`f82NS9r1V1L-Cwa<{#vA=!qQHA24G1);fX0usb!m#uY=UC>HZTT^-Jfd z(clG;45yr7tYf}(=`*KBeFSH6=|SI@vKgKAH&>SYI8Q7qMwTFT9xTx;fXZXZ_Gwj7flV;oO4(d{vJ~qe!sbJIafx6dAXQW@K^uP} z9Un?h`j;3y<_v?*ZwL?d0z^aJLVjfArC1sbKam&$zenHgtP(RECU)rBk4V}d6UTu| z2&Sku5g}FK<7}uZeH|zE8S7fy39H7+ma;$SZH*{-C}>6YpqmM*d?I@$y0eyJyoXvx zr-y#$Y=}v@;){m2Rx2r)KIg!qS|+)j!gXYL6!mib*>Md1J1VYG)$ys6;VbE^_1(U) zIupr)qd%{iSu(MjTiAjkxEsb3(^riz>&79ge(#zF8QO$@;7fwM$=aM|5|uC+vo#E4?=qz6Nn0kH9?a63z6!z%ZLt$Yg?kRRoE=^-9=4ryyL^neo^k?MF(K}?BA?X zHaPMdHJ_%4E2n(3Yp8l&zH5q>3|s<|38*K_*=nZpbQf-jlSTBirJXb4$VYT~wnemg z3t74<`n->jbLf1QLFgo9aXT@%8F*EY>yN3Cc|Hnx)M3pR z_U+=~!I7JuG7j;dy*&_ur&cFd^yC9sr(6)FfYz2`IM+VIUmOGxg1Q@wKxYawDswSsZXCtKe|+gdq?yE0e?m*feaxj$JQY%$3;yBi8t z%*rH;Mjf@-Ti^b50ZELb@@}EQzl3rNHx*b>mYgBRF=io%nh;?#Cc{KSlJ&mVC~bG` zJah&fN%J*UEh%=_sw4|O74k!7`;5nzkG0?^&>3&u=@KO6ei(ptKhFSl%dc3D=Pdtk zC~bLZrrP?OW^p;_V;=F-?c#}&DGD-aI^VS9KNnS7TLTzDB)J%i_Z@W4f23ZMax)GI$Rr$5-^^E8$+OYY`{PkYc)0fyZ3ely%?4ibfp5P# z$uTf|{KtO}1qlMlYo5GtGmp6vG8gYubD6MQa-8N|{J|y63lk9zEVYlkz^o4Jic_PYHhOzFulP%^I zye5XZdtbYIltz$8cTXtz_4kbxU_SG3d{7@Lpu(7IN~{V4Z=m8We(8#SeEKNyqCEn2 zOaXNHR21Oo67gW>{@vg2^ygvJuAh#<`#5kU3*09eqJ|>6?%p0YtTsQN^ZdGkH?i;8 z#-2J5!P1dRaq`Hg=70MkL={UP%7`LCF(@4rQ$hh~u}yTi;5qPfbMM*@Fzc4hXy?(X~eUR-pGzjN#nw*Q_SD~|6zcCausI@|c|SXs(LkGGk=>?RThpcMNjUyV&|#=DcH4zjHQZs5X^9o+G7B&lWU(>t zCO;l~?bnId(eJj_?uT-|x*t1KClk-UsZ~vls_EoQ; zx*qI%U|}9G)+`XFY|G#@lcUOKYVuCk@u0^#?IXrQ-Zkv;lnXx`Vt7kwm)d zB=fd+t1sKPeG=NkYk@*}G0!r{G-k_zg&6)=+@3iKTr)&8A&09P(_nZ0Q1_Zfkjq)j zUEK+!?RxEyOCFCE)a`s0*vna>KZLhcMB8Ed@_n7w0J&J{zT~b7j}OT5_iqKgk}-AD ztoRQwn8>G^@O3du7|Zp;&a1AFn#bwszqd)N_Am2BuVs<1?SMR9@G=Av0UM{XW@5rV z)^ET56hM1OQ18QBsjg8$dX$jd9IkDYM)^@&&0btgpAcSc4J;lZI!T_klqstOmFm<+ zbZl;y!j8waN&N^Fw#*h6I>g^@E&j@5p;(liwPB(_9Y|-!l0Ukv!tqUS9qC@!cJ6HM zu?|wPz~NH*bOOdNP`BctkC*cxM8)2qmr;;+27eoAcA2iJWIqVOyW1I0jOKEgIP$dC z?i;X$wu3)Yg#M8d(b_m>cAf=iB9*&wp|qrTTm_)Ro7sBoM>T&F7#V~sG3FZPgPcBw zQZtkqa{M$c%PZ3jX%UzR64ZEQQp++>sfKSNY5rX6+6G)|`Cz>+$)f1#(Qb_pLWm&yZv!eVVGuv!UsdmQKM)n*Z}xU`*GX$wZb;-RlFDYZObxWch2eJ zvCTBz9aE-Ntsp~GkJl|A(ILxS{07lsfBciQuxI7T^B zJ98Hc5*C*KZR34$gyik0X}ivuvm8lg zI%Xn$eqRpEj_HUdY$at29&8RlCubc^2^c&n#a_ItG8#`Mjc^|s%8_1!YufI@+9suY z4m1GYsY{{4&|;pZQPCoyG;J2}>=W}KR9ILz_te}egbdTeY4=tOd_ptO3G^8h??L7> zb+&hS@p@ewRXU;CFMJy#+UAo=9?NXC`}^^}uou=iY%)hc7(KI-g_bc9UU>b*$zZ&) zXA`hAhj({57@=B44=Hqi&oK}tdussvBY~?E>=U1SV02YrZz*V(w3=ua`&Z;4ctK~M z{44Ysv`-$;H;`(&Vm9@!tDDan>tY~UQ9rls+Vj@(kDa;m$Hs3cK{-ELiGAbMtx2qv z)hw&r*b)1T(+4xZH63@Ux$YP9TRR@lB|j%@jy5egHqS^yN@pMV%)K9%hc?Rvl|UpC z+!R*Ofa%XvTSQ-3-w9tj-%8(3opfGG_xIQlbIxA+j^o^t#?P3M+V$s7v+Z=O?U+yI z4@Vy#;jJL~BeY7PWS?;udNjo}D)d*I`oXy{gyz((AKmj$VVk3j<;?BN-$ zaa+!k$DZ=+Ow-9ui+*LbKUCdv>ets$_*QR(yCB>plg9549I6)dHxkU30-C6X(ssTP zi5|Wr2R)^V%xcKAZl@|y5W+McT0XRxxp4;?3~DH86#A#iDZ3}yfuadxsGcZ<+p@v; zeq@t41k~(O*xWl*bw!e{!Xaoa#5yKQxfuf&0va7~zeY`upJWb9@ljXjsh-lQ>IQ{7 za4&+3daZq!ob07v{~Z`*10puF0b!QEDHomwsB)w*P7=zh&>_js6e-|brCq9SG+XNJ zH7=cZQhKUiDWLdm0!3a6^c`4P!5D6Y6CJDdWIG@gY%&;~95%&F_p6UOr-th|e(kV`Wkv)W#nz*e81DM+UUt-~W;M7u* z6<}T2Pek3ezG|}mt%glClPa^+hmxH zT5HLBY+NC~gFuW-Of1AfSW?rt}`0xOR5* zxKm0H$OoQqxX0}Ws|neGcKcXkU(q_q!hRQLWS$@u=@H6k{#|i$@#t=HP{>5r9$Iv} zNaowyKbJK)6IKc8ZGwf_}(8p=5dIU${ zDBBAy%KL2DxKPgZkxlB)-yfd@MQ`JN`()Mc_{_7Wl>DWVfXjn|8py*#5OJYL(b@=!2U4ArHq} zDT<%Ew8d{I@=23HQC0%JVhfYG{j>@KeHlM1mD zm&H;*w!AT8XD^8mL?{Sbav=3AxC5AS-4`5$Qw`Urmnay6i9_*j;+?8cLaLYmCO1V{ z@(a}1pti^y&)80c15b@r>u{N@27ytWmKy~*f&t9;6>x6Vay4Vw1BJ{|tt1duK05B= zWlltkRHWnLp=&a3Th6UFK1esWB$c>Qk;_lhDl`f``n`u#EB583Uk8i-JkMHaJu7oE z$a}nsQvZ-}(Ce@+H03sHkAuF`wr(vQMXHr3f@cC~J*ghefDQ241W@I}*8vJg@g{J6 zY~chl2eh{_XSuCEVSElaTv|=UAIoa;xyMtl3lCmap}Lnd)WHHjv!g>AdL78=<(jNd z{0kHgtZjJG_1N8oX)epoK0pFqnY8}z=)?WR9tgMq#QJ(9b7V zGwmOWMDBcuvoWG7Ur*YXQ|RP&ppe-MC2OWQyjG?CGP1D=pD({*Sgyz^d4xL>^XyDrP-3m}Ug9s; z_*9~#cw=F-k%b~Z@LdHy@w=fD{CaXzSw?e2p`vxZVJ&S&!0si{-`kdxmeh{Ff6sN? zN+*;M)HY^E6zgLmb7BxABX8Q4=LT!6kxdt3Q)jCop5HShfrKUjm-9meizhnho0*MX ze>M&smTITHHh?R8Jl}g2qjQfhDJ3~p@a-MBsYCyk%ZjlXcy};|wY&^1up($PE?+&b zIJ$zm1hu4cwq&dk_w-9^tlH<2`5Qk+UMh)K@KV0N&m9@{3l-Fejr7%;mqddFlp7no zztjh*7DCn&={LfgLzP$HPIIv?`?*l0QSXsf6Ju+TsHNkI=^S$AM=HF9PDwoPYISnV zdj1x|Rz^@hz~*bKNo)1;p+XQzIuxXYJ8`p!8p4y}=>k->Nb+!_u4$q%@LQM*FVE&| zbnx@x(AbMjYYm|5uiCcK@$!_5FJ4ry6-wevBuqm}h+-;hTujv1v^?BzK43bTo~K8t z%k3V)!LK({|59A4*{r{p7=rn|fXbkuA{&Vb=@of8nl@8czS+`a+tp-9mL83o@*@2?J+t3fS-&VM@Q$Uws=AMyp1F$ir z$>Eg(pu9Dq^tc=$7@O3inrYk*>z?a$mqGs$=yPaY<}q5f`GGFO$!Fdk7kvKk7sX~{ z0oNvOPamNKl-BuAW!>D&DzwD7V%gigFdn17nltxS@)ib8CFMbh$Pm5SyrX{Vlp)uA zzN`vlw^VUdtUz#mg6E#=jNtb6n^E(KM!BXXklrX(T6z9&Kz9k=;OAGW z3j7=ECIR(S!;ob+?>(MNvjPmZt2o|0 zc<^Mw##{?IVG89wcwfy~tFEht_OHE|zye1k^poeIY+`PYoH~`VWg3b5%>_2$eI0gfrNrJs8(sWqZ57({)Hw{ov@W*Z{2wRjz3 z1E?yTe+u}Km&(gXgEKYYWT|0kgj=U(=X+2o8N7Z?G-a3)`gC^$!rU_iB^faDc2P%8 zC^0ZFV=9vrD|u?@%S@^<|JDg9sQVX`vNW4|zg^?)Mbr;MT{aL|p1aH4Hpmg%2aF$} zYPYxxifS2}#Dw>pf3HhTzj8RP(*Z$LMgNILX?K6<;A`3!ktBmNGvut^A{+PwqM1N zIRi}Xie_oh%fFzl_z>%?)Ozb<4gi~BB_;_%Gx_<@{jFZ?8OgM*VAZ{h8n!9E7zVN? z@^3~2oXT79HB7H2%J~}2*~}TnYJyC{cR0D=P-~WYqq?h_VhhIZ?$d5kc7mk5(FU+d0ITo2 zgx#5N!u|s~L@a`!e`qv}3Bhk(nAGDyS=rQLA7l*6>cYMcM#V_{N`QzEEOb>9wS}$8 zfUI6VH<)NAY|v=k0NO>UVsRH0gagv|$|$XyFJD_SS>m@GNsO~YGBOUq>C+;5&UQRJ zp%SoUO#Q;6C6(hK>owk=- z^=a+Zxw5G=?D-tEpL1E4t)PNL&JZrnkw6j8G`p<00As)2+N^bWTO|{XjDl+wY2{f! zKt(!NQGvQhGidU!ogJdc#^m?avQ}NlxiLq3Jk8(yG$xuBQ_YMkhrlowL0&R*W^0c+ zhlHz8%C1~-3jOs`g)@(*j6LhUU;If6NlL@3zIyh;(8L{w${nYYu7t^0-btA(S?Tl^ zq?W*p#och6zhbFs@QDQ&lhxD#Xy3`Yr+@84K9#{hcC1RqrhPrgfLbj2cWTq$lk{qr z)EOGnsxAt!V&-;xA;3?Lv3^RkmKlbJ{ZcLC*jkBt5XlmFe0J5EIR2k0Z#JT#AEbu1Z%{7A%yN$gCRvsR0ZJkR)c$zz9b$f;k)s#+e z2LehT$Tah=Xsawej-~`qN{Wwb*2!r`=AhOykmYytGhzdc?AE1$RgA6m2 zv{k-+e1X4PQiFHlr(T#7Bu&x?5 z+R~0co^3BHI(%*jckjk$t^AI5z4Cqtn(8z4a$;Uc zkAAPW1P}9g3j-^m|mtv*BCahNSv#}AgwP+Jx@{zR~d9>*?K^{|F#2oAAp zuW;^gD&R3F0{N%)n`hDcT4RTjvROkZF40UP$=Y8ZCz}y}7r`+9he;O(S*?n`XJHKk z?;2m$Vr{uUY&h;eD2;KAaLH_m-ZPmWa+N^F(J4#!)`#13?8xmF2ucwXxmf687Lz^K zen8M9TRi3GX{=OsG^R&4@ik}|N-I>U|QS_BYitS(EdggqqIRu$t8HfE9dC<|AQVmZRBX8raLQMTSF^%Q1 zg@092O6x(TwV=Y0Cwc1GU!R=&A;_oX=E*Dr1(BGNr7aXB*wjfLpS)H7Lc^p_4*o8@EPS;Gg3d@Z$eFkw>)xn@o*_mI4 z{z>+LXL{AG{I7j_Lp(6N53r)PcNl4+{b4CYi)M zM9%x~u-sxuA9?T+?7~x0H);{%?t*WjOn@+W_KBy2cT~OdDKtE3YE-nvwm_(;Z@q*6 zYOzC}wT9PN^RWQRf3fvV!GQ)**3rba%}Fw`GqG*kwkG;w+qN~aZQGb&V%ymH|J|+K zhpoER)&0;f{m^yqx#ylk;LJo@4qle0p>FAS(e{H~;r9V^Xzhg4CC$K5ly%9sc3SyH zssd}YTZ%44DY5Nuc9<~IdEfls(6T-LK(7zhee)Ip%SVVPzM+fy7Nqf=VDFpfHx1i3 z`!0aBYHdj7dQPt!E{xq!;gt)7aG7*QnLN96{9_oo*%_n$j-Rr+?hXQ@fX6GqAB3-(}z|> zF?ihB>~gEwZsZ*VR>{siW!8=m9iU=EGa8@#6{Z}LZlwDp0#_b4Dyuj5KcUg(pU8ie z<+`7Z!WTNpC@YPIEBGxL%&T9Z69T=sM=Elyz#RBp+k#)D69Ge*2Jz=1$xpe>g9ghG zKZ_hAP>2K73=N;~$-sb+o1S4vNQ+cMB5*V?My6E905CKN7N-BPqtX0lM}z9S@_UC& z(^T$oII5+&*(vqO!IXd^S(gV18AfU}Aqd_tC0V~`%NYb4Imtx(R;}VO7{q^AMt+9F z2XOp6g<|ipnLa*u5;Na+U->;f)BP-W_n&N(qfE_Va~!rH^R;vDpI$$E+PdecD+~W4a4;+NQrk!o zhd@)3Dt7D3*C3@*iA@By%^yfUPZi;^WQPeNTfGr5u%ij%7@4q-xym<~L}?hBPeeh} zi{Ikgwo+u|bEYF$S4Ga1{05N|CCF3Y$}y8Rq%+*?RSBTR>F%Pd(4AXu5%`Xs(4QRQ zzteZB0IV>kdD5wax&pb0)N`b36yuy^3ioCcGs^r3_$X_id z*u`|*l)TjqjqN~Imm3pD>sv#%)8p&4(7?Qy(P7bf^6S0pvZ`F~S?!I+B25Mfk4KL5 zb`6dM|2e0|Q?FrFbF|$(-z4&uk!6;7O*0p8PRfPnE6PHbQ?gTlPX(8eNTs27 ztVw`7A!w5owR!~}eBi;WK_22NeEd?%1QFcSef6$WK@EauuCO16tj?{i$68xiVz)6^ z2!GmPM11O+2Oa+-P*R!|K)l*@ovoug4m>GYiMGz^IoA`{yn{d?%WQt%4w%<;5}k{> z`q0(gKXU?3zCZ$bfR^$~-KWXzs)`Rhsh5L%x5ES(`rwkhH?OtEPh$vNy{`rX7ro6t zJH-_%Q~PTL4*Nsbqa30;B-`v5zD^;bvD2p$={>(5KGx2g3gdz##Zj^|uJIot0V1O= zw+I}hz`y6~<(9m1GYd$9##~}4S!hF~NnGkMIM>x?eh=v#pfU4MzX^qIE?(9)YRTCf zFgNL$7IsLn1%|BLLuO>fI1}@bV4jT|+S6>OKVRb7&{lr1Jtd(bCag>%j|XTzw6y2s%+(VMcy@7O}wFxkPV zf*|gQ)`@>ht%nDh;78QiQTjmMDw7{dLlJR$aKXmA^`u&4ZAJXK%8#}Q0eDkTz&X5a zR>)YwTBi_fqI)#GTJAtT%BP(#>^|zY(eq(A!JoGy$HsEGM(px9LixuuJ>EE!5(V)T z!%Tpt;XLCwiz2FN}V_H2l85rI{fVhv7W8RYuRQVlk z)M_hJU)#{z-W%C9J=t)-{D3AJx585{E$0HtER)Sf zgqqE%J!3eJeQ@ec?yvq}xNBZy6G`%D29V#EpVrNv|x5Oj(0+_#>6Z+EXO)@0?( z&|#Y95Q0RE4n)1sfRZVZDuE<|TEMuxqIehEi$yYoK>VX`a*?OELidI66g$I{u1?1J zXV-d!J|bo!*1N6bTEH5<&W zl!frWrc0PJrKb?c129YepQ@?L{xHkGGT+KM9)v2|q%V5!c$s0d!p;YUYRR3>VBmCS z*~5gW`(LQXfa9Rplk+skTL5Y2%nfSeKr|A!ZyN$CZE7OAC&UCT6MT>XRP65zQqx~_ z?3;8tk2R08sY9%mLZ;7~=r7oi?@znw!W=qJs%Q3pppk#~_|%2t{FY!V8di;+|0lv? zqsv-sPUnG&HKh7k15sCy`9Md2nG%0RrYX_iX74`K4n%?Xw&9W=l*FJNg5F)JEKfht6F@K^z zs!&U(VGx>8&}0cAwgOOCIhVfEn7KYct3 zr=&gis>RQAR}l%v{=(GzR#Ke|iX?s?x)@M8wZFW11m@9y2#934neVoooFX2GHzBbE zxY)1yW>%c`reD#UlpSkuRUA{p^n-cL2v?s}13Z!8X7Q8AFuTzp^a+-!wVofe+10xg z)Ih30r(;n^dLA-V{^QoPFNEmdMR6_YGe~eYA!E%~VOqm-@^-1TxhIJv!;k1c>WrCH zVKL2dCTXlB>qRUv;~$Lqr|M(!jl>pd$fK-8_omcGtG^U5?UCvR*VI18-@iq5Ft7#A z1F5JpT-Yo=?Y*i4il9?iY*?L~6=uaGgAxyT*CmkMr=g?vNwj$CNnhw(R*|^x)#WjM z@imC~jv49L!MuKKOFZDQ9<#&C6p3!DYJqgRD-;$t51gx*2Ixsc4%)2+XGaf+t^LFf zJA@WS(LNDbETOGpx3Mlr%LkN=(Yz4=&`V7m4fusR5C)<$;V6U9pIJOni768dIq6!4oGELfHI>>_rdZGeJ^x8PWE97&Yxg8Z>7FhOoW zsO}VlikD$gedXo`HudF`jdbVAN4Lu*LD@Px6^3oxrP`a?Qu5^i=XqF0skgrxaPf&cvT=jJCia*kL#Qf_$drjiC-TT_T4Ln024=4KYAR<_@Q&i z&SNN4L{atI;pc1+G-j6^+m*Z0SF=D(4*MFIa%F70K6}dfGsQ>5&@mUK34J7@XT<1s!aCkEzSTP>OGI2I$ zI#4n7Gtz8$v&-V&pe!AP`2{ufoi)xq6XHsMYC34|^;fLuhS4>b=@$v(oR9PuC;zc| zx=4a7cc{=2V}EH)--*SrrrD&R@kReZK1r+G-v&WN6_gNF#mi~fsdmS?l+XX6PUTN~8S zp=WRdh59@@OvL9ELBt}I>91;=PRZZUwSJw84x>1T=Dv3g`kURKw32QQ2y$*Pa=x6u zKJP+$(WuB3S>q$fgkbHlKD`fIOhsN5OF@f4;w5bU zp}>VlBaL78Q%c^nOXQ%9f!I6Kw*x$HewGo!{IiEXC-AD<8u@O0TYsHUr*$1>(zQR~ zIu5O;y2cKat|PW4Y%$=+9ZbISc;KgbueTl>STksGrjk0B`2Kz@Kf z9H86sgo$p^?AgM=(Gy}jVX*i=1vH6}4h#@ZU)nvokruom`{r^y@m);+!Z4ScI@zIg4d$n7Rlp>X75JQOFY^8B`K15qLd$azf zl;z3%n0QA{fciMeO;Zd3gDBVwk@WLIRDTAWCO)Wh9k={d1>m+W^5YtlxKyR);Y~0K zQ%p0D3mC9FSa)%~8`)6wDT)hiiwlP+2CHCN9O3BMF@a+M0s^K52j0}~=k%MBO`c8aeZ`^g@>6lB~LuuFDcmz94|bY{^5A{iw%q; z8cxg_NRp@{cvg^ufGntIQMacO}e zBGe+5053hHZYk`-U9W-=(|Pt8lX*uLEr(q(;`fj_ud~o>EB?j3wyR~DP}O>)Gbq{( zUKLRSz~m!M+|l~G+LsnuUHu=tqyXvs=jb~98wU?4*J$H116#!gyZ%tJ#esFZ4+XtR z(FlJyUV+yxdN*BqAL?7P<|2?XY$K?tVBQ_&<51`uul?QUudEeW9Zx_P+^LReyF*;l z_RN`6r$Mo7Z+(51>HMsI>JOizddDE(@i8C^+?FK!$<%p!gcL>guDssxJzyrAX|jxJU&9S(Epi~^Z>;L zaPoA4ZOLx7*Qdnc$R$OdO+xX}b{ zVeE6L8KA%7*->(rseD1#Md%E%jz!mlfDA)(OSJA;M#CDrHL4rRTU7i09#+7fH07G| zzGXNw?00YGHAN>(M{g#GiV-|67BzxQ(2sw30tP}qxP&L$%9}Jf0mfb#SX?ZIg`Ca(p={-Z21)Q(r6Hphp=%^Swpx?0W};%cA7fZ*jg@23`4YATq_|I?45p z7XA*S8tD^;v#(}vT|}o7JODf)^Kr--qh58omgZMMv#f%`E9lc>aypyGv;E1q43af_;p=&Vb|(W_00W$KbHr zmL2c?Ut!6JN_QfV1q@T@^apbQ@O-Tct;H97lh4l`ZnqTTRH+oEXphrThv!(qr z1i%*2_y%U+g2edW#)129`89fNL z<_8suGk;9qJ=Fc=cB_T|xtYpALw-Bsvyvl^#U|`kCG|aby&Jcpd6&ZEC96xLm^1** z1kzo40wP^Pd3(=M$AnS_Ga3O^BWjj0!J48RWAyHQRWzY;scK1H5tm6BU|v->6pINd zj!zn`A8hec^k|m}UKo;k5&LRuWVDIzv@^VshLg6_(Xis{sJ~B19$FY@R}wpOe~!QJ z(}$Z#UZ=5c)ibzW_xx%fEW)e{|1yPYYutPvI=DB!9`ikZ(4T#nt*G zv{_QDgJ5geD&vx4OCI+FsL(17{{%=OZY^ZXt=MBx&|pw9{YERU-(s+ZNpoeL?kUU& z^1><`>nQ%!+j@lRMjj&yPxTk~({wY~GF+-`5kk6ATIYat=E2(s(1;U>QzZzL6Kr5b z7u9Hx5rymq$*?ubM<7TUQ`Re!nh!?dh@Vwh@4bg2=xGqnLFcFpDEQde# z2-qYo7$_u+;eRN`P+^Nc+e^B@KX0Y2M*Oxm!#%fcYHXlcA2ha$~adOtidQq{S1S3^K%sHDnUAW4}e}D`e6#Xhlp+az@_qSb=169I# zE>Y+*&EP6+5Nt~Z7HZPh(jm2>cE~Xt5y{L+%`iXL5yNCnz?K^XykG^Y%dAPGHNeA0 z3a(I+xIEoU>zj%r{vh%SNJB{S69_mXRQxTk8MpFimtJVn(1Km1iI+z_|5UhTJdnK@4&`rgF2R)UzS3e;~B*WU^V{$ZJWocMa0SyBQq)1 zhj`5MyHgzNYi*ISZB{uxceu>RDZeKXaK|b=)4wv%E|kgILs z#kCnqs27ov_*r3Lo7r`jH@my3GLUd?Dr6RArib~n-z!s-rLG7SFF9axBB(i9_U=pV z65jtCl;!RlFhQ_``*sh*Z`*Q#R4zz0^L5T;@N{fVmS-{EXTyH(E&PARmK33pm>f>yp$K0VLSMhCm?sk zQjQCeVu{Nll@XPz%=)J#GyNB(5i04bBHGA+nXYpwo7CLxu6_nM^mHL7Om*M;><=!5 zIi1ZE_$V-Uws8~p^OneF1bks;?xMN8Ut~Ygsx?GO<1Jp;9KL^T)fe~f_L9`wnC^TR zmq&k5PfH`{u_;AktG zY1Yr0^5dLn8|4q^kSw(L7~J00gJo5MQS%jv1ccSIt#~?XLDNFUh55cr+=to-f28T` zGewG`ezOC42W#L+E($ZN3cDOz7(EeM~=%k z_0LKTeBvZA>kani*1)VSxrh!yu{P?4pjw!l4rhO+?-><;bBb6hzNY-nBQN z0qU_Qoi2rjiJQ`hAG=7JB-iF31TY=k(+PFu9QEWI^&I|&O7(J7zL)6Gu4=~zvOVAG zoSnJvr$=Ym=*GmsV&;(#>f^&u2yNSv2N|3pT_{Aobf^BLf|x``sMM5^57#ahfbZMH z)D0E`MJxZVXJ6UPixxMC8CD)IQxKW-2Z+Q=;LnLPD|3@q5&fk?>`rDL6LTB8Z>;Ec zQCDsI>+mHh(KWRr_!SfKI1C>AX{n_0aVZ6v50HgekMQ+eem(MS(~x#~j&^aS?szcUVS~ zv8@VDdDG*{b!EL^Io>)Y_Y57itTa@-`ByS@`QBanqCKvj3hAAMzp)co?sL5oo%6gG==|2AZD zqR*f2&7RM4TiIsyLO_gWIEy9f7)p{cjzCjyI2>2Y!%?j6f_4t`=|V|X3cMxbiGnDE zj*A_wyDhaISCTRsIj{CZJRB+{=UIiuRe$0?ZPw<+#zr$Kqrzb5?nm{h zAT(R2jr{J8S44IJAC@lRsg0coR{|MO{*D?jc0Uw^CF1ThzT(rF<2PNV+UVV~bH!Z0 zb4Z@`Ljo7*%vqQSP&v6<0~Tc)x}0qPJ&Wz>tE>8B1bnCRqqi$YC^%_x+{s}=lIT{|g9 ztv7$?>)8!1NS0ylxQ!Lir5KK9&|MZXmI>KQ(%*{0p7XNr{%oT$E>0t zvwxtgFK?p@lZXU<08&Y!;gArF9R3sR$76p4`XEXO;_fnjcMe`Q48Y z?oXES2Z_HidFX=&0i0Jzk>(8kXPae}=Jp^sQFE;gPmBouD0?8mm1Q>?b;EsQoQ7!d z2%oFV@Iq}@bz3>s(x&Z;BLVaw&PT+UD4wCUwJP^fNYNg_SHz&~KPW#8E zE>8)M(u`vU0Av7?u2?S(^-f;hd@}GJE-PHBevW-#@1fpR7yeQSKipcB9*> zwHn-aGd&I&ge@xOh?2%Bcpnl*zz)9Z#Qy%8U33X^eu?zP3al;Z6qcw% z8=To}n% zWLjP=@IHg?zA=U$qi%~5&N!P>X03UBjg$ht{~Whh&@k!`_I@%mk0?(fj6U$xt*n{b zVzQkVV*sxvlVV4s%{Uyn4g51j^W$Yv@?2x@hWfSSxwW$Nxg*2;N%}XY7=~w;Ap}wP zAyZv~m^&0{yMR}vfnWpm!9R3UD;4=-Y!JjBP=SH1I#$S_;f~qJV}Z`_eEUfeSl|0B zGkbUu-Jbzwm#cS-`<=J>-kL?_m2HMauq9?59f!c)p$gI;zv`5|TYjrRi6 zYl57rV|~Fs*FDpl2w7MGI_UGg76#QVjW5vHB|C!Z&kaQH@PV+{cuP62V?49B)W#ee z&{^0O7cop##NG1~Et=$K_ml{Y`(H4|TT{dXwCM=lOts-gJyUzD!n~+$mCti3t zibN*xDC;|^&ZG96U!i| zByqpA*`kM2t4%RIBRUSW{spC!T9m|d2UNq_Ayugs`*<}#V&_j)veL&c81NX#z1>Wj z`;|0O-Yng3GH8GoVosHb9w{%aAZuM4`9>JKR)pMw1P7^KJfIe|L_Sg1O`PZpqg%wA z@leOIn_t!wI(J*Ob!u+E_#Nl#onEeUQR}$9Lbrha z2o@mu$=kPhXR2c!`KSEM7AP%Dj%(;aem>s?QInm*(kt)MYi}4cNQ}g)4$nERK< z%k{qqMjZc%DnyQU3YkgEIrJU7!_3 zqj)%EOGWjS^Ib)5>Zh$b|8FGIIRx7^U0t}G-)}xAxI@5A&Eu3=Xpb50S;)p& z^GRg4RSaRfZOC6Yf1?Kbc4m;y-|dz9cD_i9$6RbWct*GQVNHWcgp>su2|5uVHyAsK zFR#A(%>tYOJqCK9w%YMKH~L1w_qX$DL|kt4R<#Ai2z9QiVX0hP<+@hzKT#l zcBi#whZ)k^Ed{T#)sna^W^=@7bf>MBq2~VIj#4y>uW$K3 zv^mT~OPsev&-kfNYi@Mavud_=9W7K{9kuoATu;QgW4(bZ9=8Fo|W%uhIXJa|i2Tv&7jYDL2Oy9|WetKw1#M#wfm4a56zq3bQmo%Hp z9Gnc^3FNq{<-XG@&OU*Debd}m3Ocw@aB(zQ(TXq_B)~rAX8TE3TQ3gx*?p+9sT!*N zq+fMrb_e-d1Z9`G(a!s!{3iRQr4p{*$u$oLPd1znv*A(CQoCC2om2phv+v>vZ-WKL-V`N;t$X8pKP z=;w_VY3sVVII!#_cvg$Hex`iBj;?#sUS;Q=?aPXk0IHj~+Xtv^_j$O3kcb#Ed4B*S z)mwo2IpMh&@$2C+x_T(Yk(1EHlA03{r(xm2TJb9Avh?-PoL+$;*PN${98m(#pa2kk z)C4`zWBVFkng_cmgrVZ<(?x$1MJUbMP3QgyikG?P(TEv=Q_Ejte=JrzEzIVs8&HuA zG5^5BwxyO=GJ&{SVQ>tEZ?6UAXEiWTKmfSeVC1#a@|z!+ud2IyF;WmZE#M=DqCT4A z&7w~`%zK#rsUYq*P=&xnGl6$|O%|x+(mLn7n*()SGAx5L=R5aHrLqBAQ$6d|5;*s& z4h&SzmUC^Qv8!x9<>xHhY4V%Tg@gQlXtVj7W90DjSn+(q=!_3Ruum0nT{X;4*epSz1mLZqKy{F-3+Ja%Vd4T!HX&a*1q*Nx+=(``>W|AM z+3y>X+7D9tprH%@8#-z{Ya?_{sBxBUgy08r1B9JVO1kSl ze}0#(z23p@x=9+o5s^#VD>v0Om#O&@gMRV49knJs7>#K@4}DyXhFzN4z<~O#k%?A@ zc+XMmg=s&<+UBS=1LWo}?3Q$o>=1N8ycP=+VJw)4SYNIfSN zV5byx$QQ$#Z2K)&vof#i7cewz!=rQ>;wT1TDout56GEyK{dxDMNFpx<2^xoghRMBf zoOiuAtp*bxqcfGKr!1QI`fmmSnZAS(ruLXw00c8dE2B|r5PYk+3ySR*($pL?u7+A` zZp|RVY`-Szv4!GlcAkE}CTG4@W$YncmCKmsw<8gHO-SkV9fn767v}TQvXPq-u5}z z^r_D(&W{AJ=(_niie(?Az>TRko95;U(F%NX(?>?Y1$PMy~>0o6R7~T|B zcQY2**?O2;7h=%bFgTxGl{Sseo;Hyn30cGRgxTw(q5E<%KBSQ4H=N8WIspQhIu3+mb@`2tN!h73&d%2Px>^Ic~w7UviM zc%1&;etD7o1nla6JcE6ljm8GY=zCZEr8JRG2{j<0)f9V9YT>1#nIq)ScX|*#6yZ-C zU&2a9`;a*l(KnIH`DH7ghW63QHOJ0_{{FPbDcvCZQfQ-@B47$-R$Beq4G$CbLsWcN zz;{si<(I{RnV<+NTB3k}6zYp|0`?Vn8CJZ!?>x?xJ)qLaD=NKDG`$$YDLu|%PMOhJ zTO*Yt0C}qAU9LJorCv=~!>zU*@5M|m8Zb+@JI#M^aC|pL<6kMAmBEEaqi7~mypB%> zUE8v2MW+>EGd?tYHjg?z?_@ZUXOmKYUDoh0cXHhm(pgB`v@0=s7Yx0{%>bF)edaDV z;#$`14{*U*{R-!b#9dx#iscv>yTOBUKf)_j>-$=fNr5w} z2jEBK3W93v5>)Qp8f=I8g|@AXhSj-QJzHSmwZ zs-+XC_kvv3g80YryunPt^xFFdsNY|-qyWy*$ob_jR-YH<^w~+tl9y6hz*o?wVn(;W z5FhMT^50xM{<2i-Ht<8|717Hk9*d}$>BDVPkJAd=te5pFCkNR>)(fJRB&$`ps=g+B3TCtUb&^KD`=~c>LR;Zg9vZGqs zK*SqF@4e>HQ*$^H7;Ul8x_;W`1t2&({Zr8Rh57TE`)^8|wVdRzm~r`DJ025kr7rD8 zFDKinhbxSTN(0OADPtc?Koh-w(Rdv$H52xVONG+UpHDCC7=_rNH_6Dza+W=v{5xjy z8!VPkA)-GnuVQ4?nW{8An{{O-!Ar5dE4)<<|LS@Dsw#0(Z|JyJL*-1?;R6`4%xREW zQO1WjDtcux<=6S64i*C|6t4%&5{AAtVc{ES<~eq^+W3E27(6O~9E2!@rS$0|3rsY? zVogE+&85_K9=Nj>rNdfY`LZExZtO6J8Dr$$(brgq@TQpS*0lWlZ`&FJ`zYfG-O3l) z=va&YeFEre&CmUJD@HL4SRcHb$nup8BlDIuGG?3P zF4B{_Bh~yzhUwk8IP(#zZvDvJEv7SV#QcLcCN3}QV4I3G;kTksUpj?nH|pjKhl&Zl zHi;dgIo|HMH{CYckaqnl#xcdI@FJ9(D2P+bc2{=wLB^7qqt-a%k^Gv{C5U*gRNmkR ziT;7*_$AnTY;HJ(%d;Tum*5_(mz8Bt4jY+}+o9S49R zdCTmWfEDk8l6rrX)HX9%eAIo<42%sq6T%`HoNx{gMP>o*u2?pdWOtTXP$7}1!)Wcf z!LPlY6oe}uJKOtrd#KZ=dUb|f*=G+^d@k-wyDI9(>nYtM=5h589Tj-BDy(`sQ{LPX zvW$2#rfVXJU#;|?Mhr1N4wJoQg2Pq4sbrUqGUl{m+E0EX)?a<`Onkdcm$K0S&aOt- zKQVV*EhXR}hZ0TiYCkRa{QH%P3{3Zr^yhwVHTIKO&31N7CitckIxyqB+kN6Vg}Xrf$I7t_FUEEcZ5L9|dOYQBgEG zDTm_sbI9;2IR>WE(PiE3EV;{ZD7fDtX)f*w@yKKmlvb7_gtjD#S zy#heGtU^IVuaeQ#aKQCo0ItH!ZJR{GS=3Crqxw16l%#D!?$hK;J!I>wDhcbLcp~pz zF-Kf7CRk2$Ee7LXH8S{ds||Q}ua#eiuk5c@X7h7z1wUEE4eX>^0@e{7T9WDO!2Z+? zo*mV)sB3$#ndP>ol`m(}5v`qnOGbLAWG4j{^`l+r^;cO$MjkH2Rer>F+N#v6RDYS| z-d|r6qvO@komyqd>F+jVAOG?L9MOE5lU%(i7Tfas`9U^YrJ(f8Gjr_eRj`i(PTEOQ zIF&-#$}bx1hJUPy~v)VrdFl|%b&dLb_|^Zx+t zdS3;IT0XlGh?m>LYv74(Eoz9Qd0Mw4&rq(E&i&^TG@d?heKUJhHJhSvJbi@Zc-Eqe zt1E__-PPQ9*(HeB8bNC*+bu&U8|`vLj7Ye3`F%$MPpay}_B?7?N9?kJSLru<`FCm_ z5ceNbkpPIOwiw#~A{YL@t-X;IEEng${yQfcRjL9aID9G&I~Z+hC?YsAfM_m37zNU; zlTA1aCYS)W0{Ke;U$X*xmCk1Wl5|TS>bqWTFEg8_15Lq{mqP1tVXVOD6tgc1dk%sdD*{>mO84($sanW*` z2Jhpi%89uke$F|xEEOY~nZ-Fxl8*%KEO`-qz6vi)k|2#<*+i-Z;9NztLU?1#i3-c& zam&~k!`6ZrWYAy7(Y6VJHVngl)VfKvS*oTEDu4;1(*GE!mmIq`fK7|H9y^um$?nivaXA)c7Fg=pJl=JrA8N6cheMdb3kNPbAy)A)-vG>`e~I$0(r z+Kd`OGh$=Um!Pr4gtDW6=^H-(<6owTlpxlBOA&&DWI)YBjL{jCAz&mE&CsVAlwu*v zstIw0vuk#vf^V$Zf_bdAc30v}-qiBQ7`tb?GHpnbx?=$cD%P{|9_A;Lrl2qQ@4Q%z zGl@InFX%O%kDs5*-iErW((8P4+b&yrJ_yL}F#HU;88n>lBJb|h#bXJ#$SYO5j7aU1 zM4u|ocLzBl3_md|By@<4ibx~#9Bw+n+UbqLkU zGwha3ipPp-O4H_;ceh_f>ftm(q~phH2FJ>LjlO{86@lvvgWl7{=S;&3e{6d$)&$3b z=^1n9>F46d`cGfUi(!ErLzi%-2aOlpMDsE^jGACa>dI0jV)yyO{kF3lIz2l4lDAOF z9*-{|v}IywC{(^@=GB)ScpJ3yW$hqvcFV69=W zdSni+v>+1UhAZogz8%o^WzkQ6{nYf;>elai zG3j&>m_GFT=1;B>;W5FZNarEwTm4M1)K8t&5l)UDPe{UF&l*E_7@$X2IkDF3gH|>m zhKe2tZAq9K&F76Mt4?{9f5mnMcBQY}W9CYJEpizLj7DnM5T zKo!KN`RqGwi?F1H^m#G9Ewkbmic@|uHiwJ))K?cr+j8dRLa`u_jG?u&BA5b|oO=Ul zA;@&nZLA0|U?LxG3#^`n?dmC=w4C+H4#n55UNHIs8upY)6=VTw#L(k(L%98P7ojA5 z6c}V!}56t6$p)}k(iP~vB!T|B;_+% z$ORs<{+~;V1C>7>pBY~Z!X}$PB_XxLMh+sQ4Y)hz;-mK!hLA|Fnq!rQdzf5SZEXVq zCGi0TZlJROaYkphD7*kFTEJ5@=cNG=@Pl(botE4ULo-^GHBM?08rwl%ja<`ZN@wb| z9O!I4R&N;lUI5RBpB2Y~z!W@12#HKE5icIMc{MC_U=8T2rcUdxLo%tX) z<_2NsTr4PL6m{#G2 z^oJWe7MVlje21ZRiS%~+tl;F@chITZLC3XX1=M_N`8G8<7ZOaWDp?v%(DfwSt=DgB zzW|9AM80*LOUST`FK3=`qHp!D03%N;KX~+d={Hn=Sl_5kp>x)?J+1O5^Ax2n0!L>} zJTemBKxsrsQ+p1t(l3~0s>p%OsQMhjZ?{&zn)gid)Bv+ zu3kR}PD^XFGI9SVoeqY=BDbXj>dOFR%@|38`uWM)bHniux^l=8Z z-3e^Ij`x&7g` zEWJDrj8P8BdlCPlRduQ(LgXDS@{OBYvUZW>*Jefg0Oc9by-NQgtLjI98^Ym1xQ**#QYwTn6%N`I5eGlqQPZQ*Y(ZJf9uf_ zfKsGrg_)_x_eD$M&;b9z(>Vu+5v^@Jwr$(Coiw&>+sVdu(#E#gq%j(^X>6mhjW74! znQ!Jiv$MN1``^wv@AKkkrc#k$8GCF>7DZvAo-)Nx@7$3 ze&+Om?w*}%&~AVOnSHvP6`D`>WR^A6J;ms`H6tW*-!S8{{lx5U9b>d!&j#&D|BLS+2%3RKF%DxX#N*3kT`qwgReH7mN8>DDbbkb^koH~Ai{P6B z^(TthhXWNd7Gy+T5!a;R;q6^3-A0VBYIy0yKGnTJy6no`L7QW=rMc?Mv}MGw!q)ns zow~Wa3Dj|?3URzmh4oPus!1dGFUiE=zG#fr73uF=X=Z>@Fbl_!L36sq6?4XFC*R9i(H!x4#cYt?63)hsIi>&l7BaAN2(fN#s zFu@MgXKUHln#dNWnXKmB27^sRBpfx}=AKt!X`_kf~}EyV5kOFKH2zDCA4(UJ^gbFy|+Y%#`iI1C3)SDjup z=@Eo;C1SU*#);18CqZu4faMjOM9kRqdxzJduS zH8MnSjoevJ{W%28EjTAliOa1g?@q0jj7{+%e-?&iVFg`QmRPK6Q|o;9$sO_^Xa124 zct0L8bW{M+#zLr}0!w#B2a@EbjTM5~HF#70RQ(p){yeOjHJTKbaWXKTrt(M;g`0nK zBUIj%8H!CtIwRwrJQn$fYHIhCY@;h@!^9^gDWhQATFN$fJAm`^BRpj(99_erZr-4+ z%}b^N{!e#U$aT_DTM3zgwKE;7j$ub+%|oK$AQ@opuwro~_D-xfZ?fO{lg{n}2cW0;Q&t_E}oV_9odoztI5Vuj{5@1e(j)2g#}$g za?1k+VqW*Z%ss~LFr0sbeZvhDSl4%PXV?!iJs%<_c5~I@Y!d`wfGP?QSg(Bl1%D2L zu6+$_6E)zGSXhH5$W-c$Fy2u(4VtDQBbnq*B&vhVG8Q;a=Nu{*ozQgSR8->>`&O?q z3^y3GVqD_}vFjV!)OvsJRoFa_7MUuIbBi@5Q#Uu4t{ z|1Owa>rt^%<7c~4^O|fwz5LsfQ7lnVi>n$X>Lh!)W|>|IV9&M?*Yu8P#9_jL^KezHRA>yH8>)n=mLZ={dVcv0!NP_VSwP{UzNivXN(e@Z^4Koic z(i|k+84fxl?U^U}#vgnpLX4wpDe9ZLdzG)xC5t2kJC*p51`8v>?&qKf!Xb?|4kwFs zIrkk6f-2>WB_XJkDfWT#8c&?TL;EihB$0NT_9gBHA!gn|rjhYWa`nixZ<-$Ek9iV4Yf2N<& zkDLE|S*=Nff;`ct4TW0i7=KqgNKN}x*)$jybptNiT}4eN|B1Tf`b{%tH|Ybu&2Z^U z_)YaD#p6YUq;7RYluZ}@wrU9DXolW1KO8HI9u8sTT82Bya`O|m=y7L@eQA^-H_5=A zlA{VvTdw%!{AXI@cTysLR@RPdE<6RW@5l=}n+2}?d8E|lVXiv$$NdFPmz|givfhi6 zwrm&rAxS^dTvcc~P(J^w{Z9#Sary@eb^SvUBpPlDYYH54fBW0CLROlWUFiW)-ukRVI2{1wI()oO!DON`J4KXs&Rb1%Ep zTE>xUlYHoS2pjEWnaq+!qR$tOJP3|IahAiUIWj>ce~v$1VEyke&hgpSkhHv8b9Yv} z9`gV{ult3zlxY|#&bqO)4NJ|v%mK~;0^QS<`r9oU%%$Gm*P}b;sv(48TT7#ta|Ynj z+ixt&Y15#)myCrl4^=y7AO%6ACad;At4s}6LXwjl%|vC!S8z@L{WT@L*`d;155i4d z%cG|aFi>M%@*=K-&GUL+wMYL*WfwCR6P*I|Ny>~>`2(LDaS522s1B-~G`{~8wWF}f zxmsk-locVF_QAQ%4>jbR*tidY696tdU3j?+PIZH`<|u9BDhh`c{yb5#IWk10MEyp> z4kPWi!3Bi1LSGS6_g_cU`c6lTbNI9-q<9zK{-tO3Tr+seeEUPX zi-rfwREX)!tLGiV&O{8|?Fldt@jvP_dR6Z^^7?vbP|7usL@m{T^u@+ps|utQ&$rqTQ!q)?$sqZy0qh^x<(}36S_iOe+Vc)&{R}7Y*;^?6Jg+H!wgcAmNjRm( zb4a6x{>X%U>H`lZWl3T zh$maasbUTdMa7I5aWpW;bC;0Gh%k*c9&wL|BtKzzP0){dH|-mdKsDCXrl1Jbj5NL# zXNqKJw6IDwNl-Ob-cq-I0Ztd`mXP{TNob9$Uu|_{8qptF>bDHi|9n|Q*Xj^)<)fYj z9NXf9OM&>G9w`g^8GJ)qAxknc&KrFUu&b#O1{(J=^ODAUcOfKAc?8#n%#q|3McIKl zi@0@T>(^jeKd}EjqNEHt*}nXE6`5lvaKa*u;j%2yyhUz{|C#5g#NF_BRl)4%mX9Sm zfaYR*8_$k8US~Sl{@5aBS^bMOvWI|`lzIr*2fEx=2l z#Ax21*V8X)PmJx%e6P%XTNZlwzJ_DHxBoK;=I;}N|41#TOIn{3*F!02K-q+%@z>m# z!e(6P?zN}K{s70x;Rg`ZQ+pbXTl{WaqS|tK>aZMh_fwNkW>Bm2L9O$P>H9kThWV)} zP6R+8K~s?feo&X&e(pZFPeg_LVFPsc!n{p1>GuZ9N%t&2lbRO|sD1>VPN$DNK1R*j zW_v`jktRBE|MZ*yDBH8#eCQ)3Wd*5ojAE0GQW+5vNwlTKf-YW=r(l>jQzUo?!9S|e zl=bQ|e+f=e1e6cMqHNonjP6ZNUzmjK(0>5G%Q{vA<}FS2ugBH0YW}cg%#L(%R+X?I zu?6gKDdW_ueLhgl92(;_Td%u9Cpn2I%PuioQ?83x;(_U53<)sV8efizZMBzXWr|~x z8kE!@q;>jiX=t+d-VhA^sglVn*3Wgl-dS|wKY9fxr7yfn?#|k+Md!EWooD=aUKnT0Zg~?OwYnTbtEn9 zv0#fG7|u6yRHh+!lFCtH|9QOYO92(H=rp1$$L$A%_!jo&anIR8Bs$nVDN z)Z3Z$ZYzxwKe0=_b(xcxY1-ZTgL=?>6Qv`E?bQWTrXs z6^XEqK@%beqty>6V+XZGhoiC`G=HCD2Sq>b3cRW8iw;DgsIulQYH$F8c!ck|>8K})LARnU|=_FoETrw*DjcjoRp_^th7#)TkjWc==Zw6l!FE@A>uk5^q za)VwVnKT2>1eF4FxLvt@a(@UQ4o+$c8^y4WqVQq@M8m4O#9??6EG0!oIF3o3WJpZA zpAg&#a7dt8^MR@l)e_d=eRW{&{Y@lW@nZ%h zNv|lj?>;AW#1DpF%el1AA$%nku1+1q-}Z(Vu8w+Npm^KXcJ74oe$mQ#|Js)xvRhN_ zr-qQB!@@}J#nw7jy@hiqvWKcmz}k@5hx>S^OX*^Os@DSkdEU7k@(u)FngtPkC7m10 zkiYCgc4d9!&Mz-3WK|&IZz7mR17&T$$65>3``6@>R+n~2cPC#jIk5VR256}okF|EP z%zubl+A?(t1&SUV4Tn%L8s33kjA4S5D&`-R*6EmUQgeHs)U%GUIl)b7cVx*Be~mOG zBX8#Dxu1?sv!;#0)38!3QjBh&O1;~_O=$nR6|^k3x@lPcqaOpV>^nUKCMTk+cuePJ z4-yYrgn0*V?P|p+uZQa~67T+o6lYmCS!9VuvLA=F^6WS0wRX@L=oiXK+Pz=bNl+G! zaTa(d?@54RrqDH=m*>w+7URfPnMAZ`r?hx(s8qj(IxfYx$LvW!2C8hJBHC&l{x?L9m9SVG1!`EwfsuBFcn-wNxUHmm_>U^(?_y?mGxI z$f6_M!voYzY}(*Qu^4V6FdkiX-kE;T5Z@clNg8PlY8&D!3yhdU|@b~ zLPDl<4&7F8XX)(d&GLq0wb7A~(0K(3A>Z!Lz{Y0ZY;EY;`Mr8~(NO zBr%LcJh4v(*~1>^GQ}mo7lP%MOe7Vnjn0Zr^fe(p(?Ly4tR($=Ll(9WFaA%EfRVnP zg^CHr!kOOhf=-tX$^ae(Dv%z-0R9swCOS=4OkDHa=;`k0a>smD_osPqG}te32{#27FL7`onj{lIs@_!L znt%_ol57%Sf*^q5>8#K^FfmZicD8WhA*eaosH+>;(DK2rtO%!p%$BLb1+9K4LegI~ z{o2BOPe&{2vcp+ubD#%Xm)KHvBgPLDg3^uStcMk^4sg|yBLuye{HwoHPe4OY(qcZz zjrpmJnbIOEIJMTfY^xwG49Ejnk!GuJOhm`IaETR{V5EEuNPdw+|GE%cGz@-h(+#1r z1%J?^foMOUH%BTMe>4)4V5p@;sK9HYhy4!}XKLIRH{=?A9_g?EmLoNZxRG^r9K zX>e(R^b0k>yE-eP&q;(;MS!p9g=ErS`VOB~1h)nCod_cVep6~jEZqU%VkPVG2>?y0 zjGhDC3D`HN{k@q-x%s3IBD48Ii9*Atr9RQL%rKw)+d&2LcsDB_TdZ{J^BuarCRJpX zumjKCFfT^pZMR*<6FrO%QDi%16@kYqD)`ia_0%~F#^&YwwxZu3i-p1(t|=}0He{*^ zRpKb&qw2aYV=5l^mZqBXnjt>f2sG>WE>msY|%<f=Nwquu zKy{QLE1^(lnRHHeMBI_5k`Jcgve9>i=DkLrPEd`YSdjRo(CF;(h&^SddM*$;Xkd@Z!2Xx9z)b7V(rhoZjZP?NJ(B$@YtR zD+|niO@;fxpquuYH`^__jUJ#i)DsDaMb)BPyNE^)22Ep{EcS4;W>8|OW=Am&vx|Md z78P%-hi3wmVZXmj^g)izcx?E-3geq;iqKXB3dhA;1Yp?W8R|}aZQ5X-vSVcHP1q6H zfcbZv?Xq9Ma3J(A(Gw8aOdp|jL(Eb?rhOdqC^7$l$x1gc;TV4YO2_;}{`W1HC4f33 z2rmy_k|Jkq4-^938qO}!n#Y87mHExpkxeA=%m>=oR)V$pIyJqU6`T(UzF*$Y!EvPG z#8Nji5K2F&j6SGu@Gk%7G5airm0F!KW;OtMz=WaNc{TBQg$VH`Cb$O0=ZRwa7$g9< zRSJnbQlstqh3w*ZaSc9^?UtUZ*bHsA>4pwdChsFz^lRABz65=i?;hdYd6+m6T*RL3 z3sApQaZ9tPcnpD2Nn`=;ej3n#Rg$1I5w}`f@=IJ5tre=JM1!O{q19hy=N(yPKidF&rDJ~O)Sy$&|qXs|N zA#~5)*+~Yo?t|pzU;aPOvm?~pSgN9n4kZzbCQA^8T~SMOEG8OR=9TQhCsMgsE;|!O z1GC@@A{tbOGhKqN(c2zP2ErAO3#Pb|)_xNn@}roN@8Iz8%pYdWw0O=sDSqnz>9p{3 zo^|?cH_i|x9GC={dXYoN?-N!d_sofMo1D@Wu_Ks*)@FuvVD5@*{`LED%+|9B z^`Ds`hOoaSANBxYFVNP%oVMcbbC=n#uyJRP^S69)jmklc*U|3Lx)GqFGoBYGp2+Xn zaLgrlC4F(@bo1W>Pc7bp{cxe`-pFbZSel*|$DV}$nfGCJ!on?T`-=u0u^kSY#_;w{ zIF+-htN%Aa1J1(Bldi%EPM$8#0j>keo}SAAE(pqzzQzIW@pbun;|9q|!a|~&?hJ>F zmA=IZ4vWV1pZouZu(7hTaYw#zf`19(OORiJ`V#b)V7>(VCAcrae+l7Bh;1*NNEWVN zrrOuHS<;g#kZi%&c-r17kR+l1*Nh|`iOP^3)PTef&=$-dfBe}XF7R5?%9m-aVs>sF zcYe4&zBR&z$m1c;EXq_TKs9Z8J}i2Vh%>>(ma$9G;Lo*~gMVEflo4LzN^#z?x*1x*&@28RKFVxma^=4TvA%Ah})BJHF z%+a>Ued2HS9^|@&alnNzdfMQ-vJ|8mUBTt@Y@yNT-j0vui+uN;$FmEfut228!22J5 z_R?z=Cy4y|Kh^J|8Cs+`UtBY|I2d+w_6Xb}b#wNCr0wBYFR;~T%zraV6a!+?gn{xv zC5(d4amp5UKeYmGp3Rs(X`wg4!(*CxXp3n;|EL+|lO0Uj(^#hs^pDDOvbUD|8OhhR zswPw}FG)9i;0`Nncv@4ko#usJW<}g>CcAYiGO!PL+x=Z4CzcL z&H1Yfi6&Bmf5ConW$2F3swz;paqtr-!GOyjJknUUI35vODBRFs zyL({EyQ+sqJJ7U}up9rvFrIHA6gYS*4Pr>8G8^CeOe zb501{qcu@(H(Me2p>m-_bXuaMYh8%zBx%Z0Gm&eNrVcaV1pRQV4=+Fl`UplKhL`d& zzL_Di*Nx5k&=ClFUpNoO3C2TT(iq4ih^45f!5JnzNvPw!@?quvNr z-+x@H4Ecwz9nonH?OVV!u~ZlJ2J&mjDQmI^XOz&&dro$%eIVi^^1{D$WXKk@@^)f) zmKK4L&l&Eqx%E6Xn3ou@59xgyN8uUz?G?!$g%m#;bOhYwS7rxMVJ9*n)56P`I+>Q9 z%MzjV+22?}AcA&@m}G@*m3@*3ciYJ6tb4lhAMq$JN+~wZgVw;vt?p!KjQ$|bMvCk- zb^GV4uvpO2IM=J~X&XYJgu~?okXj3@hJI48kP}BxWtGosD zs}e5X(b^D5X-y+&&1Uf6p|0fvg|^Z)wkKDaY<^1wqDGArcr&m+^T_BUQ8(h7=V&7V zR;S>k;nr}NM{z*Qk$4_5G_U=n^v>_XCE|psMc&ubmB4S)Qge2G-ehbUjEkJe)^=Me z|HM%vNHbY_orXR)lcS!7B|`dZGCZR-J57yxhLT~5;Us{37m6GE6Ba&w44GY|$u?RE zkujI;K;mlGUcU_BRNX&VSA%HR=LQ3i3j22Nn&I3Nxo>fq{aAT75qtvUql(E2AMl#J zn|N;GABc|Zzg9$Mbm{OeC53%LplM5fQ{}PvSMS z_DEyaF&Zf0LTgdUr4Qs$M;Z)+IK?vwThObTbq@i#y!Q zXN4SiNrwRu5%ws|oXU_W+Ue!FbAfs0;d9_hekE zUs6{&X@t&~P8g#P}BNJ(nG(L#QIzpFtQ3W9S?=ez{Ch6cNK< zk@yy${sWp|M8IgIUp;=Jt!S(74HppuBgKaq_)ydwVK&k+M1Ndl#-v z2U{Ga`7x&+27YI)Su`Zp6=*4)*tFV3RvTauf2G%$TmJ~}M1V^}=)QcG9YBEO2(z9f z#;0M6;l|(MyeJOe1u-yY%I7+T<#y4ABzx6VB@jcxW9voBPnr5BAkV4T_;Y>9v)#zZ z_wd9{?g_7Mp1bpBH-b5LlwnxZNyT-?I%L3`+1iKak&zUaZDd5nMjatC_PLo8eJdb$ zf!J2m2RQY-9Q9lrySPDoAcRDpJhU-Gp6!bByvR{CUvSyj+*%r~aPSt)fBX21|3^Oy zPHrHIs|r$r0XFQiAJoOfOOioCX*i0ci;>doB(IU3v3X|MZ}lyp063$zJZeg41J0O*$~Ko5=%&i+Mj`%n5Xy|o>Q45+na zh!&)-3!*@XM!>U|~=oqZ%z@!qQ6oV6(aj;^eeM93_QYhkAQ| z4vDe2zBq^MpQzfz(cBS)y#*I#Kep|MG=+;=z1Gs`W(usy6ApM7jJ9})F_onc@m6Z3 zjfus?^lqmO9LgXXZ>>SPQ1q~%cHIquT_2kHQGfu$7Dg*MVlj*1SWzZpLV_~g_YC#Zr-ow8?Y)1$?N4-A zC*Jo9Pi%z6K*&K#x_mJ>fivt<<+6rU_<;;YO$hI+TT~@k=oFD0u({tf#ZmKVxCmWq z{v5P)gPiy?ZL4XoyMKaqZ*%vafGJ4OJ^eO~^Fh!u<4fX%*NGxWqR?PtoTU2tjdwm_ z`-$I+@4u?5yZsP5@f{96jj%61nCh9M3>{<3Jd_-(%4nIr!qqT$2xu91LP$aLaOt*I z57(NynYwdzn+{C_3^>DkeRK$sv%3P1^3@~bf1W{wvkrYC?}ik?%R>Cs1|C>JEpXYX z%3v?a#UxDcgqnYs4$7!5%x%Oqu;J|kU;PAueFZPRC%`k#5o`@|YqtssS};HZ?sryhk@jLU6&k1uvog)O{?2_U zC0rXY7O5g!;87B+Y2a{LWV3$muZ3&XnEqQoQB7#3LIO7|l1aauFzZGrCB%tM@yD~t z9!(peS15R<(X?zQD3h2gVy04K?cn$B9&em236GRr660`}o6kwCVkpKQS1HSmz zfI(0i2^t3eLSnHTw==u!~DjAo-ozjnoaIhEm$+i5-ZM?f8e3VVG(%T zg$JVSGpctvHKnjQ_<> z$|i2YgIDSGSEk^|qTEs7DBgCF7ocV^w*H=NPxKP*`0Zxx-nvQ16*r`Jkr;Ks-&KZ9 zYzUfkq3zA(fD{or@HHG(QN>Jyxa8SR$^XN52>s+>!{T>gqzK1qjfw=scAKn}6feZnS0ABwFoTCgQ+{sH><=a%4 zwmV?>QihD&IA8Nrby(uW#~d)H1lDM|Jd{Lv*>5;LNTe@KihdXBE@AaAYKSi@OxqV} zkj#x_kx=0tE2@+T$#i34r1%Qg`?Bs)QTfB*L|hyVJtPE+&G`#kR@#m+4pq zcF^x$c;mbDVlU>#@mJs8mM3D{d%(8QlKq@f-!(^)2ItW_jq`is=CpP=|3a!|;((ai zjZiZ65BPF(-MvwOPR3xnJ z)W}Eg1GjHBtMFOh-3pP@4bQOJiD17(CLEs(EU?(!`XN-9T*e zcp(PoHayL06zFyEHe0EZSQvy<020^O3hK3SiGEQxtJpTcIYGxaAf)|m)iBCJNOH9X!PsM1 z{TGv0AannpK>owl{IR#eiMJ*;j+adgoMi4P7bAgoZP@gJ-$+70cTY{i&sgPwBkI|3 z4pv2TF?UeQA(3A|rzfL{r~RI^-p;x=XoQ+Zo)q|vgZwv%M%F_Hd3A<&>oqSErW(7x z&pL70jE^vt-=T?dQyw1c&j~@_>W|Il?qO<7ZmRd{+;({1ZK&SpFuBcOmu-_*-fc(- zmQ`;ekCkG7%srL^tlCL=3;9rf;w5*HcjX)66jr*P0RY|<1E)($ipOCmIB8jwefhRLRJ1F`( z`p?6AF7>Z>8^sTEA#&QNG_lkzKyBJh-5|HTgx zR$>W5C1XLG)|7V|>>*afmv$DH4V{SdLfVPELD(8*8se|(?XD&(%?MXXEs`KHSlw&#W6S7skwVM&sK<+A$38Z>oyWW zrq8dFo~>#=Vqdg%1w^DLql)M@Ds>dcR1v8;roCR3YVRbc*iohLITe$)3}x!#S1a2F z12s+}H|6B-B6Yt?DCpw}`2z@Y@!5cb7hD6Jxb)Q_BvPRHRcy$6`_QFU-rSZI&w?N{ z1$G1^7JvNE$^&c0Rwxn|bFg%`aVLQ=jx0t)pIP=rQ+P)Dit%HoXXt`5HYhGxGJkc( z*GhP%#OrUe*J>gmRW~};j8ICM(l0fuTosb(v5d}ufmDAIe6{i<_t{rL#o`;y^UR8eSA;fmco zvDHCmS=JMd-Syvu?Wn5?!VSjm(}HR43wRtgp9XrjHR9$>KeV1-Df3K&0ko7t*GJxi zB2ILC1oaBisT_m@aHr7kc!|dds6l&=FL?Dz@Ls?R5;GqZBuA{@X;G#s&X#4}amdT*OTvXnA)DClhMGli&T{ybE;Bn>%d^^eLz z?Q#fMD2MyPbxT7Ec0yn0`1fXhtf^FUM8W|*WbeFHLJ`~BA`|c`@%K82;r>N3T|Ca( zD^wuxqsn^G!zP!$9nWSuq0^@4hNL@MP9o43`>nbxs?FtNMFl;Yp{jo6j5&CPdXX}7?wF?kP3)m@8N;NiT*rEc5L~V%QZIghDz@_kf z`NW~!H!pdz5rhBj`&D!fu@x&20D=bqAb6h{qQ$S9bfuu7#lC5GGc9+#=IA~n+BB%d zNKn0=6B$93Pq(gyekL>{oLp$uuCgPX&&dul!FFpC> zQT<;THWyE$2b4GV&L><{I9^9(E)N#G_1U(uI{bYfgzam0GS5<&AL^6E|;I}#XF{AX{coDeksm%f7541k?>LG;|;b%o{}jk z;y%HGXd^EF7shg>CnKR_rK8fI(gFv%dZ}xzn1NeH{nF?2AuiCznTjLne5tLeE-4Pw z@f*-}5a+I9$#AkOKY;*brY<;LnB-Y>d;!;I5*(Vp6jc75du``(Bj;8;edMuw%Vti z94w%xMj|m2tfBh-sv_pgSQrY5HNFEH6N(zi{LlKSLxqKX2gC1Er(G;tK6^QW zb>;Qn^N{37hb5>#xDbqY(Scx|OFiw<^lx-mrW)TJex&>O>}{>BU4af;+p5(KoYvvj z0~_i;nY(^xwAP+qxGRoG!b-y3D%ueZbFv<%&_-}rjis`uNyr6Gnt$kk52bP_Mt_Y@DK>t2yzv>PFR|D2zQZ2(TcOQ@tw4 z&7wbu2kPQA46}X$-5za4tuipNe^`lz-J zCG!?OYHLkj)S`Jz9s!kJb39FkSvCB_gM$>*odLn32wMsdV!r!Uoe>GO;EH2|mmA{r zurm04NT9P(spm=i+|Fq4-054xVOEz7{-*+w%%mvcNESlKc!+{A``2$M2Hb4H8nFVI!$%b;5k1?nfPTct#gIbLgR-mHj)mDfg) z)se2jiS^%}Ub?O|O2?cW>p`6aGMi25K1;E!B=u8<)ZuPOP^9=+w-;)$r$fIB9 z;p~*sb(#_jRrD_7oh-9*bq;h?{O^o}*0b1J+7T55h>)6|O*OO@m^BM@^e`4C3o9Jf z9`-6cf!whOR!*uoS|m#O0VdQbDi1Tl8T=ZUBuL6V5sAYNo09o zfWX8jvZ}=Nfy90zjY@t|qFYh35=|PTq715;yHt$5f>O-cx3!<}*JiN+Z_DXPpbo6a z0cAFSJ?bp~B1yW3jV8KIK7bLU1^e~Q-IAj2h!-7+D`#Di&fb#FUX#*52yvtc?un=Q zo_XYUa0xyny!f19NRp`VVCy&YfETeKNGY(k-|m7M}FHv>$5yt2?h(H#|P=G#?ic6C;R&-i#wd z6Im~9TbX^agt#1xh70#>L8X}PCs&lz?LyQrx5v*d1#GoN-VfF~#-RIeE7YmjPz080 zqPEDru?sz;5qf2nY=}D6zl^+=t`!S@59zvHW9=Vtx{|5%5OjOxE!WXpFX2BG zj)r%Av`f()#N8`#w~c*f{#~<|x9!J;LFA7Q*%~c*V)9{o&3_SvT{1u@r5Cn+2z!2g z=l{fUbT-x)IGJ_#4Ek9mBHLU&?tu)~9IH^??$XBf>&VM{u=;Aig*#T03h+m0(`vp$ zm*u+vLCQO|{oz-pJts&lQ(!GdDK4-e2v>mN4}+_H3JPvXCiR|aH+{Bo<$T@uzYH`J zgpFhD11c&fz9MxDc#w6#aL`#8%#{?c%pYke*FQQe@hqCitYd^EFw4+=Ka@rE@}T05 zV0dB^tvgMnRx-&X7ybc^d3H-y$5uj3i#~If#RZ)dzA6sl>S6Q`UvuE~Cs&uc2uvA` zo^K{<92HWnEWF}{*Fj&BrZl0$hD{kLEE<07@8Ik^`A7$M*hxgmJwA$-}|FC20h4TS}qGJp(h&fL8RQ_^ODjmDbXaOB6pO+ zXn^w!t*zNB^noKNNCp#21k%_!F&BHZU7)81{f6}!2z`V}2Y@M9_XpkhV5c`3(p&csFl zHfZ%7yim|~_ukBv{P}6Wq|6O&o~MI?Fqtd3Z=dwkUGOc%{WMY;amDjtBscK0*Qp7g zopZIHIIW>*cKtOY`%+xTG^OxtJ;rpag)^yTJJC)}eUXVcPqGdCA>SWjo-x?^Her)R z&<1{RU$_+_*6P2tA?X3{U`Xk4Jm>^S+${fJ@4?2w@?R_pFs19@gwKogabZ-LcpkYB zRU{!BTOjh+&==CzPc$3cvyBF+PVlR8z7f3F-cJO06U>>WnASU|a@+uO;{^>A9P1XM z&?J8!04k4x<+x9{(`ADAB_C1DJwfp_dZe_N5aSu4th2r$Sxh=}e-dsIm|M~leo&QF zm(3@fzS7euovnW%+9MXuvLQnIB!bPhdL%^{3kY(ojkcOaCixKbG^RY>vzIA56|odY zh}1L?F{05l;f=V75DPq!aXRcU-@pCIjvd!%gd{@)%ps3L$C(QxEKpmC?LZG!!bteg zQXzt^m2pVtdm!_@>s=))OE5OeQoawY4KNaC$^=6{)n&l=9TQ9sD(k{INqT@4N6W^G z4N_q(F7&k&4MQzt8EPq*hDjb>P0QH#hT@??diJqNG$?9_QMA0ls%yd>LKKplgzc}s zTd|D+sdXXUvIH7tmZ?Q{l_0{g=P;x4rN)@b2#(vuuN91OvKnrAjmL;iCsDsm)=1dlJ;`E~qnl#8*_KCa z4RqA1=Y%g-!&)+58J5QMD^}rMJ);>6Bd`Vma3@It(EZ|PL@eKxKcSLEY3`B3ptl6KmHS9GLiup+!7Ac0wUxMIt`%QYSfoG5^uP0G zDM;6!hWnUR6s?vTQ4Pml@ zlCsiM-ge$GmAeQnKxiE_7Lk6z0RbM{!Is0T}K{HacLub|-#2G8do)gbokOsm_r=|Mg?oQr0Z!*~>Dz-&UMTLlXv7}_W*Z+sEzMqd z4KiLJ2{z~$wiUUUPFM=hVjCTMR^A6^PC#Dn)JT40?7tO%zmo>D>NP^~CcMIATl+!S zL^5rzS`91BUg4~1{EZ3++k+u2iiG1as9(|~jib`Zu~R|;sj87vHr;|lzFK0f%}CV0 zyeOGw4;eaLC=*s}caIHVS5{mBhE7*XOD9~Naxcn+X}M{BPfAbIjd1Ellqh+WB=WYRbYiqY&))c&2k=Y)c#5VkDo~2X zdIzo>)ikg*gBAykm&kKosm*BTFDjs5gm`j$YuO~s%Udgq zEX;X(I;*e8h%b3t9mnHX;oUnuFWCSSS`@RDv;xkv^@F%hi8u)#Y-p;)7ldD~g_Iq- zS}^7(o%fRroN$4oQGB%)+zq|Ti!H;Z*i)%1`P*M?!3)el;3w(gu=aW6{{go^NWXPN zSA1(Xtox>`!nGIH5&f%fIc+1XBSKHao{($NyIGvpX3sehdJ)kFnb6_|A9O+VOH!&&;F$EEebUU#qG)!%pJUj6T@u z?Bua3Q$4HyYDV>|=Ldg-6di>)pzPz#xNut_aE1(B1cF4?xuA{%^o@+tVk9_HjtJ%& zp}Nr0MwV({-B6$Q+l*4ZuKxAvg?=uytta+l^PxFcgQ~ifK2^_~vvsV{6gt{hMSyVW4(#46YJ0fEo~Juw>H2>?3r;~4CT6Rx>KITg zAmd+7{0)1CE&KTKqx~?q%Vs&U^>|qw&xXyUnVeL|%f)oo3{U6PWOz2Nj$R&Ai|(sm z&S%p_-AsNtZBB-hu{|HZe|+!t^giIdbzZyb$O)wDBSjfM+j{PgnnWGtvJJ*5*${UG znow{$zAQKy1!sTaofVu+NYgl|tjzlnO*^wiW zPq5fZ=OSpUV0WDhr#-MsM}-f=kYuflCT< z16*>C7rDoa+~Y;=@gnzlk$b$z@;$13A#Q=q#r2I3TGZ_5`X(nUa(R6tz(Op$yS{;1 zddYineS<<)%FeHE07;#q=x~7{K2ktkw%dlirxhFX_WCd z(~tJ+WW9fHlR{*}4w<~YqGxT7e9dCxX1*9sM)l{D*>rhMH_`)_4b#IajWdITF{lbqHPT6bys z%Gz$!nth`K{(g!D|2923c>0jAbFF#dvQ02o%)rYTwGHYm7`pv2M9O#fE?%NWuIJv7 z-<~ePBRyr`>k`=6>`SXl%zU>l2QyUa%i(O?c<0jg^MiMK3wHTi15X9@`#1mApgpdU zHjID9tBies)n55+w{f>Jb3sPsHOz!itZlZ4I-6Zw#|@{|A3uf+aN}h&MHn9LL)ehn z1$%1%zp`(7Pe6Ln^!*qogbHPDWOHM59$iqxVlEQ82pSauq#2e0)FpbHv<3#G;r-LU1B^9L={QFC)f?NF*^) zv4~0=El0n+3{rT6m?ebL7FKFWC{qD`4;EC3fi;KP&WAwvd~HBQqKHaf<*bXJ5-HRZ zW-{#LIdDo~&@amA-uT^rY;IJr&hwMU@{pinn|l;0d@SwKmNuUU|8z3*W>5v$-bUAS5NizWUDvr<~k(j@o=TVeH=3O zqGJ3$tLoI>_x>$Ac}+US_;65+>i=5&I<@%lFV^C*%X+F9)qkND`xSS5>FA5}hgttc z&$T9+v;Iq2Dv~7Z*gN^K0RcA@xN%NbLrEgt)C~hrd+s!UP*Q+H$r%p0fFvN8)1AwK za?_{0A|?GcB_3!~c*2Ng;fN$jh;YYraRtzw&Cnsm&>>OWwgFB`%gbVWcZ5oQtQ~Yif;wZn!;7?15ZDJcSZ}LLP%sFWIpnZWfe0{eC@7r?1k}-UzwRF_nz6NsX zceq}E=%plO;Cv_>u!10ugc)OgwSG*ySjP(ns416|n4tsWF7x zh6=k}gIQT$#^G+@KLg+oKCz=uev>3j_2Psme2?i@eMP!4LQmeCNG!e0P-D zS`JhOIdIA~ZTQY~`A#<{Y`Q0`kCG8nnoy}-1_+PoXV^#sg|$lWoCSW&0%s)d7^rc6jCv5AiW ztBE*{l@uUQc7{MWAx;<{2$LNUWbbDs%rq`giF^L`=IZ&YB#js)In7ygvy3vBm{L)a z<-jzJZWhtoSdxsW>z{9a_xu&G9uNyoQjnb*vb*-a=vFWPW+=yOK_iLqlrOGlT+#S{ zzPV;uT;J(O*|w&)Sl8P-+q87R*0dJoPn7a)xiGKQ);wWM{R9E#CBgCi6hRO^6l9h% zA~F%pBqx$9BhPE(lVowXDy{Iz@E@KLuJXNU&J@q%e-c9eWq%qCl;$L%%KcPq7e|K> zlH^?aAwFL)#O=DCzcYgr>oqpg_`@}SQ*k-(>ZW}LJt>d3#im?;3M~<1f>0R1vilqy zk)(+n&MCwvBS|V8QENz2Fm{rs)EEQd5>|kbR7gYhE<6}TbL**!rZn>#ngPtRvdd>o zFPe#*5(aY4U`9&jRuE$wGeLR$hgx&u3VO?Vh0NxlvrpHFil2pbLp7(dZZK$njKpP$ zqxkjpjOAJU*3N!3FOVwnuJDVWd9NQuM4F*~5|J1xX8DY~PZF7-emvDTmMR-lap9K? zX39V^MtzH!R)9T-nKS?AH=&szZ!ww4Xr*x``DiBFkm~kk@^i=@z&tr~qoFwq8h>1s zO&Jmm97@QOvW>M|g+^6iO8HQKwyHIz<2@O;4ugdviuvWO4osw1+f2tc;0M;rz}rd4 z{sb5@z09Y^nod9~YUooBHPo;Qr-One^;F1ZYDXh`=Y-SD5gavjKh760b#c!o==Fth@g)u)Ab;R#WmO`KiEO}T`%*v@SlS~ifDb#h|y>&~X8RlQp; z4Eb$op4+-Boi2*bi`LrD-N$RN_u9pi){XUkS2bljnaKozP)2y-eE{*tt7=__W(4}C znb&uH-&OS%EewL!$5l0dUs?51Kuvrv3EOmw(qJYo@F6V1!w&qoMpZ~i?B5r2+r6%~ zrDGxaM93vz>hXnYDQVHX|Vv~9t2XbbSF|Fl?McvE!qm3!%qv+ZDXA@{b{;M&>XibN@2u+gXp;Q`^^VN2YUA2FF;u(d*|p_gN^ph6%XQtB zZTAXo%P8n<*``^R35XQZmmRBc(33sIcNVP&fej-WV`l*y55P7)_Yd<^s?;F$(*VqX zG?DWO%$Qbx92|rh3{~vA9%|FH=SHUkul-F3l`szVGn=NTkrrkmfiwZr9)*yX5W>n| zx)-5vEmI;?a-i~_Mr+Z>^}c3HCN-PP_Nvd2q>OP;V?LJj+xfh_?~2>C)zSyFPmG-H zi;ze;-~{Tk=51ZCA;$+tvy`L3zAKl-Zrx2r3Ti22g&Mzy&2@MTOEip(-<9pWsdVTG zP5@R*W?o+=yr+pPOLYLlo)qk--I-txpN$bguQwv-?2QOMXd^QHy2^mAZCTx|ZtGoB z=}i%2Q=2cI9kRG)@t6xSS=dTCQsB+XFqd`^m;C1r8GjeRlUqx(vLtq^#`Bi(ys2xG zR~DEKGZDXD8rsgwVWRw4CY`G_?>dNAAp8%?Q@^&;0w$+?n5!1$Qcn&H2y@D_1AA4x z521%*k~}LW$unY-I2w~?QY3abrmK{`2+jCtCj?Ym*lx2P(BVxDI(t)t4`3u-x-^AX#utcuEONyOB4LNeU`adm8{} z=zd);t-3V2fu06@xwCsz3`d^8?nMQ-?y)uP%y1h>fDbFniFb zLq$Fe88N8#xi|rhWDfZ`8Rh4%8X2*3ff0KuT;${QVPMn`asnBp*c>4vA@~FtVUI^f z_|iE#YeU%dHiR!W3}Umg|BPd${<)rT+h^fWk&!Zlij+klN?KH;0;ouNR0ORNDpDR5 zDSwBGpy3X%dfpRM#JS19`X@)@Gw|R)lY!MiRHQPJp1?%VWGAw(>X-0D_B|1E)Tx+r zvK~`v7<8N(`qXO=d@@MVaug#lJ_+geiFCu*7BqXqkizfOs4UluU}^2|ZV|BU`ph;G zl7(Rq2Pp(Q0fRVTC7L`Kn@T`f@*-&T@PEZQo)B<*Zx0utRtC5TU-uTm;3BQu#ym&3 z2+}%Fzg}DfzD@+_*y1AS)f?VV4~zr{bz8aE-X31+ z{$_yNHx6#VS-4Nz(r#-kLn{qhO#7q669+9ATz#!# zw}90Cu?2Q6>t<7QdXGiMKUPM~*ni*D8@u6B-@Ar+-d=MW@4Bwu`k93CnMz37pS&NF z7&0;5+L&lXL$~p-Ma095qV2}v+dW6YHRX^{DWQ+N z8V0Eo=JF(0!zSWfa5anps-cg%8g_w7PG1ePmu zvCWg+3X5i0Mg(YPbPeqP2V$4Q8YaQy0M0v817N|pjKEe>mOUx1VE`&1m|wi%^N;rZ zu4o>MY;a?}uU<|cg1xLa_mH=O_ZPrb#QwFr=^hVwp9R|d;Qq|4C#oP-mc_!`b7)|c zFrAD%0dPe2b;1GU#3d2g<$uWO7}l|*U*(p{K?pToBrvp$r6+D>4z9YH-D$Ub0gXkq zL?_XA3?RQ6y=8u%0$P=&biaNsn;Opr78*7M#KO}#Vu zeZcVclX*hH+#z_;xC-(kOQyGO{0Ul9p|IxaMQ7W1ht+%!+i@!OO@GnjD&qYHsDVF; zo~LPPU4-uUK;^*2(QBUx$++sTeTH^i7}Rzi+f$9uviMtApjFw}@kd%5o&YB9AT06c zWy#>YEIF_T0mb_u>K)z*>Nk3xnWGAGgU1|Anvm6o6f=X0hDb5-`a{7>oD;mBBzh&& zOMAUzJhKVa9p85c)-e1K-^a$|)*+jKJ1Xk84XN=SeA+*ZJC1TaKr!68fTBjDNdv{` zhz64MzX8J4&ViR<9|IHtIhS#Q0uz^H?G7$~%Z{5c6o&Uag{5wiMI0Mrz+Lt-BXvsOipII(vS2s-^{;zpFnMQ)f`j~19q){ zi}nwGwSE6pNA}LKY|QL7($9i19CfkfwzTpB&1xd!Qso#Y$*!ylzX}7ju?mxXZt~gV zTM0SZfjNxww}{Yjaer%k^o$<{m1{(iVnQf z0KqY^HPo^#Oeojz6DlaNfNK)k&c~R4{X`q4O-xADnUpKsJOwd5GTreUuc2|~VnUq1 z@pH6vd)4B?t#i0Z7^%rrDXjD4r(et$oRHa*eCS$$7L;Lb2^IB51>6;RRD@-zR(_Ia zk(ySr0pvthU`-(kz?DApQymbM-OHzZsjg>1xQR1am2$EAeR2xacs)YFuk{vxw3~`~ z%rzn2hC$&cI@c^p!qKDKuDM`=jJk;veH>oOHLiYDW6b{9L*~F0Lg;92MZSBWn&MY^ z`gxbG!b1E1#1DtFD)X$$c}B&~s>CxY>#T}4DK18C|1ib6Ca&w9Il((;l6NOA@T;t& ze42O8n0Jl%C6^!%)4@cD39o=n4{=%fS<`i!B2O>80frAO+K;-i|95@Jr`OVd)`$EB zZ8#{3SI~!iN*i8j-7DzB?wfD$kA3>hW>On-5ONnYp_LZxN#XPB55c{&bC+Qs0~7%{ zmw_q*69Y3cHJ1@65h<51@D3RP#+OO(4jmybZaaCfK|)Jlu^+!(EN~xRzx*4^?%HQG zyUS?y<;nKPmxu5U9|0eir|=FvQzF+HgO8Nr+4XH^1U_cDF+|uryIyCn7LwSjC8Lxs zK544%ep`0c>T1aqUF?hQ-aoDC&8A#+)fJv~q%*-=J zmpJhbCk(J7OzV59o&WZ;@BEi*@eWY|(wDvQ4i|r)SLMF*6y1Fho~l5*s<-@ZFnz@yU!@Yrhu+1|BXS*-m_ zed~XJ`QqEp+y3|PDJY07U|m%adfXty3!V!Nj=;U-WiY50byL*^L?Z_5VgJjtpqUElYV@>K=hVK^`! z|4sqKUA6%B)KgG@P?ih+N+ zXv)+KQosrgEEQ(rDq{|$CE@;hAtRGBCq9cRUCbkASf)rR9O`D9h zgCLowfJiu@(2xx%)Cpz57QPo!4N?dN;L$V?YG6Q@*7FWDe*%Ue;1tn3^JvcH;CMbp z?Sm|3WZ96YQ23G)##Ao@PE*>;iDC%o5os?jJ&QF`56j%7bZEelMYe>*j>?O4$he;1 zOomxoj^d^|^#3aXfTmf8w7b``{h4z0I!{h}RCY}nz)MGJhj`1@LWjlvZ>|%rx|9=Q2KM+Ep#I+I+ zLzMCmWzIkp?0Iu_9-_pDhA4IpqU8S?MDh2BsH23R18dL)MyvHiJB*L>$0Az_Ors3g zsZ?XZ;oYT)XRIiEJeS?UW6sXyrUK}}qi|CTJUo|g^$s+D0u_9V<^U=LDOv6IMz$B~ z38VtM$l+;eTmt>HN$SyV2#g8>3e%S(d{U|=#$+efi1KoLkFgGGZWfzd<4@tj(bP#swqtO^`N8TjDU19*E8+J zoIt8chZQYdErz-3C*yYUQEF5HpU6wIi8H399&1{E$6_=OiqV(bH-~Z%SYk!6b74lD z6;qxPlbaGm)=iu$ef%n zjpqek$U;OyhSw7XM>SpRrM3veIU)ODUAsCozPODqC>!v9UtFJuIz|mVi&?Onr#EJ- zPCD~{fl&+J>)JEN=Q3!jP@6w32c|VSS9jH8{rYs>m5-UmyR(HZ zf+b|R_$r94y{`|OwST?|E7;XtxejGzBSBd*E-U-VeDDYa_!0KxRnVsuTG#mXXCD5$vIy<_f1kx;M^mazdki0AB8kMW9!>!;|RDYEF+L##fR~V z7{e~UpCARq2gv@P;C@2P&2T+I06*rU>j}cZ#uZZG_rIR-c!3<_~ z(c1L%5?iQYawsnU{g2i^j!mgaPu)o zL@aH~vX^}8qEoQ2<}ULO?gZRXKs1oEgK*dHj^N!8>$M9i?)Vou+q(l?#K`CIhs&Hh zMj#yo%2*@!OTbE4(q}Z%2*Sv|w+4(LPV6?*gl) zJ!Bw`E!z_F_O1uJ-C=uEHf@Z2MUr!@7mVxsg%I-ZWbmau$<3x-{gBpzl0<3|ukG{l zwm59M*}{@a(R{l3{e=-o8x*CB2~Y8a;e*+HcwNUqNm6*Zo^H544?*GzOW)xh89W?c zAA+Pzfz@80fN^eN|B^p{a-)YcO}3Hv>TVY?JBEvygs{kGFHjcI<2J}EEUXK*ku5~2 zbvv#&nafj>+x!WNKHxoAx|(dRchStS%VuiyT{XMSLuP@%BQj)>!*|CUoG71b9_N^-p?1r?L82b(_0?$vENBa(B ze=N7Z1!gj3#?8)SF%uo@i)vH;O4L+fD&wH%QFAa6%rbf>-TAV2$_vJ=t^a@|(`5)! z_P78)12zFb#rf|M*#7a&SO1&}(aHM^%3bRJf*8T(nI$3vdqbf9&nS@Ae-$;T?28&pZdEWZ==|)ve!g2z?ZC93*C%0t z_ejhhXti2ws@Cr;w7>q2ZPEXG(= zI`PjyiVh3>MlQatyqK}y*U;gqtM~nbZ*Q(RT^zcu-VG~BFw9j>^jNrjh~uTOI9Oqs zNi9mT-S(^3t_wJhJ+~>Vx~i{yI2NJZ6m6F-Y-XGSj6={^N<+A0q1eVFVnE>k0JKMq z|CizX4io_}m*JWb69hOjIUtwu7!oL#HT@0}f9xFlk<9earX8l2vIhf4B-H^frhNEwj z_v33teE=pQd?FDe^d_PVGaSuki-N8ghE0Slgeb7)rMhK=08Ru z8;Z*9SL?EnMYG>-8fn4JQkpV3J`8~)RVR&Hom(qKCyfXu96N-Kn2BkwvJVJG!;kAG zD+?P(RB|8C6e?EM67^0BUADOwRSJyp`DOs_+VA@Ka7P&xxRnY7m?Idea}F?pe{8Rb zjj*XjYRz(CYl#kPVF^T>^jv^W)ii=6+9Qj(k4`lvjdz&(88+&W?gX`%d>9LumNW-bw@S-pN-6 za9fpWCF|PkL|zuDG28yoMmsSy3+fUSZQrzBwePzN&<-4J&E+C%$Bo`he?1AK=Z;?6 zxnoS#A_j9`T83;X=atB9*dooPH}vkN_h`TjOoOho+(v_Ay@$=u#z%QCf3tMiSeYI$ zM8;CaqYs{o)pRZl2B}kLK2W!u{-fF}jSxO0vUQ|Yxmjb&BARmbVY8ab$|cJly(zX{ zVXqfI;YE7Ak`rFE*9*H817G=%o{}$-F6_+=U!+2KkqYE_6+EYVLOcGvc9(rpX{fo1 z)LcDdtguegzui4V^lnk@%RAy`z1qh$>A0vD$ZrKQFvpkS{0ni&&`X-&+G5cQwrPRO;UL@ct{Si8v*c{H#r^Lceo3NCuXmGN@1(I*6wM^o2(vs}-Co!+ zl;lfunsu(?=eGW*H4&o$q^>v6x&BjDiP*#V5+^epTSNr z5D=>;o&MXai|4PU%m^GD=Onw@0Hs7y(@en_W-7Z{XFts9;HNp5Kf~$; zVMy@Y5nS(^!;UzT{}f$wdwIBBmiyL^s9%0Lxr&}#l|Qh5ik)0V!~@It>19F2g;R!G zEZo|}OkjI%>ez|>^G{c?F9=Q$i><~b(u5y5gMS{msL&D-N{(DK?NOSWSMx}*8VeH` zagH=4j}QkA!*ayH8P7WQ(c<97PgY0l(<(C_F9bC{t(kevgpf!OXB&k=gW8Q+3t!}8JQUNrQ=xQDAy!gaDjC2q^p|> zJdP1PTQ%E{b1G)V-u%wt_wDY`m43ExkGiQB+o~={M9Zo!x~i!iL9_AC?xyrK?W)*1 z`spUxZqn3c-L=nPfXP`=uiXr+cgsgxI?t9UXEF+Zhi+fg?WWn^dO@sqTK8O+?*Sv~ za_xRD@7=Qqv*&b;e();A4wT&sARX+RN7{ygAEN(0 za!WCKwNp|N0Al-_Y6yxj^ZdJ8mc44g-M;U6F9P$$h`aN;$odclOi*N8&?xP7b$!?y z9b+TcYdpKw2Jsx@$M@7vGRzE3Wb1*aP>V^H35AbUmyVBX=iTedx*xnOJsJFl|Mzat`DE30RekM7JO)`sQ%vB0 zTAC>O<+~Qe(HwAwGDJhnSg8y^1ohbWje8p1C6uIcxFvc`|0|^=26vMP6boZ<3qo+* zc!wgzUuZ;R@0cG_`~|`^KjQDq>P0X7VQz|KyeWYc?+qM(e#GC}FZ;*nSoX#*87Q9PXP4+%C5am*(+ zG^xy3#|+?Mw9hw56oH5tP-K(b$@oG-;G9pkgG`BH#Bxve9&?=Fr;!BPFCY`cd}=)b zR7yH_gebEsQxi4m5fw#B$RIpitGKuDK*N#by{0_k=8(~Y13^COYzLbW7kw>V>gSkzpL zhZJH&?IY)`7mO4_VyG2)HnQJ;Da_zW%=m3it&dL~Ge@BF49zz1oy;*%ctjtXOq(0_KED$dyCBZh@(P&7od}U&7t| zer4)9fwER>`qaxG7`n@!iVX0ZrN;-w)<&fP!yxgry!$H@gRyl#n8LHX z_dSVqo2-#B!kUdip)LKHif!B2deL=ZT(=(nY-7k$a76f|KV-*$H;pg4iuJlONFSO` z&CdL4O}xH{7cL~Vf-ESM4v4+wB&?YoK zITUbkq1tp__pQ(KJ5QUTqiDh0vCJVQAimK4i;29!I^H;P+(hLD9fECK{QlIp6P;on zEtZAxNG7O+#L%~YNINGV3Z1JHcm!;y{wlS9mux-kCzIPE`1!bL6Q51WF=$umAmSP@ zS50~(P2H8Bx)*~rMj3+wh4oA?ZR78caMuNSXxNvl%5`l2igKLZ<1&BPxonH&qf{%R(uKoS;yMMY>1}Ck$mhuXzkd6?6OvCx8O@U3e zn~%S@B={1INDMXf9OE383=II}zMDB)QW9MQa4vfd(B2?)WDppQuOpZ&CYOVTaswg` zwlH4}>D^~*KKh<12Q-;m+=@9D1Yr)S&!tl5q_UvAs{c^Mw-h*BqhJC*WO@r zERw}I2@nSZjha0ztXk?w>YbUyKR(4n2Q}~4b>}3v$_m}9;%?iuws+IiJKHL=N7XFyp6tx-ouj~Pl6F&o_1%MfO)mq5!E1CP9` zyjfG{n%~cSQ5|--Fs|v$y3qK92!ELUV8F+a0UTkP_7baZ+XtXL>?$oEtyszsVR5t~ z4DmR%l3BG5j+mf$a8ntcFi+;=;YCv~DPP>X2eofht1263+|L-h=-YN5e7vaYwF=rI zCE|jgoV`Sn5B|xV>Z9>w92}9HOQu*}l1$V~ChU^w_-r7T#zYBvRv<>?^MB?dpOc#) zF)Vh-3LYcEWwfFcaU$G=DdnCVD1!hX@R@Ejcah)m;Sz~&uCM-cML->n^bBYu1cVK6 zCEs0{PL5&bEP`amJdGL^ZLa=y$;cjXNiTJ93@bN{grq2yZgPLpDXJdtmjo~B#-%^3 zEa4F9>TH^(o?d!RFGX?;B2bN(GZ)KLLaG6{=~T1xsyDXV1w{As0fF9juku2t znQ|{P>oY17M5uKc_vjwe3wNMFT-)|GTT-(ip#(Tvs`9aK4fD{fN#}?JGP6~UQ>rIp9Ry5R z#6?&G6O=Ni3Dj2^zv1fSz-w& z>`~4WP=XjHGXm;E=@U>92rAe)0-B;x#_`WHYUliuQ|fpZ4P&dG--xYR%3`bTKZpxAkcO+18U%;o_6pF&tBrF6JIryh29{cMkI*JT&9JnH~{j+LE;&pRpX{YOQ5b=z^RuPx6BFMoMXU|rFt_)cfIpj#6^otX1v=sB|{ zx=h64=V#V{moRKBFank~uxkJ>0(9hs*)?M^j08E@=f|b&n!FUf9oKeS!FdpVX( z2%TbHAVO9nzHIQ z>yS0th6V6^F-5qIxhNutu&IE!ynS0SV4D?%IHJGk;>>NOJ$&S{E7xk$Sravz%n_@ zVe};^n`YN^7RR#-7_xZo4H3kDNy14L1Vs5yyHfAvxB8=U);K$`=$VH zU)fGr*&)uuIpX8A9*!W)xJ}YDD;0~kI;7?RSI!P_S2Pihxq}Jc{P|lqd}!Y4O=fJrRi(;1T}0bX?e+hIE7P&Q^DXz=>8_Xh3N^GX^)&40?HQebP#AV9DM4wnGO6`b!VnP^>JqA1l@LtPL7A6ZToaoyF*s$ zQ&Qb)-I14vc8ctFtK+N*Q>EdY(v6|(lC9TJk8Ixnr>yzjL#yvi z<`+*&-cZndm#u)25SsXma}dr~P#~a40BllNPB@D%-xQ68AY-sT{I+7K*dt?;*>~eVrY@ zy0PQjkdUCC6sIHP^yKw!Usr~3YjGS>>y8HgVXs@vC6W<_tyrsW$c?*)LES@l;`7NB zl=rp0KR)yEWFcDTxm|2foPQoOl^!#dAG<8`KEA+Gda;_TH=Ra{0o^=gL2$;_Vih&gy-Lb!2gstBH0cBU1+6rZEWOH6`HX3tDiqx@vDAJ@U+5$nEE_$X9T#2@Y%95&M zH`^lry)z^wTUvP!Cn!)qSR{vYkTdgf$n(p$ZQHZT-l{sW@&k61*X|nr?twR05j!~x1U$2owjo*<#U2Q zv(%!jcPh{RR&7=mc4)1VwybTN5qi!dO6Z)3q})|yp^NrKsn=_#jZiA5zu=HtKFW9D zNxq9u@*R_Zr#Ua2b6(HSuaBbf>0)%tf>$Z32fqLPSnVnUXlG5bh;J zN9?%6Ed2<=Ej(dE#z+%-449j-@7GmU7-S-& z9rIY^tvDwlbPjsQxg4hs_z)x3GmU!VjR)R7X2vM(;+XKz_xva%VJ!Mk3nk$a!c~%x zMnkMUta}=Lhvyt89OA)`IfQX&m-jtx|31inaHaNq+()gD1X73|fWO&}N1Jl~DvS>8 z;4uk!&cx}!b^qL7N__o`unZ&)7GFHTBM8a^8lQ~VJO<6J64Nm1a zP+pWptKYX5bGC_)_;N6RAM$stnP_s1hj{%wNp#h!tK2Q{8r`7sPB*iv0a*jqYi`Y5^?(bJ=x}V!m(d~4dCAO2LvvxVj6T_OM z&J5DbTf-n|heaE>5;S&22(~a31dY%Wrr#CWU!9{Rs?n=P7fse?80bCrAkFQcY2R$K zWNVwMhe0Q{?KQp_u&S{GyE5%^M+8)VGN|LM9j!1+VXv|^#E37Yi(LqW{XUZA3K9a= z)>G_PBE+t{{26p2Zc!Gg8W-_i?W$Zm(#=*Emc!zjSr<;-fy=WBjda8TU6Fd7DN9iM zwBK+1q++pN(&?+NNK8RD<10Wg4yUg3)dW~qaRAb!Mb|j~kI|Lm*$Y}7y22=b3t|rr z2`b}Himp5Yg%IQ?p=*<<+@Qh7A*=+y?S&piSkcdT-nM#IxqLPUET*~2lP*`SK90FI z*9-ft6xey@8&#nUU6Wp zmK=2;Ze>Gg-7yl9!)N?yz#Kq-oU_5SZ$Y0Q@I|9r+pvf@U5_7=kcAJd2kLt{%y~y8 zP4(LB5^NfD8KPcHEi$935i;XIkIdM<$*@ND1GZ3olsogx_aMs6u*F~`90m~V4EISG zg%e~))Mac4ecNl7Y*E@~t6kwjG=E zr6H%f(nZ?y6}==!wdXgo-@Gr9O03t>@f|;1>i# zCZ<`_sv^;|IScvV2m5H9ktPZ3_Egqyv%+G6t^0*hF_rbpud|Q{w;~ZdS=diHnN1J+ z^fkWB>JvqYJqT{{*?ot9s#`{KKP{aTwGtezh;a2eM8@G==s|BnNc&JS*+Pa33CT-+ zwXyB2z+R_eosNou*tO;oX6|KXsA&jV|7fj& zFPCubjn+lKPn}C4^K#mJF)><(Hje@2q9}6C3r3S5q5cJWZSgFZ;rtF10W_DJX^Ny?lgh!5?AB(hwj5`YtxBAOM$MT~MUS?q_IUE^ z0}!Mnsx@nSyt|b{m&Aua5CHK3V86J2_cq$xnG3$T+wjfzXU|vH7cag`#3te_=Xtcb zzTM<}lk%K#1+By8U)%RW#JhiA|7H9JK1hNOm`HymjM&-cShX+PyISKXOVSF+!ke3V zwcE>_ZwotnFW|MirDxv_#ZYxEwxVs(cc=D1BLzKM(j(tgml%uiMfQD7&sdRD0afX7Bc}k0gs#PCIFfK^sQnBDLb! zM;U)h-0%;`Q6{#f?uVlCjjlaZxJh&AL=_4(0Wz@{)uA#&0sQ=PO{%eAQIh$oW#JYm zYSYo%ji%>O_f>bO%1hc-TQs_Uq@jm%syWqO^D%###$io1k&2m;*%t{XG`TeY+_h=>-*v&q-IB zI8bL{sMDOvdpGUTO}p3B@p{~&p^m0IoN7m`x}`ohJ98VR&dL)%>axNO`BhJbWZ*tr zF(8>pmc+tag`>J+Ju+cD8?EO*yNG|2v>qSu6}*B~Bp#otUR?=1T+ULtI1mqgaePT$ zZS6d#bBF4Uvpb^U6t%N5#hH|8NcP&FquZ{oJCy2!l>~OJ@a_nc!-zS#3AA+M59mWR z-1|d1^9%S<*BrZ6w}ZKK?DglLc)O;fVwGGKH??*PqxZ1Df&%87{%%7r@4kP(fXyft zg|LHA1bzm8EF6d!PZW4w5MiXA04*2;Z_2=F;0vr3cD(zN8GpXM_~4k0HaWpwoC!D< z`KD|xus;Lc0S|Cic${x~y}7;k>zAw@z;PNlI{>mkO}{Rf00W7$j73V&_I^ZZ>QR%E zzI^%)ma*Ec`2&dGTGE1+FxIVz66J@_yBH!TBpcz9YvKg87I#GjmvXuE@xhAjW~MH;V;Kfl0|YfxWcVh&|?O(>CAGk$P-J5_`u7DvbH!UC8+4u z3L50T8s>p7lR|xIn3sxd4hy({K--}Vq{7(DR0jxK4>aJJ20V|Gh_C_sSAc*9h$2KF zr{l5f0mBj7Vzs@&nBnABsrp`n0b4^v`?nf^kDc3JL%;~sz`-X4@;OxZ`p}QI8=k&| z0YLkW0 z6DsW^K!F%Mwgsjv{+)qIWgKFh%mY&d5{txdf=nulS(ZE#nZi)$8_+2M?8!fmPNU7d zh7+v&C(sGGI*zeZg)_c5%w-+eWQ-w&3jFGC1Z-;_iK%$z zkbdEq;#QK+()xx&`Zb7uD>$H3CVxH1{eJ@2X_3#MYs|PB&%i6p+LI*2puGS z)`RUrQs-ooM)S!TQ|V}UZ`}+T2m*kAG`v4O;R`0y6vQcH{41+}MLEl+slUo{Rx$|| zU3$H?BqVnk7mFnqw#pJAf*jGuM`Dav7zQkIin7EQWrHj8zN)yNU6Z(`KfebF~vTa`cC@7GSWVrep3 zWaaip`&0;n+Vi)IfZE^!#}p_mONj)Wr`p9JHoUVC1v}{71_ev$6XSmca=QHPq7Y|f|I{R60YQFsPje-58Bp$1fekySJVic2eheZno=<} za2?Q^m$0xsRVEx|D$=IgrfRF^)KCK)@16Dp=60~3m7*5u6*c&km7CO3RC34#F8OU4ajGtc&%T?;mXfuR0L|tG3Y}DgeEj;rzD;xW%8vsZ4 zDvGvs)oNRR4CGXB!RN87AKR{}@Q7j?ob^rB7OqMwc|<3M&$r>`jZPigSdB4SKUt8m zq#)x~Yeg9%LG?*)qwB8Gw0fh9wnEr9=4s_o`B}z!$X1+f%YLWgZD$M(yYrmSHv_ZA zGPM=#K9TA6??%&@IhAM)_aptec(4Z~3iHti)sG;5=vY9*44~#g2a9Ig9ti=QQ3_?p zDD?zc1p9$}-Bc8INHAW1T0~B#MOuq+Tw!afhS;VppuyyVns?PldlKcmLXH?Br7e-$ zk*08&oo!KWBl#1lu@sU?uGWL_rBTMI&EMQyYtlftt{Phq7r93QiT5&ATd?!S`8dcz zFgTrm0{|-99?*|I{vO2@xpQ%LPZeZ1sn`gWu?U_%y8%ZkF>%bm<@wxZL1Om3w9`c{ z?9Lvx_9c0u@e(k&E{qnqgg1V}sc+5fl5rN+ zcy6q(hXH@nNZ>qu-~{sIZ3#tOSBv6x7Tgtn-EFH+_Wq&E)qH@@?^?k-$o-*ebZhK? zO~Tn7)_N}N*YJUdj|-M4c?S;UX#Th;f+WN*)j*PO+2fn4f9@WqySv|WxAAj!+w~CZ zy4&y1?v^K8wb-qS{BD)lemE5v_|bhTjPx3B`G7v1A(%n?hN0k+90q1r@G$DG%%Q)a z4!SajwiTcy?XS$O`6mlNq$~8#+>^V1`zsMBLC%#R=1LIfsurWF0_m4Y(ryG3$CrG^oj#B&Y)GeUZ*29a;D^h zxStTLa%LH7w2VMFSN;OmS417f*_PsS+XROvCwl_tOrBL@<=fhA#KXuI^vvadXyzZ* zj5`Cg3<}&x&v|gMHASPT%L*pfOPe{P#WnJ}%rOwF=it6li8-5=m(Gt30bUMA5S(=?{p0-xWg?KO zW)roIDy_00)?N>4^Vq1pS@$uPMU_g%JoRTY+{Jiuo(dVXIQIGnf7qQUKT)Jb9Vm69 zRy)0MwpKY?tERRFn@zTc@ApgOx>)8+rmOD~>ytGrBfKXhh| z-qq8rIvlKuNZZoWe>59&Z#GBk?(jd#4(7~2LYnZh!_dkO&xzUFZ@dPtL8dGR0(!AC zdo#FodfG@Zz&bCc``BwF5{!fr87e{(&2hid9Zgzng1NA=$i~v9xOAD^T%n*uiE>SAS=D!*zrs(0H?`~dwdWEi$E!d*u3n@if0>ZENuk2h} zgP{xX-ij?cy|{h#k24md?{iBo>nbgH?Rkhoq#2Wr*PKaO2^``h#%d~#XC-nFsCt1w zs1OGZBVnowe}bHSEb}VOvht5?$ux?VW6!HVF*rt9)M=SJQxz$kEr18h#^KXq_AG27 z001DcD#7qMKF~QvEg7>5f&Hc;cOm;P;A?qaBxcwe(0b@b86`w>Ucf8%9^QHs9FxOJ_WY-7jpUhkr; z0Q)!Au_S_-c9ZMr-ip)SN=iv+_F_f?hn8pZ_hlrIFv)3FLW>Zt3k#oStwt|yNgx#! z0hHw;e=Z=`U{Qr9S{c>jt|FLmex|d-(7a}8$!Ebxb$E(p3BvHqovhhmyrXF!;;vZo zNHdh(f8fYQE*y}p*qPm~MIN8+0pw*dLiy`xOokn=z-65#8^Bf7#CIAnp~%Z8laLak zZ9eDqpC~iPb8Ge_vm&kXGr|7#?`TRRU`OT4xv6Hmi|WYBl$TE@T1!z#OEfvhjk(jC z4vziO#ud+GZ$bw7yM4cj3dholRnPJfA#XBUf8E^c_0V?Fqz!PJSI_5xBG7CfJLPfV zX(eA43xyEy{T%q=q?mYdEEE;sJm+5{7S6;8u~4KHXD^C{LU7!WFNlSIU`x(op^Zy? z6bnU>rHru<3x$h>e>08tMG$39FgUck$EMvI9})pTR;E!tA06dFCun&xP=Z1b$RQU8 ze{XT6)Xf!^O2CEZiOroJ25r~p!ex>0g7Qlk*!AGeq3wIXL1V!YCpOwfF5_hjwD}~N zr}TX0N>y5x0n8qV2JL2y7-bQBX%w-_sd7B$!Es}3zvk}59ne|dje`R9Q0w#c^ji~-)#i7tELYYaq1t`062iza` zdt1i9oUbaul1eB}t64QdW<&KH?3}ue9Xo?;f#>lKkJpf%;@-5NU z0JSnL0WeUu5~`1CvE)!UI{IA5$Vm!7WT1l*ppui5oSFoDzzPHd#4y_4C^I}He`^-y zi_F4NeT*%crx|B2G{WDt+SfEfmi!u#4B|cnPDmp%w^>afl0Z}zq+eZG@mW3fp;>ZR zLOsJFLC7JQtxp;->Ae7w2uOe`4mQkz)*&;b(VaEoBGInPRi6BwUO+OdU4x<^m!N4P zJ~rml(Xm*!+Ez0Nk!yntA}0n8e*-Fq0Ds9s^4OWpQm|CA`H_L`ku0l6l5YbdK~1dy z*?i})@Sa;Bz5|q_%=Z`*+^lH^8zQ#0qX0}OV7N_*=)|BpuFGJD%>_FY&+9~~o<$mn zsf>>_a~&er0+{J#v!BJdXX1?Ny9Q;)^j%aG-*8~-I#G@x-p*S%!~w#gf1R+Q*j9Q# zj;C)Nh4KWUB`PwEBYDY_L)YS}_hv(1R?h z1_1}qzmDnt`Of$bsp@pd6ZgJ>YI}wFa<`i&k=Ij2pwgK%PtV%#f8eJQbNPiGblb&r z;=@ZQCKU-JQCQdU3Y`9w#IszcSuSi3UY^Q;=NG@+qGB0OIY14EbVPVq`77?Te*BE) z+jgU3?3B(6nVt&puyJnz=x=FfUMv*gVKr%*)v3rrB)y9Ryf~HEZ_k3u^djmmTnCNA zSC;s@n2@cFoRVO=f0|aGn8k$r(8O|pWe$}E<8o?;Z(9f(55sjd*)HKEi&Nq25O6AP zY$f;M1ku-PeHf@;gADF1`XKs6m$tV(p{JqOW*=Gx)1`=TqSE*J7GZ6+PPD62ayZVA zcVZZht>LI{6z zojai~fV#2-e;_Mg4t4Jy#sK#95ssyj7tbIZx@t z$8+pP*~G|JB`}W}H9uh+QaDmMzOcc0YeSZmaZJZH1O$HC!x^_I=dcFed#u4_9o8Vb zmXdNOexy56NWz~boN@9`y0j^R9EF^gR(8g}*%%Axf491GuMoPGW5DQvxQy3KJKt8M z_1t|EFY0hJQpnQ}RDcup9t(LA^GCIASH|o;b$gi*C?-Pey@Hz-SVN-zC^b7a{qnZ|)nTSYWvB zrl$W;f9OcDTR?C>UAd@xO?T7wY8?MWZ#l5ne7X#=2R?<)n#8bb+`Qc`Y!`dV5kBaiag9EGK@u@$zY{&Az{Gs zf4gh;djm_CN-sVxrCu0dC?&LkP_$KXzc(F{)Z$P))7U-F*_d}>sA{vJ@p~Tbj;5@( z&sF_E{ep%|CoYhjxIBS3C|tiT_RoD)7JKR&l{ z@+g6CBy^mUif$oHkMyGI=zA>M&Pon#e=9kBzcI(Ysb66yTl98=C|T^Qhh4vvi$`M{ zmgb8z;@DFAv90>v)IR&~P4C9PD!Tqq@c6q>hio@;r}u$teT_Cu#x{&{DH2dIB;|H} zf9zi0-gecYe=q0|+!XH=n)c!L*f#$JV|TZEtLP_vMTXIMACOVP$wxBeQzE|ue~z0| zX*~pbW{X~fPEl5-?wLrgh3>RJ6>N2&x6P@qYPWRTwA7$uAGtL3ih4ths^=9O(^hBJ zV-N0xr&+MdG@XZ%B274u-YKQMX`s4BWC?7eeF%KQ57*52YCVDk83Le$8e;8?2ay(G z6bIm@q0R?L_~o6aAThQRMs*$}e?W^;((P+J3-kQA1Zy?z2Gt}tI%7+$aW)&5Li4RV zaC<6O%XIrT&Bg*{xroDP@K4^{^DThLICeAcn#1wbv(d|D&&b1OXJZ#UJOg>uYqk^j zD1mKLgBNxrfiI+r0bAqD$xyMB-pQ^aP$fga9LLdJQ}^bne|BF@95)5Lk$}q`*hC9)yhPUeBFj4&f=?R$bpB+|F%9^SqtDG+o(NM?Ab))=4U2 zIau)90z&doFdj!rz5u^SLD)7l=I#Wh?hKK~cEvv06(U++X_!S3hD`6Z9aRqy@^x^hLGD+W~vsbKMtD zG{s7i=m7(f<{yXK?c3A7ua0}>cmO%<_3Ux!ca`-{IBHMy_h@>{_8i0H)CIfyJv+&X z?l4UTAXsz;7{v|YV%a;89pCOm!8^zWTUAe>m^3U7M>l&oLAn-vf3(eoN+S!lD*az! zZBCnN09FYA=ipXn5as&!gO2z$7?K$=Eo4vZ*b$Y#D$PInO8R zhReE?vqCL6gU>AP}hT( zce7`$5isxW95Sp%Uryl_@$l8$W*}({e{!DMS?sHSxu_!vNXtlK$Bq)J7YDNmFSkeHjc=HzcG%_>414RhbyoK$h#YMVx2873PG9lt|Su4@;3SUwqft#1XjnyP~Jf37??hybIe@KEOQBJz$_L zI$MI^oR)dje+{#$4U{%r(LOKXvVO(0I=3NR(5~)`gi;fPA%^x&?qN%3v*HBcPx;i| za^|uP6ZoM@VQ=OtSC5hms6@Hu1Pa&W8sifiF{=-ha<;OMr+2@dIi$*V2G!%*e*-}E zA@gd@*0e2^{F;&uSaHu%z~)su2-GeicUzrb31-Yse+7H$MQ~jl%$x_nxny$e0r(8? zqcbvigV~#d(}FKGImvxw=xYnB_y{?tLU1n8>ZBrHdq_PVO}(K<4OmqWRj%%fVQN)x z$V}9w!=Vcka@Se+kD)Eo0r0O=9ZeyvCtAOWbtJNBbW#o{FXnJ^lm%NCgwkFve%cvc zSK&mPf3;eTfx&~Rq2exS`25~9N+9Iou4sGHRRuFC8_0$#P`(B{=!n)9bWf0QE}!+@ zucqm+O_x*m(o=OL6H?B$gfoHr(5gF&d6~%6fO+L0=3Jf>K?-@!DR=|g&-w~B&{yz# z1Wr|X0vFu#2>AW>w8tVKO%`v6#z=(GFr-);f7XC1S^|I!^2Jp7%1^>IaSofZ!&*Xp zvRGn!<5xN8+F*vsM=)NqvGxP%Jx@Ni4Ib*piak4Z`5lbSRUtEH8%emVhRlezxd`Ct z*oV`YaXHC(SJ=L>`HOw}yIuykp&(6mIO2}(u`P~o+U8Wx%A;eLsmJoz)B+PCC7nPJ ze`X!Vq$M3pQS+-NpDPU8K!g71e4*z8p!zeuV?C3`Qm=a`;!2X6B#1a<$dT&w%+e?Kdp zukt@DDuYxw&%N?-rNeOXZ|fnn!1oV(L)$qc*CcL4KT5Z5>>yA+kNu1@{ z_W7j?d+2faE$HJ?SZqJ>2qNZaO0*htYv=CINhp%^4Z=wHgjhn9FX)5RmPvnPrpoU| zcF~m^bsyS(%<~J!bIfFXdKXk*IVLgPL>A%{-bnE=)^#{?@ot%({@DQ;s0D* zuRgtAhhqk-IVnBf+Sl-Jro3Ls_E#&(LQ0+|)o;{VF+;@+)tKSs|C91qq?p{qP~N!h z;@n#UVE12Q0I9*3VIKn&0ya38fjAQ<4>mOlFHB`_XLM*FGB7kVm+=@9D1W_KQEwYJ z5`NdO;A8v3C5N0Lc`yPv&Ls`d!v(erv}fc&afH^_RB|P`NdNtPLrad<(t6jDd;zR* zxkGX|{N|e(uJ^*m8Sh0*^oA&#Ec%#?4_+H&e9{JfLde=vOys0J!En)@6pe&pD3FmH zM(ALZsJ;=CMBj+XK59oYnSYBmoGDHh&Y0ZY3+oT->Io85bd4O0k9FCM;W3pFMT}z7 z$ugrQI-BY&-WiJM7iR6k@N~Zdep1vuWXP7FLksrmpfCC|TG$Hu#1K@6{)M2j*S95L z&br$Y4RO(#v1dv_^(@$0!j>qaD-#9~R-~-fBZno558A?Xg(1RZf`4b@{# zaH<%&3=882EioaIPJ%rJhON+o{RKY+3k6X#L2VNfmcdK3a@6%<(3G2~yt5>@PbFhUKgx(eacaSh3Zk_L&8J2}5Eq2+G`{&o?yNl&`IXO9LF3&%B z{C7PzzBxNJ{(lwzjheT!>C&8>nC30CkD!-2O{U9*a#Njo z)SOQiv%C5AWN}YsweMe(&o|@Ov#;h#J5&jr;zukro_}LB1Od(}csiZVFx%BVovJ>M zmaPJ#=Hl+tvOfQKGyQ$kyq?WJPv&)U_p$k*dEcB}`TC&xTw^EEM_Yj#ysds8*ov}a zB%H25?z9^A!Zhz@motMy`)+afX@S8vv#E{N^Y?0-%_B{IAgVS6A5g{Cm0_}!i}j#| zr-du1uz#tc8h~nHfiz4QQNyM{{VI5lR(*JXU~j^=1?&xww(!32^^~w~#KSlU z+194pQ?Lm~F3}+p`Wi+xrIA={;JDN6uWyzU`+7c}e!d&eKi{ANNQdxHTOp=o^_Yd= z(toHUI3T{G_Q0R@-Rk@>`)fQ!1yYXBh$u`z1L1)YVU|wQ^f6+QfsD8**vp7Jgu5AW zQ&>|4q}DY8r9skg7L+bFgfvW#NX4dH1`2zq6Jn1r7z;(9<&=-ap)C@4f+;ssZYY%V z0|}#2$)T4}+gyD(*^nz+WTPeWzGS0S_=iC(O*g$@-xOTom$S2aS2j#oBB(v} z2q(HH|JXMxihQfrHUa6jlhPwiN)+PtLeaWh`jsFYZpqXysFwiQzev&A?ZYk3Z{NnW z;zUO{Q3Zbf_ox3Vrc{Ubf9Tzs4}VXS0>r=rXT9VQ{5CmI**|1ZK59iQii8Z@APH3b zB$R95;E=K{F6{InyX7@&p6&ITmY`ncXDd6M;E^Ebh&)C51tW^*`1pcn@A{;TvQ7AO z-4pH|L&A>CB0Mv*XxU|G)DGK$ICfo8?G#Sl>IaHJ!k&?eWEm(Nl2!M4aepp3yzHj9 zU4`mh|K466SH-7(S2&`(vvZcT)&rkQ$*>3_WzC?)JcR)gf~r{UU{m1&0uc ztk-W)NMA$Ad&TcKu-t12K3onbWHxc2FkmkS1-j0wqZU%TKRdLeo_?d#kbV$~Ic%et z{Xi6R-a;|EV}e&N?;~P%@PEbXS5C44R1%OMmEE_clRxjqo!=bv1KcpEYznTkw-PM* zfwBoS#ym_I`?LD-aG0=Uq=vain1rl`m+0B*SJM|jY`dar!FRJZZ>MIP^?V!U-+;Y0 zl4S>yuT?` zav!R_pU&Uw-*>+)m$!?5G|l4XkLB-nHvhG`ozFCtT{K@Nx69e|`wqJ9R}l>75SoN? zrDvbCJg0hb$@KqF@!1R!;1FCRN`P^}5nv2G-w+uQg$6_v+M)>=N)tlQxc=B7+iy+{JZ$@dGTXUzE;rtF10XLVS$`BL*HkS}65h{PRTT7GMxDme3 zui!0|ZDH`@Yd21n9^@iYc=Xr! z&}g8^=I!0D|0cn%y}`jQz`+lvD~jMMf16!!`t$1#H(zdu{1cEMp+THxh%p|l_cy8x zWf=|k|LK1vLNAm>&$p{PAb=7ux)wTNXK7W6dH#}SkU9c+_Gz$M% zkSG+DE-EVBL=@eOZw96tdUXLtTlgD|96fw{^4E)t_;M1=^v-GQv1y zh)}VlP)MMJXIc2p;%G6AXxpN$3=uKPSUe^|>&`N*JI4T3mbFy>L2OKoX|WNXF{V|~ zfxuQ5ZI#y0tEhiE(d@;hSdcL9jHo}Pn7lj+)4IFQJAIcQ4kGWn+FGG+#;U)8!kC7w zIOGjTKGUfc`(mj^hxNE3J*;(If|5vbfy0kdpwyH`*htU!hf=)JB?|adWr4qwV$aPC zkJ-y5BUI1DYkkRItw#S>s>%1JQeWPhe`MU#wpxu^t;T7k+y$Z zIvUfRntc+F%v+X#$!v8^Ug>LZJAo* zat2Qbmv(_SQWJbBYom!(q+Wx+ETSkhW;mqQ%mt4SK66Dsi9@HT$1H4*heO>+2P^;S6$&@U z_9$JVyv-Z%q}L1GVXt5NNJ>*D~~WI+|XR$vu#PMljFJ z?16vnmqwY>Sb0h#*s3!>xRg;ul6Z{!>B}*1jE`>W+MxrduoGtd8+35+M=6R(=7~QV zqX@2Q9Ay!{9`5oxR!c4)$=0ve*}U&=A9sPz|B1cN5I{fbE$Z!v2zX z$3{6Fus*3nWL(b#kF%Azw`XvO`@WV();+A@ys?M5S)|U^>~epSGU9~3 zY=7c#3d<<-G&KptiD_!~r=pse86U9y%nV^a6_weX)SO)n)wzH6 z`uxn+&p~a(5lgryYNHf!mf3i!ouJkSY)|bF_I=&@A$PWh4szj0lG4Z%xtyca46+qd z4#fv*&+P#9lUV0A`g;+zvlVnuOJ!gdd!iPC7{-aQ+jfduAFw^QLs+m|U-Zt_(LpcN zCp7UyFG*06nQ?acl*jb}+tWLQy<2~z7$Ufx@WSwHH609N2v-tc3}cQcr`GXKgj`-= zdxnRw@9WMRzq6IRx}im9iVmSq^lnF);Y$wPw|Tubl>_h06zkbE4}w1(I5W;cuF z`IC6FmC>?ui}(t9|cbL2y_v^JYQP zaChAIBp3gOX_!5f%b-!pNTy{x9W*ka12bQ1Mm{CXPC?`S#9aEo?dNic`_IRNXjXNp zo?lzve|;im>*3&#KxCDAiVlC7d{)R$(cu(_K5%;uhq&h)8qa>6#o3xTScGFz#yo|A zOg<^hvi>kV#i9?~p2Z>VIg8e1T&HoiDh{szGLmT-PkRLlC#o#Cgm7fezxit7 zyy6AcPQ?iJ-Kwq2V<*nurCpzj`KmZrgcB2Io(|VEB`CtozAwhCuA6@eCVfEnOb($x zmQLWFx7olB-rx+Brk;+=^4)Y68RgfaC?`nsf!mWd#C;FA@&)E~+GayLXoC|CW4>sM zID){{ z38FZ$i5)Uxa3zXx1X69IuP!+prAa&xLtw@z3E#SsNl1dCs82j0CY;&2fMwH!Pa?x8 zZM_>!-V)mcn=CMF%uJ@|JrwQKo;!O|92SK$6lb2^?^5{$Gctckk8LL=G7P-n_6Fs` zJ)e#7guTq3k~#L&H^#H=DPd>!bTXH}UbCokdz!RjD&r9LeAK_W7y%il754T?y(SEL zwozOfG|6H_xTgS}Vyv8yc|BH&^~6JPFUY+~yOA%PBv>QMo@3P0lRR>g-(Qo_o9Clj z2IcJeGX8WgF3NxT)x~wWVor~`ZEENM8E_) z|4iUYT7Syrt-QEIjn%QDqYhEBb>8&dD6MX)zDK`2}=B)2UCz|#--y1N77_mV`Udac! zGSerC;fTAdRnnPEJWZ0Yk$K!IB@!xi7AlmUWiTfuJs7U5`dDr9rVyroUTtnw>JZee z??K5m=vaTWI++&g+e5yF;j|V&W%tUqDisE!=V4LVXbcb^42dNPcfoN>4oaszR6R<9}1+E0xU8Qmj9t zfGSW&$ynF>RZ%(Gx4P&7Sk*1fgY!qL)=ZYL{##oJ{WsSa72l{ta;jKW*Y+UR#nu+y3-x#(ZqEVhs(iF} zYtu%3q#{(Z!%$XnadX0qi~UOu+=0|pq|eZ6VXX!*d_pMp|Ru%sDEZ5o!| zgNF&${{!fd2)>u${0@_THTY|wh@27zd~=NX6|SLAPCZL zaZ@*KlbJL*Paf(%@Fbjs2}LR-<%{yycNe>$NFC3*ICkR9^hx02d%u4Ry}14ETd~-5 zSIJ_tNEUy8^!w`e>c#6!E<_R+Ng)=u_lqJ~n52l46u#Dr|3q)4)XV?g{_`|9F7zUa z^M!wJw4240@ZEDp{O$JYrz-)=B?|$YOW0Dyxyl!--4zmZ5lfXVL>4EyShRL=fA#O@ zY&^M^8DC2zXu%MPWFV(R!u&5vZ;MV1xo__nSrN%ove%ZS6uCmuWrlsFa z>(q8B$p#X2o$=wF+cQ>>fPIZ=%B<-Kur_-Zl07!U-tj@y><+En*}5mf zebY|X%TRvR++tJJgG<0o>DUu?mNkE9p(;e=?@-9-&{?M39qE_0g04GPE=AO#uKMqt z?YGUkqfvCS@$h>%S%ar|;29#?A6ifX+r`TpqtfWBvfVYcTT$oRM0*Lb+X0iM2AC=w zG>fNB4jo^j1z1%oO|+e?^gwD+b^hMT^v0LAF>~9%x=J&%pi#NnmMyhg+x35K>FU0t z?@R0FPp=QWr-s)9`0X3~O{2~R!j?zuw@V!zJGTPMp}BRKoKIj1}SgMkAh^Bi9ch6` zY5pEP2o4%6YDWVeT)z#SsL_Azk?3p3#?z8P2)Z`!hK%PkreFm?`MKP|Hr+M5Rx!5W zv&&Vs-r%OvB*e-&ub;$94sPE&a)bU0x7xJUc7qEy;I$KSws|b1TquY+gZ_zZZuK-y zb8thGk*FBB2QfruMN|?2jgUf$0qp=KK%>PDmNgCyvIb*Q@OkTlk_mr730*dg^HIx$ zsD+D%^`JAX2js9GITOeU;$rGHLEPRY4ZbM|CugMuk}bW$L2E2`qLeNBu6+wSLjjYdXoLRpb-KjOVV` zb5;aSvs@qRa_3gafAD{km-a~K_mG7`A4h9=&w-TQ2O}hfVC2Vjq1RF;Gn1&RZ3CWD zM7)Hzp~+~@Re%(76;Cd!hMMDT$6|f?v>TCOj*=4mM%gv>^<1(7F)K~QqxA0FcvKRb zLWW`8wmDR5+GS&F+XA1CwAGy@a^28x1#VpAFsh~gep}Yzcszd;lpdHw+Qz$*Z@Y&XX{$B2Lh^w+$EotF!rF0%99rW%eLm>kr7+f?+y@gNIA^f4fRw9=tFFuUjs=t2AGvOi*cwRV46 zcSg=@$aF9akCJ~i_B+#LS#V<9H6eK}dBPA*=rgz?eR4$|eR{`%jeXmoGk)jRmXmAt zoRpM1&b=YPRXkxFMv;InE1nwMO%Y22l9DpkBKtitmrisnASf{A5)zP+HlG4?X`q4A z`Y_N{H4nCZ)f~`7j=vFnzTkx|3+L@m;Ip)=5vAn_lJ7ro#rJVc0zj>kyw@w%>8nNxr*TM3P{&kNxUC} z4ojeiaaIvh`bq-LD!a#u+meS5Ifn!*KKWe^m8ftPP6?qC-a zIhGm954cT%&YUFazc7Wd@do2mDndXwH-z)};LwGy>})P$x=`2K&zE1F3dR{d`pf>bPqAJcBMb#7dOT)#~s3-x{Kw~_aazr0t#fhoF z02?6hX<;7Omi2}Y6%gmh3PuS5I~al)Cd7A>4XnciAWywakX#~Oq@`TNuFsH;b(TNA zw}XElnN6GhLTN1KQfI_N1?2b@m^wJGQRM`Lo9W0OXGm#bvvJ}ApS$u%2fbs$S=M35 zgm45yDuepaA{M@$%alk6IpjNgNO=g_!YA3cn%Fn>unclQt@r)SuIYHjzHv3DY9x}} zdjk0R_M6w#00*$*tda*%67SPH)|vd=S!sWxqJPxqdzU>haPB^AIiT)7xs)JI&q~R~ zAtWF}{<74diu4T^-$PR8?p)>iBhipAILSf|XWKatFLE7cDi4kVRiyOjXvU`q$fe{E zwQP-rHQpy2Y6?kl>vd!KfOW%H*);UqxlQfRe!(;M)se>Ed08DBw3@KAH-DJ`LOFl0 zWlp2zP`|*BiOi*@YMjq?*J}b`*q(EqP(>I%q}_sHs$;yK9m+rz4Vl*_G|H7CTtHmkkDdA=(tV#uVYHBTPg z1}O3f1xy7KSPx#a=R*AqXCBJ|bTfaKBSEacew-)|Y4BMhCu1Xr1p6G2NNxPme*h#= zGKmvoeg{aRq>g3&VTk0g-~VBVq4-JR}nmKuZlh8VU5=qbC9cYH(m>ec%{L~}^jE@YtJtqE?O6D+2p1q$V8c2nL z#Gh51J`;MQ!6xOTsldx5s@xEjXbOOQ-|PU6t*GXXBwM4ht+7Z{0TF&?8HLkyA}o1|M}> z0Q0`C0{y=DWI~w%8u+p$qIRhY40mag(t`yI^*9`d_%|IO@Y6NTZ-_>f4l@))fE2`l zRN~;iax2#p`UkdWxuAbPbx>iB?lF;ivnK$J7@r}c(F_r>f-(HZgE~$xIn)m*3(UOp zg$B@gtaluEC<(u#ab2^sMD}$_|IUtd+wWI>XOK<2)+-S{@ zTrkoXG2r(hgd|*T@+Sl6#K)hRdzE{TYVd|Vzb$<}Z#xjcvPBMoUz<;wkwBzO(?yZQ z`d2>gh;c&l<|E=MOh}4CTueyPM+u1%9M7CQOFRKjEqK#AsGQQ$*5m*M;l6qnNz5fuY5GdP#=7!oL#;K~pLf9tpre$TJaqYNDL@J_KP3hZuA zina^v1x8KFf8_3IJ zd9Dx>e-gBL$--85c@yOZdgoDaP8bqg2l20p!ff08rZTfR6*#?{5uE1L-t4-u=)g9H zBaKJvmko91QhmvXI~r$l7)24stQ%+B*clP&UAZ*N@b%3@_-${a*@fL~ zZEfmy(wL}jWX-N<%57WPdeQ{R5$i4Zs?ICBf42Kw9M(>)gCvOdzPZht<+t|UG+*0& zz08}3NpDi5sOmmJPNWA$GN)95x$YMUB7@A&l!}2EC=&@rS>hYbIvIBSc#gz}#nq=P zXE{y?m`7pm7)d3PVsqs?xkNhC36Tg3oirv{UHx#*$WLROVD42)E>NbjFuA|as7TGj zf4zf-ZI%Zg6Hq9q$GSkQcbNHQo7c#e+YKpnDCqLTf52IvdF6{zB)kIF|O-rXC(Ek2Yi$%L?|7)E-!$B zH+Gq~PAerINp5ohn&6qH;lV*8yl-#wHnf&DNYplVICr+8udF-isJ5)jw#=*Wf40f% zwL!DFpgjF%-!#DgFas&lckrHR_^R9mN$VFis)!cscYbp4)`gR96gNdYoZH5<`SPL8 zH)Y{AD;Mcanfn$8TLt#K6ZjMOCNzL&;7f`4kko&2ACREL^9B5VbZ9na8x+DKgl@YE zzhxT-y)COMj=I|WrEvZ9L;5s`WILRWfy}SKn;zz+B zUgxc;ryS8US-%QXOqN%T0e^*u9e`*=gUi!QwPU=m^!D7)W5 z6jLC7H7;gf#4*BB^40D5mB=_ z!5F8Dnc}cR|80uaHW3YW-){Hq&TddaK+gX5Jh)TeIHLgaF?`R&>$y zhaw8|ioRtyReGK+qE4n^vX8ft}l0w_V7e<0|)}& z)8~^L5CAd~|3Asid8N^F*-d@Pf`?|u$<4&zurCA|x^uUHrN3^>r@g6*$@GH&fR*a; z6~d8(a9_{=V;cL;J*qBt$wQ(L9zz&Z9gv{sIJ0oiUH^Skwymkde?thavQw)fLgyic zAsOstA_p1f0lY5%=oa0$k?veNWcuW4SoJXk9)5vKGSWMH*P3lt2Gox#+iJgwomGBg zs;&kGI%IJtv4L(X5#zn?KTa79d93QU1td0RN)a8{_@}9P4D^6Od|bmapi-%IEMmnQ z6FCzwI*>|7}Te}X}XaKLWjG9O~Z(Sgn3 zfMx{q<3Ip40H{D$zm91}@}7^!Y&`TSC^`n7zm6l^;6LcWebHekq%Wa;{% zbj`^Lx`sGPH2pmr|9>pP7H9G`^Cf6h91n5G(IF0DX};Z7;nc;wsQrl$v^=em?hp^y zE?k?y2jAvvcVt$2+~_5`Af1~PT5gt@Py47q|9RE^W%6yNj&hQ zn4}-e+O+;02p$GN$1xhDS1-3O&F8J%_~!V}PsApH`3_&6P(prVlMLKTJny!g~H-SYW~ zFyPt)LO*Puo(KPRR7RXCpxEqxalJ>RK=KVP_lSZIfcIVzVi&f}t83d7=B+RHrVhEB zF?~cW%%y^@=6^`A6R}o62m#3b9&5iyam10*Cu<{uvzJ6b&Dfwgl3j5$BWa9xl1J8- z2athS2QujOAzzXXQxXqL97+5|REgYenAZ~25%=E-ht4t_6o!+pj1BKr!x5W~S5FS_ zt=;&L3!R-k(De31NCWh26qtg!e*6J|uxtQRNGp9&Jcooi>u%V@5X%tU{|f>Z zV$_#`SrHThFgBOL^r$g0@&VFkZh1myaMvz zT?EvyM`Fw&XGxCb`TJD$jTcd})`pEdlcbnnPY%f`+Hv6{QnI6k}vul43$J1a+ z_vGg6etlQ%y1KSs(v+FHd;zswZVLbYy{T*W+_k`Ov!!x#p1j}B2giXvVxO>v(qK~) z7IEyVw)5*~x4&Nh6*i})o8wv&&U4ti-PgYQxV@B$!d~hRMc4aRX7*4iQHq8)i0`7O zT`mRBl1s{o6uIm6_jWMft&M-iaw79Mf71?r=gt(;8ntaqGx(kNr{l5h2KR8dt9)~N z9ICb<+e<<9<~p3t@oo#|>#JSiM>{pu5D#uS#^iu1zjIAz#$uYJOoYXn#&lb*H@E&U z?BFX~6tG3Gx_|5C>c}MJJoNY_m8r8ob_HXC=P}0S2F1ysBVDyAoKSzNXD1XLJOP&@ z8JrGdL{jBvWK7O_!B{d$NtW0`cbm)`-ae!MsymTx>}8Ao`JWBMNGeGo56e> zzFWf;0k9&Y&yU{x5Gh>8*}$)MJ98Y0o7(U310G#bpG?0BAvu31BOcwfZEe74Yje4d zv#Gu}`{Gm&i+NVJq!|%uJjHguU!BAEvXjU#N5AVT3s9@;SAy^{T>r9Pn>;7Eo?ElO zhLgYQ%x@>t?9OZBQt)t{N3XK(AhMAnUbwm=C@i#t#Yrdz2ZQ41cu;AZ@J<+Q;#{_F znMr7Hj?msa6r+C`#JOIe*iBXRj=DJXwBXA&_gys%rg5!6Tei{DD4#n#)K5)mx<#M5 zxG}YB18C!G24zeUp`%Ur#lL-U@Rlv6x5@Z7TQrN)VcDFKL>ln;*tNfzyATgzoh49yk%G8i-ylKuEHQlXHn_ zL0z{P8TVCl>zbSx?p?(+j!12J5~-K{xgX5IJt)tBT-6Tn0;pbW?jbP!D~0=+h9B0e zKD3{XHSPv0hzwk2R`RV(I4&B0?uzcvHWopk)*UsMfrsL(>jv^88 zB@ysX5&>Tl0V)t4);@xNpdVL$k_en{>`%=O9c@0z8}JX)SAki^W9O@LKxGQ~l$xnpd-_PS zrUSzqT*bV4edS7hb%5=89Kr?{!;(76UV{R>BLIUbD+dNwvOJB29t=)5{&|p%SjKUm zX$;CB5sM5S4(wl`bNVOEqHQs}_u_wTH{! zVomIK3Tk(f2Q2P@DBk}_B2)RT?tlCxD(A|I-LH8C#K5sx!UZM3EuVJR{f4Rj%HoF_P-29K6_nATKhaA7aQ= zeL_sO@^o$J6g-xz84tM_-=Ig`IPC|ijqzFDR!K{a8J);^%||&8oh>cspr^H1Tmb|4 zLn}zl_gEs!TpJN`0 zqc0-koX}i6pNxM7TqujqUJp==O~j$9@ENB-AwJw2<17A-07N*%@a&qvR3?xZ9rWAkQ`wu6WV^ROzgwv4gyT*Q~_PC}!bnD$?m%{oN)@Va2l1cuw_IyYi zlqeDHerQVsU(Vefm|ck(hPbS_*5P~%zQrK}(0b`xHhBOPUV6Dw6E9cNJ214)98gK` z;wt1)N-iZVJeo;Z=wT(SQj<$RT*1lDV2Q&`iTLdr;V6H21O!A^siJyW&_FmJn#W6i zERM1SYe+V>wW#r4#{P}Nwu9?;jY~eUUaWo^V1RVvm$vt@izc~F{S|H|P%~Pxx4mAk z4J2(2JLz@3_BlxtA!8u?(f3&5myGx|=D*{5G|^HgoP;ZCw)*jchzu4z_CkVBnZF-i znU+I{t<8Ts`;wWleELn2=AP2A;9RLb`D(lRF;r0k>D`wJttAr+iJ57R(g-}~Tj#|z zO$p0JF2>7=uffC=IA3I6$iz#v{3TQj7{n%*HlL*8pZZ-@*8!B=^<&kR^GrD2hAhZc zPSdJDp!@zYx@776`}rgPjDUTrubno_Z@`z6>!B4?6QwZl6?mr)eK{Ak;Klz1*Z|-A zmw{Ok6ag`pK|B!@12i}@m+=@9D1YTyOOxET5x(!Q;4Pdg4U7jtf~m?uvZ9pYs4BKM zC)o!M2eZpEA0s{_Z+?Bc@fvc5E3J36s-$w60U8Z7(CEj9=6BaW{gXvE!xfEgA{zZI z{J*-s`tD7dMU0Z1<}A8CM0rklCZdeygeE}QNAKg;`cO>uxY=?^xS7Z)bxaExTgSC!g2*KILWZ)hj$_reeq}zNlnQ7je&yHt7fN}n z2iO#2@p!9kqiS_ORz+=lO))rz?r_G4)61~}ag$>?7BI7{^$YB(cz0*XgC57Ky*ZoS z4P{l=1@6|()_v9OFNMKLqJOR1`{KN}Mc;I7RRXKX!g^hg{WLyweWUkw%26PGmyx4Zc$89&&UZ9)ROy#Ym)J4Amo!sc&9EdKD zGTs)T1;N}FvGMM;BUFu{Wbv>8h3KR0jGZ0U?J)IjN>P?mUyQC-wSUlJGQR1Zl97mt zor%d}!}9y6+dZ`6y(M~O{AnX4h_!+~Oe^a&9n#4BOwu07>WE+H8Ys@FpjEm5vZ%`m zF3(&T(qZp?Th#TP?H7YJ=#0$`n&l}0H}e+#Tj0q^o>9Y+5S5_WkW{3W>($yyl897A zGp=jP#pJ>@Ng}%@t;xAuaKV1z!ikDZqrZukgr6S5@z?9C z4_By88Zn=QQaFiHNmMphhRy|{Sst;JP?<-)jt*BpK1BHa*^W^-7pOdCknU7w&-cTI zgEHKUm9Iaj+yd^LRwJ-^A(j+W=dyjja{P=p4 z(HO*Ph>|9d;+-B$5`l)b6KKrB~ zq8BNHo6MIs`F#iR@%M2RKO`9uGWCm=UH!4>S66n7i+_b*mZd(9#je(8P-R#}6uBU2 zaNuJ%K#<3qx4z)jR9203u!|ko>1P<`b3lpT50v1h01XUd;pUFBJN;?^3M_|-`zILLeBiMg@(sn~rrL!-O&nv~ZGkv`7iqUXtg43BhzNt@vZ#A?ElQ8GmWy=$e(HgTulEf8mJrQvWKA}Ca7#y1& z8$B`_EqPq%6bM$6zVMD;^mfiyYJG6l>#evN2k%A);|w$3 zz#9kOI8QfBN4? zA1`*xa!4HJf=ly&F@4`ynmtmMW{;F$_NIpxejGy1IYB+nQ@9=j_T&lQ&=pXa5|)Qh z$A3PL2v19`CprY-^7Cmf5sGk`EaKJwYnJ;=Ie?L`SPsZZDnqb)ix0XCqOXZp*z*5v z*KYr<`wpTv$Z#)5pfAl5DRW4K{m!i!AQ5&Z;I{$4(?)_gGiS5XB8t16E>4FLQe~WgbdNLF68!011ra>WrG3bvsDDFWmF@+MJ)5qvX*H$drfR2QZ5K?W=7IT` z#F9gl3m~Uzw38JoBLX6CD%iqvtZCL=S&es_RN_ezc-FgIq|(^`16(;wwQcWoSwJ5< z9%}&gEaw8{6l$IvEVpH7Nfm>~o7z#N$p{@OQYlD!!XopI-jt>oOt$#S8 zKTK6!?fPm$R4tOYw{~U<7Qx=$$6V}$EIPb! z^`6d7uB)aR9Zxlsu1u87Yyf*E&UT<2ESQ;W4#c7EaMe$%XEBlmYSA*at_MH~x`%04 zgcckcV7~|wExbaCDNYIH3PN3ZTYn5AR>6?ecGch};^wNh>~%2&sn&U+5ddRbI*M^t zlm`&H!UeGeh=c|f0Pk8oP6J0DW@zWFdm-<;X*a&GZEI8W$J9f?jQ?K%jf_VE&{hhM zJP$HR4yh_hiDF5B7-vh&<_p6vGD;F~Nw-FlCV-lxTkCug$Y0pRzqO^7+kf#(C6M+w zd%%Y9K#(KAdBY0oo{d~gmXJ3opu9(@0E+dh^k)?x>2>=2>7l0PxcW`ml z(PvK#O54E{CQs?iK1GJr>%54%gaSN(KB@>g@;B>=kl?2{1nPgw6lH>{wo&C>NNkXk&_s@?ZzaE0bm=Mh5Z99zpRGJs7 zP~K1=r!EWyM>_itw(JyvgQNSTVo(E)x`gbqyt3Z}T&A!T{3KD&^MAJT-)mI7D~9l` zN78q%U3CIkoVCq*Yf9U?)6H?!r5j!pr4Z-^Rg?EFh+)J*7c~uVO}qxWe7L`le}xCn8C{27l5y+s-494klPB*b|V> zBUJKbq{Ad9nGhc7aO#lGtD^kvQ_=6YCFDTB#XES2z?15aq8j;)Q4OQ`73B2U2e9t5 zeDq+VhuzSrHVM&`$yt135S|m+=@9D1XgbS##XD z5q{UN;3HM>z&J@_U0W%yHs0FJX5%=j^20inqGvb~6An2hIhK`QpKcty1bN1i*5#KW z2m;-WMju}T^ZfG7YZhH~XEeHsX!O(Y{NeKK`Ku(27$ur&7F}*5tqD&>lu}Kogq}_G zd;DY3t=n?nmrecM`M)lIfqyxCIw#RYh!iNA(LZm`S0Yhye_hzd`kcj0_3@mmIB#uN zci8Wnw(s1?rq3(e+&1mnOq20CuhxeuN3QnUJE~|`6ez(N18y{GuOi!c^V3=MyBQ=2 z6NH&Dew82-Ol8l2iWYHRO<6e!^8LOli;ZR6H+}(ShlHY)Ti^;vD}Sl&GS|~3F&V$V zbC+@D<94hzmeF1D-+lk#d4l?GHB`cb( zz!Xt8GJahZpnN;JZu;Od`s=)h5h?0o^qlY_ZE&O6mSEkh|2t! z2G-YFl4grO^+j8ICWGmv+*oy4udBnRtgq~6G@;>T9LpwV3V$zVSAjroUpM6z*Rd_y zqIL@$O%(0l_F0o&u5XoPL~3p|rR)l7V>K+U8W067t+nsYcR`GR4l+$rns_Ck%kd=M z911(t8X}L^*Li(qorF1qVBR2De5f}?Tisd>Aj5JuF)Yw$eO1vC{qC*aH^n*B(8mpdx&y)<31Js4M{@y&JNhOL{rFYCh~V{RXN zuvJj_$FezeVc~&9Tg(YbCt*lrRhU7at8yzBn2d_ zVL&rdsedF%BCLIYwjhEqN@@Jh9&DiN%XRLIBnQ*H?W~6lbeEAq5}mPVB?QSRw=~}z z>Q!Hw^aH74l0Z7!V_X29-IO7A?AvBvw0&8)fi9*)Yg6pOkZjv}4mixZ>`iPylC_&L zVe7iyyAGfXzO*YGl`Z-NHp+TsLkLTV7K;$FDSxfsZw^*Qj={Go*1hdFnG5@cbMm&t zjM!n`;%R(wXfbMokN`U{Xi5ki#W=I|MEl#lT{Cye5yMK5BTyM)4Sd=j>b3V)A;H-W zb!{USe01sAlE3m)^Ewz@hM7E*xE=K-N3g*&1sb<2_Zx>Jatv|UD0lm+0N3u(wO0~y z_J1qnXu=G9ZU+OvH;4lJL+|8A(k7O`2M8s7bJgZM6LtW@?OmQX(iDXqZDWxgz6xf3 zL&KUZrdZp;1adE=j1$6W2u#icRm8Gr#U)Xi4_HafLm7A!29U@!+N)^Z@#d5fvoOfO ziDXKNWZHW@KzEjCgdr)&wV-+DG9vYC{CO2vzi zumW_D;37GP)XBb9TyXWf&jBA5P%VrOw63^n~WD--(vbd z5-v`5Wv~IEJ?$R=nt{mzkk}fDAktu(PqouLe98}fvzn_v6;mIEH_YQN&wl~sT)eW? zE_NCOkxK8g&@=H_82ij^-Ap`~Ko}q7`!v)}DbXo)HY8xXSBxY81ZNvOrv#Z;Mw3x) zVS_M3jKMk;KD@;O(|}AN(SDXk7xw5!O)6Fu+rA|3_QkqGMBfeQI#-xju2B zH`nF*+UiZxl%#x-gLj9npGWtxOm!XI;P{BKM`+lAQvBMy+dzz4_sz7^$BGY!94mFu ztg}JPMqSXz6y!4{jv1M@N=c6xnN^A#wM;}jWd;%2OvJx-CISpeVSk}M6>&jm`ot*J zr6LL(Rr0u0bcwtFxFiITU&=2)s+Z>(jR&KiVF(>WdJ!NarhDeH7#=KsCX4wah^5ei=z&!q zq69mb4w^I>C$!I#y6Jm6K+D-VFhouG$)ryWlsS9W3vXgz#DA;F$k!pEG*NmY6AfiQ z34lO62w*K$nLb#Rprz@qQ6XmhXo#OAGF$RvgO%L3z!&$aKpw+HB7}*a&YB*g0!6gW zru_aCVg^}==`XZhHqqwNLS?cvQ4zBBl@topX0eXYuIfg7D*@+D@vUSjfWiKzz#AR> zXyOX?&JJipJAcO@a#E_Epgw?{qtdA^-SO)kut*6XH}8o7v{aeFuef$lLfKkN8ln|q>ZPVcS#1uZh}igkmxO4tTM=HL;UznUAStD@etZs5MDZtG@O z=GC*1$$zYP!XT6_j!QJJ9j}_WQ5a`{A^IkhY%gS*~)@|VssBH7G4oL z`FW@iv1wv88TO9S;4(Fg9He65lrw?xCuQ94?RJqCSm}73 zJu;qe>4WctQVrFvI(EcMiPZAjKjJ;{O6bvLY*Rnom5?HQJg5EHob}@0gHQn*bJXf@ zg`s;$clhcYJ7wed#qsj&iU|LD)rVj%2V|Bd`Yx=V#nhB1V_-7WsAXZ#fmvL8%iP$0 z{C}Sm_Olmwqs{D}$!^N7cxIsi*PLWaXi&P%C?H)|E~){c0Gw8oBs2+^eDn3)E&2W) zF8OGtzbN}0L3!yBlqaX>osUL&=}9OrUFM&;Qtk3is8R0fbeT;Ug&JB4^Opj_)32OP zGD^hwXCwv%6$MTH0of!|qwzj8nfzMRS3DL0J|dH38e$JWJ&`!3VSsQ#HVG#aJQh2a zOqeuP?V}HF@BNn+Q-Ii5f+2=vS!U;{x#5A){2y|fOxBlySrHTgGnYY}0Tco=G?x)5 z5h;J|nOk$?G!%f}^DF$AJXEWzWii0avQP%t>B15QW>_BFL{81Pc5sx2<=1m$$#$H& zFD&u`0bA*m@Ni4m<2fawt0Rv9=x~=Wk4`eSdn0y1WF+)Ss<}O zn8TN8@cZ!PWTNLLzRvXMf(ksm8xcH=v!#Dtd^Y-H{5^=E9T5zL1msu0ofnJLq$4Wq zuf)(xNOPm@>r9tkLPv=UC*p!IB)D>dzSc>+%*=)cwF2S#&m~11vswd!G45T&Puo~! zF)7ozNsGL9Zy`slk^EZcGjroKdWQv0b2rYHx7V<-YFs4lIWJ((3z$W^-_4CTiAjHN z{b*8@rOsljgZq#y^ND>!R-?vwumP}=-2kOXkkIM$j#AN?2D*y?qbR5bFPzWhuRnmV03MR-& zK_McFWWB#bLGdO@7TP>ADBdJi+iKwx!$N{(qAjq17cTjkVIe*SR-CkukgSQ2vGcP6 zM8u^@^O<||UJuvH3$<2WC?6=wp{1@a{O7QVpGFdlHsVLM@l(Cog{C^GYyu|ox=XUI zJL3@&s);JoyFVaKv%N2zY;1oOME#LM6jET1jt#F0qk9#g5sGLN7EO}eSueU_Y@G{% z0uM$arvL``xrp&-jk8t!-jA0HJ@xrilpD#H7v*i7rT@fjnsqlz8Els}8L^39D#6+G ziRv^S0RlurUlAb%+&M#;#ucQ2U`Nt-Y356FnP$h9Y6Jp_5w;bk5Q@zXI!a1qO4uAwKRVM>M6x(pO zXinVE`-DVr4mP%IH`EnF35rMqzc07SK{iTkV4!JidM!ja@Bz!ii_P&qq1i#;A|6rf zkJD*=p4RbRPjU|aFp7UlpiRKR4uVBB(=6Z!6qEvrzvx6r<48pc76O@d7i3?gmCO9) z-LV+s1VL51dm;HM&L&H6yWU_HD3klL0+Oxuc^S{@6EmOIw-gx0rGJC#tF5=v_#v!O zM&az^Td>A3lsodnFEOu+BGYkx_Cm5qlGBxvaKCE7_UnxXufuGt10k!ZW=JgjaiX8;NTH)0`<0m|vRIdH5qu?JOl@8(6E@n$3#iue}TaQlyT%sc7$ zso(Rg`#lg*@tsDdjQ`x;?m38$;}Zw3n_22(dqRW(jW`8F+P;aewM5vN1W@}Ii%eEg zmw{Ok6ah1r;hGT?12Qx?m+=@9D1XIS-;dii5`N#mLcqPqK+TX8NlAH2@0uL$+Fozt zq7ThI$TIB}VoMuI&Sp{E|9&$ZQkHCO)=3H+7FZ2`4TrS5H_U7N88=tuDsmK`TX@Ah6jAC49 zuj^b1%M^bjV4cu1zQQHp`~B+X#cPvBLa{^{ z8LhTa2IgoTnM^Y+p=J~P9_z(YaL(hmc5lnRs&|W})I2Ww=Flzvv--!N50uGBa9B_- zP?=(RCZZ)6nx~3%tri)Nn}5YJ(JJ29cbv=GVoAqkvv=wjQpX<`LdTYReZ-2Qt%~*D zcHco=Cj8W{xoCaAV|Og}`$tmNIaBS%_wjvqZF9Wu*kWmx>2Yi`+&QRBApy$WjGR9#=xr9B(^ zom(KMrKz0OMiy`x_YVs}I|v1GD9Ob_#IP4I7Q(=c!vJC_O)+epCO1a-ev@!X4C69% zE9%XhE|D{?^hB4O)qf>fDznfJ{2;&y%IJ6%7IL;*SmRf+g-C4Bs}FAfp=SLU)(9UF zuiK)u%Z=SvhpHd??3?mEiMWqNRb$LhtN>hSqoy9E5UrY;PSbmItK0lX@^HK9{5b

|(CM8{Efk~#kp#_^pL^n_ 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

%-^nm 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%0A3f8rNl{^2Z>m4I2a6Oz8MVg<<*<-Xms5@Bhht4 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 ~Xd`?KO|~DyjixpME^O%rLkPC;{_x)()izAt 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°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%0Ahw4tdgW39t#w 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

9JHDQB1@vmS~gfe< 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 diff --git a/lib/colvars/Makefile.common b/lib/colvars/Makefile.common index 356a7f4a91..9e7be12958 100644 --- a/lib/colvars/Makefile.common +++ b/lib/colvars/Makefile.common @@ -50,7 +50,9 @@ COLVARS_SRCS = \ colvarparams.cpp \ colvarparse.cpp \ colvarproxy.cpp \ + colvarproxy_io.cpp \ colvarproxy_replicas.cpp \ + colvarproxy_system.cpp \ colvarproxy_tcl.cpp \ colvarproxy_volmaps.cpp \ colvarscript.cpp \ diff --git a/lib/colvars/Makefile.deps b/lib/colvars/Makefile.deps index 6619653af0..6bf5171710 100644 --- a/lib/colvars/Makefile.deps +++ b/lib/colvars/Makefile.deps @@ -1,371 +1,140 @@ $(COLVARS_OBJ_DIR)colvaratoms.o: colvaratoms.cpp colvarmodule.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvarparse.h colvarparams.h \ - colvaratoms.h colvardeps.h + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvarparse.h colvarparams.h colvaratoms.h \ + colvardeps.h $(COLVARS_OBJ_DIR)colvarbias_abf.o: colvarbias_abf.cpp colvarmodule.h \ colvars_version.h colvar.h colvarvalue.h colvartypes.h colvarparse.h \ - colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarbias_abf.h colvarproxy.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvarbias.h colvargrid.h \ - colvar_UIestimator.h + colvarparams.h colvardeps.h colvarbias_abf.h colvarproxy.h \ + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvarbias.h colvargrid.h colvar_UIestimator.h $(COLVARS_OBJ_DIR)colvarbias_alb.o: colvarbias_alb.cpp colvarmodule.h \ colvars_version.h colvarbias.h colvar.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarbias_alb.h + colvarparse.h colvarparams.h colvardeps.h colvarbias_alb.h $(COLVARS_OBJ_DIR)colvarbias.o: colvarbias.cpp colvarmodule.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvarbias.h colvar.h \ - colvarparse.h colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvargrid.h + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvarbias.h colvar.h colvarparse.h colvarparams.h \ + colvardeps.h colvargrid.h $(COLVARS_OBJ_DIR)colvarbias_histogram.o: colvarbias_histogram.cpp \ colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \ - colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h \ - colvarparse.h colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarbias_histogram.h colvarbias.h \ - colvargrid.h + colvarvalue.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar.h colvarparse.h colvarparams.h colvardeps.h \ + colvarbias_histogram.h colvarbias.h colvargrid.h $(COLVARS_OBJ_DIR)colvarbias_histogram_reweight_amd.o: \ colvarbias_histogram_reweight_amd.cpp \ colvarbias_histogram_reweight_amd.h colvarbias_histogram.h colvarbias.h \ colvar.h colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvargrid.h colvarproxy.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h + colvarparse.h colvarparams.h colvardeps.h colvargrid.h colvarproxy.h \ + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h $(COLVARS_OBJ_DIR)colvarbias_meta.o: colvarbias_meta.cpp colvarmodule.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h colvarparse.h \ - colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarbias_meta.h colvarbias.h \ - colvargrid.h + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar.h colvarparse.h colvarparams.h colvardeps.h \ + colvarbias_meta.h colvarbias.h colvargrid.h $(COLVARS_OBJ_DIR)colvarbias_restraint.o: colvarbias_restraint.cpp \ colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \ - colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvarbias_restraint.h colvarbias.h colvar.h colvarparse.h \ - colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h + colvarvalue.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvarbias_restraint.h colvarbias.h colvar.h \ + colvarparse.h colvarparams.h colvardeps.h $(COLVARS_OBJ_DIR)colvarcomp_alchlambda.o: colvarcomp_alchlambda.cpp \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvar.h colvardeps.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ + colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \ + colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \ + colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_angles.o: colvarcomp_angles.cpp \ colvarmodule.h colvars_version.h colvar.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparse.h colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h \ + colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_apath.o: colvarcomp_apath.cpp colvarmodule.h \ colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \ - colvarparams.h colvar.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \ + colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_coordnums.o: colvarcomp_coordnums.cpp \ colvarmodule.h colvars_version.h colvarparse.h colvarvalue.h \ colvartypes.h colvarparams.h colvaratoms.h colvarproxy.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvar.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvar_arithmeticpath.h \ - colvar_geometricpath.h + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvardeps.h colvar.h colvarcomp.h \ + colvar_arithmeticpath.h colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp.o: colvarcomp.cpp colvarmodule.h \ colvars_version.h colvarvalue.h colvartypes.h colvar.h colvarparse.h \ - colvarparams.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparams.h colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h \ + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_distances.o: colvarcomp_distances.cpp \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvar.h colvardeps.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ + colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \ + colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \ + colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_gpath.o: colvarcomp_gpath.cpp colvarmodule.h \ colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \ - colvarparams.h colvar.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \ + colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_neuralnetwork.o: \ colvarcomp_neuralnetwork.cpp colvarmodule.h colvars_version.h \ colvarvalue.h colvartypes.h colvarparse.h colvarparams.h colvar.h \ - colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ + colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \ + colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \ colvar_arithmeticpath.h colvar_geometricpath.h \ colvar_neuralnetworkcompute.h $(COLVARS_OBJ_DIR)colvarcomp_combination.o: colvarcomp_combination.cpp \ colvarcomp.h colvarmodule.h colvars_version.h colvar.h colvarvalue.h \ - colvartypes.h colvarparse.h colvarparams.h colvardeps.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvaratoms.h colvarproxy.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \ - colvar_geometricpath.h + colvartypes.h colvarparse.h colvarparams.h colvardeps.h colvaratoms.h \ + colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_protein.o: colvarcomp_protein.cpp \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvar.h colvardeps.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ + colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \ + colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \ + colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_rotations.o: colvarcomp_rotations.cpp \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvar.h colvardeps.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ + colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \ + colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \ + colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvarcomp_volmaps.o: colvarcomp_volmaps.cpp \ colvarmodule.h colvars_version.h colvarvalue.h colvartypes.h \ - colvarparse.h colvarparams.h colvar.h colvardeps.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h + colvarparse.h colvarparams.h colvar.h colvardeps.h colvarcomp.h \ + colvaratoms.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \ + colvarproxy_tcl.h colvarproxy_volmaps.h colvar_arithmeticpath.h \ + colvar_geometricpath.h $(COLVARS_OBJ_DIR)colvar.o: colvar.cpp colvarmodule.h colvars_version.h \ colvarvalue.h colvartypes.h colvarparse.h colvarparams.h colvar.h \ - colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ + colvardeps.h colvarcomp.h colvaratoms.h colvarproxy.h colvarproxy_io.h \ + colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \ colvar_arithmeticpath.h colvar_geometricpath.h colvarscript.h \ colvarbias.h colvarscript_commands.h colvarscript_commands_colvar.h \ colvarscript_commands_bias.h $(COLVARS_OBJ_DIR)colvardeps.o: colvardeps.cpp colvarmodule.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvarparse.h \ - colvarparams.h + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h $(COLVARS_OBJ_DIR)colvargrid.o: colvargrid.cpp colvarmodule.h \ colvars_version.h colvarvalue.h colvartypes.h colvarparse.h \ - colvarparams.h colvar.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarcomp.h colvaratoms.h \ - colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar_arithmeticpath.h colvar_geometricpath.h colvargrid.h + colvarparams.h colvar.h colvardeps.h colvarcomp.h colvaratoms.h \ + colvarproxy.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvar_arithmeticpath.h colvar_geometricpath.h \ + colvargrid.h colvargrid_def.h $(COLVARS_OBJ_DIR)colvarmodule.o: colvarmodule.cpp colvarmodule.h \ colvars_version.h colvarparse.h colvarvalue.h colvartypes.h \ - colvarparams.h colvarproxy.h colvarproxy_tcl.h colvarproxy_volmaps.h \ - colvar.h colvardeps.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarbias.h colvarbias_abf.h \ - colvargrid.h colvar_UIestimator.h colvarbias_alb.h \ - colvarbias_histogram.h colvarbias_histogram_reweight_amd.h \ - colvarbias_meta.h colvarbias_restraint.h colvarscript.h \ - colvarscript_commands.h colvarscript_commands_colvar.h \ - colvarscript_commands_bias.h colvaratoms.h colvarcomp.h \ - colvar_arithmeticpath.h colvar_geometricpath.h colvarmodule_refs.h + colvarparams.h colvarproxy.h colvarproxy_io.h colvarproxy_system.h \ + colvarproxy_tcl.h colvarproxy_volmaps.h colvar.h colvardeps.h \ + colvarbias.h colvarbias_abf.h colvargrid.h colvar_UIestimator.h \ + colvarbias_alb.h colvarbias_histogram.h \ + colvarbias_histogram_reweight_amd.h colvarbias_meta.h \ + colvarbias_restraint.h colvarscript.h colvarscript_commands.h \ + colvarscript_commands_colvar.h colvarscript_commands_bias.h \ + colvaratoms.h colvarcomp.h colvar_arithmeticpath.h \ + colvar_geometricpath.h colvarmodule_refs.h $(COLVARS_OBJ_DIR)colvarparams.o: colvarparams.cpp colvarmodule.h \ colvars_version.h colvarvalue.h colvartypes.h colvarparams.h $(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \ @@ -373,97 +142,53 @@ $(COLVARS_OBJ_DIR)colvarparse.o: colvarparse.cpp colvarmodule.h \ colvarparams.h $(COLVARS_OBJ_DIR)colvarproxy.o: colvarproxy.cpp colvarmodule.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvarscript.h colvarbias.h \ - colvar.h colvarparse.h colvarparams.h colvardeps.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarscript_commands.h \ + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvarscript.h colvarbias.h colvar.h colvarparse.h \ + colvarparams.h colvardeps.h colvarscript_commands.h \ colvarscript_commands_colvar.h colvarscript_commands_bias.h \ colvaratoms.h colvarmodule_utils.h +$(COLVARS_OBJ_DIR)colvarproxy_io.o: colvarproxy_io.cpp colvarmodule.h \ + colvars_version.h colvarproxy_io.h $(COLVARS_OBJ_DIR)colvarproxy_replicas.o: colvarproxy_replicas.cpp \ colvarmodule.h colvars_version.h colvarproxy.h colvartypes.h \ - colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h + colvarvalue.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h +$(COLVARS_OBJ_DIR)colvarproxy_system.o: colvarproxy_system.cpp \ + colvarmodule.h colvars_version.h colvartypes.h colvarproxy_system.h $(COLVARS_OBJ_DIR)colvarproxy_tcl.o: colvarproxy_tcl.cpp colvarmodule.h \ colvars_version.h colvarproxy.h colvartypes.h colvarvalue.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvaratoms.h colvarparse.h \ - colvarparams.h colvardeps.h + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvaratoms.h colvarparse.h colvarparams.h \ + colvardeps.h $(COLVARS_OBJ_DIR)colvarproxy_volmaps.o: colvarproxy_volmaps.cpp \ colvarmodule.h colvars_version.h colvarproxy_volmaps.h \ colvarmodule_utils.h $(COLVARS_OBJ_DIR)colvarscript.o: colvarscript.cpp colvarproxy.h \ colvarmodule.h colvars_version.h colvartypes.h colvarvalue.h \ - colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h colvarparse.h \ - colvarparams.h colvarscript.h colvarbias.h colvar.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarscript_commands.h \ + colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \ + colvarscript.h colvarbias.h colvar.h colvarscript_commands.h \ colvarscript_commands_colvar.h colvarscript_commands_bias.h $(COLVARS_OBJ_DIR)colvarscript_commands.o: colvarscript_commands.cpp \ colvarproxy.h colvarmodule.h colvars_version.h colvartypes.h \ - colvarvalue.h colvarproxy_tcl.h colvarproxy_volmaps.h colvardeps.h \ - colvarparse.h colvarparams.h colvarscript.h colvarbias.h colvar.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarscript_commands.h \ + colvarvalue.h colvarproxy_io.h colvarproxy_system.h colvarproxy_tcl.h \ + colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \ + colvarscript.h colvarbias.h colvar.h colvarscript_commands.h \ colvarscript_commands_colvar.h colvarscript_commands_bias.h $(COLVARS_OBJ_DIR)colvarscript_commands_bias.o: \ colvarscript_commands_bias.cpp colvarproxy.h colvarmodule.h \ - colvars_version.h colvartypes.h colvarvalue.h colvarproxy_tcl.h \ - colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \ - colvarscript.h colvarbias.h colvar.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarscript_commands.h \ - colvarscript_commands_colvar.h colvarscript_commands_bias.h + colvars_version.h colvartypes.h colvarvalue.h colvarproxy_io.h \ + colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \ + colvardeps.h colvarparse.h colvarparams.h colvarscript.h colvarbias.h \ + colvar.h colvarscript_commands.h colvarscript_commands_colvar.h \ + colvarscript_commands_bias.h $(COLVARS_OBJ_DIR)colvarscript_commands_colvar.o: \ colvarscript_commands_colvar.cpp colvarproxy.h colvarmodule.h \ - colvars_version.h colvartypes.h colvarvalue.h colvarproxy_tcl.h \ - colvarproxy_volmaps.h colvardeps.h colvarparse.h colvarparams.h \ - colvarscript.h colvarbias.h colvar.h ../lepton/include/Lepton.h \ - ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarscript_commands.h \ - colvarscript_commands_colvar.h colvarscript_commands_bias.h + colvars_version.h colvartypes.h colvarvalue.h colvarproxy_io.h \ + colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h \ + colvardeps.h colvarparse.h colvarparams.h colvarscript.h colvarbias.h \ + colvar.h colvarscript_commands.h colvarscript_commands_colvar.h \ + colvarscript_commands_bias.h $(COLVARS_OBJ_DIR)colvartypes.o: colvartypes.cpp colvarmodule.h \ colvars_version.h colvartypes.h colvarparse.h colvarvalue.h \ colvarparams.h ../../src/math_eigen_impl.h @@ -471,15 +196,6 @@ $(COLVARS_OBJ_DIR)colvarvalue.o: colvarvalue.cpp colvarmodule.h \ colvars_version.h colvarvalue.h colvartypes.h $(COLVARS_OBJ_DIR)colvar_neuralnetworkcompute.o: \ colvar_neuralnetworkcompute.cpp colvar_neuralnetworkcompute.h \ - ../lepton/include/Lepton.h ../lepton/include/lepton/CompiledExpression.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/windowsIncludes.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/ExpressionProgram.h \ - ../lepton/include/lepton/ExpressionTreeNode.h \ - ../lepton/include/lepton/Operation.h \ - ../lepton/include/lepton/CustomFunction.h \ - ../lepton/include/lepton/Exception.h \ - ../lepton/include/lepton/ParsedExpression.h \ - ../lepton/include/lepton/Parser.h colvarparse.h colvarmodule.h \ - colvars_version.h colvarvalue.h colvartypes.h colvarparams.h + colvarparse.h colvarmodule.h colvars_version.h colvarvalue.h \ + colvartypes.h colvarparams.h colvarproxy.h colvarproxy_io.h \ + colvarproxy_system.h colvarproxy_tcl.h colvarproxy_volmaps.h diff --git a/lib/colvars/colvar.cpp b/lib/colvars/colvar.cpp index 85b8443d72..700d3752ac 100644 --- a/lib/colvars/colvar.cpp +++ b/lib/colvars/colvar.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "colvarmodule.h" #include "colvarvalue.h" @@ -24,8 +26,6 @@ std::mapproxy; get_keyval_feature(this, conf, "extendedLagrangian", f_cv_extended_Lagrangian, false); if (is_enabled(f_cv_extended_Lagrangian)) { @@ -646,7 +646,8 @@ int colvar::init_extended_Lagrangian(std::string const &conf) x_ext.type(colvarvalue::type_notset); v_ext.type(value()); fr.type(value()); - const bool temp_provided = get_keyval(conf, "extendedTemp", temp, cvm::temperature()); + const bool temp_provided = get_keyval(conf, "extendedTemp", temp, + proxy->target_temperature()); if (is_enabled(f_cv_external)) { // In the case of an "external" coordinate, there is no coupling potential: // only the fictitious mass is meaningful @@ -669,14 +670,14 @@ int colvar::init_extended_Lagrangian(std::string const &conf) cvm::error("Error: \"extendedFluctuation\" must be positive.\n", COLVARS_INPUT_ERROR); return COLVARS_INPUT_ERROR; } - ext_force_k = cvm::boltzmann() * temp / (tolerance * tolerance); + ext_force_k = proxy->boltzmann() * temp / (tolerance * tolerance); cvm::log("Computed extended system force constant: " + cvm::to_str(ext_force_k) + " [E]/U^2\n"); get_keyval(conf, "extendedTimeConstant", extended_period, 200.0); if (extended_period <= 0.0) { cvm::error("Error: \"extendedTimeConstant\" must be positive.\n", COLVARS_INPUT_ERROR); } - ext_mass = (cvm::boltzmann() * temp * extended_period * extended_period) + ext_mass = (proxy->boltzmann() * temp * extended_period * extended_period) / (4.0 * PI * PI * tolerance * tolerance); cvm::log("Computed fictitious mass: " + cvm::to_str(ext_mass) + " [E]/(U/fs)^2 (U: colvar unit)\n"); } @@ -697,7 +698,7 @@ int colvar::init_extended_Lagrangian(std::string const &conf) enable(f_cv_Langevin); ext_gamma *= 1.0e-3; // correct as long as input is required in ps-1 and cvm::dt() is in fs // Adjust Langevin sigma for slow time step if time_step_factor != 1 - ext_sigma = cvm::sqrt(2.0 * cvm::boltzmann() * temp * ext_gamma * ext_mass / (cvm::dt() * cvm::real(time_step_factor))); + ext_sigma = cvm::sqrt(2.0 * proxy->boltzmann() * temp * ext_gamma * ext_mass / (cvm::dt() * cvm::real(time_step_factor))); } get_keyval_feature(this, conf, "reflectingLowerBoundary", f_cv_reflecting_lower_boundary, false); @@ -1664,6 +1665,7 @@ int colvar::calc_cvc_Jacobians(int first_cvc, size_t num_cvcs) int colvar::collect_cvc_Jacobians() { + colvarproxy *proxy = cvm::main()->proxy; if (is_enabled(f_cv_Jacobian)) { fj.reset(); for (size_t i = 0; i < cvcs.size(); i++) { @@ -1676,7 +1678,7 @@ int colvar::collect_cvc_Jacobians() // linear combination is assumed fj += (cvcs[i])->Jacobian_derivative() * (cvcs[i])->sup_coeff / active_cvc_square_norm; } - fj *= cvm::boltzmann() * cvm::temperature(); + fj *= proxy->boltzmann() * proxy->target_temperature(); } return COLVARS_OK; @@ -2411,8 +2413,8 @@ std::ostream & colvar::write_state(std::ostream &os) { os << "}\n\n"; - if (runave_os) { - cvm::main()->proxy->flush_output_stream(runave_os); + if (runave_outfile.size() > 0) { + cvm::main()->proxy->flush_output_stream(runave_outfile); } return os; @@ -2536,9 +2538,13 @@ int colvar::write_output_files() } cvm::log("Writing correlation function to file \""+acf_outfile+"\".\n"); cvm::backup_file(acf_outfile.c_str()); - std::ostream *acf_os = cvm::proxy->output_stream(acf_outfile); - if (!acf_os) return cvm::get_error(); - error_code |= write_acf(*acf_os); + std::ostream &acf_os = cvm::proxy->output_stream(acf_outfile, + "colvar ACF file"); + if (!acf_os) { + error_code |= COLVARS_FILE_ERROR; + } else { + error_code |= write_acf(acf_os); + } cvm::proxy->close_output_stream(acf_outfile); } } @@ -2807,6 +2813,7 @@ int colvar::write_acf(std::ostream &os) int colvar::calc_runave() { int error_code = COLVARS_OK; + colvarproxy *proxy = cvm::main()->proxy; if (x_history.empty()) { @@ -2831,22 +2838,22 @@ int colvar::calc_runave() if ((*x_history_p).size() >= runave_length-1) { - if (runave_os == NULL) { - if (runave_outfile.size() == 0) { - runave_outfile = std::string(cvm::output_prefix()+"."+ - this->name+".runave.traj"); - } + if (runave_outfile.size() == 0) { + runave_outfile = std::string(cvm::output_prefix()+"."+ + this->name+".runave.traj"); + } + if (! proxy->output_stream_exists(runave_outfile)) { size_t const this_cv_width = x.output_width(cvm::cv_width); - cvm::proxy->backup_file(runave_outfile); - runave_os = cvm::proxy->output_stream(runave_outfile); - runave_os->setf(std::ios::scientific, std::ios::floatfield); - *runave_os << "# " << cvm::wrap_string("step", cvm::it_width-2) - << " " - << cvm::wrap_string("running average", this_cv_width) - << " " - << cvm::wrap_string("running stddev", this_cv_width) - << "\n"; + std::ostream &runave_os = proxy->output_stream(runave_outfile, + "colvar running average"); + runave_os.setf(std::ios::scientific, std::ios::floatfield); + runave_os << "# " << cvm::wrap_string("step", cvm::it_width-2) + << " " + << cvm::wrap_string("running average", this_cv_width) + << " " + << cvm::wrap_string("running stddev", this_cv_width) + << "\n"; } runave = x; @@ -2866,12 +2873,17 @@ int colvar::calc_runave() } runave_variance *= 1.0 / cvm::real(runave_length-1); - *runave_os << std::setw(cvm::it_width) << cvm::step_relative() - << " " - << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width) - << runave << " " - << std::setprecision(cvm::cv_prec) << std::setw(cvm::cv_width) - << cvm::sqrt(runave_variance) << "\n"; + if (runave_outfile.size() > 0) { + std::ostream &runave_os = proxy->output_stream(runave_outfile); + runave_os << std::setw(cvm::it_width) << cvm::step_relative() + << " " + << std::setprecision(cvm::cv_prec) + << std::setw(cvm::cv_width) + << runave << " " + << std::setprecision(cvm::cv_prec) + << std::setw(cvm::cv_width) + << cvm::sqrt(runave_variance) << "\n"; + } } history_add_value(runave_length, *x_history_p, x); diff --git a/lib/colvars/colvar.h b/lib/colvars/colvar.h index 7b2863a3b5..9af26dedd3 100644 --- a/lib/colvars/colvar.h +++ b/lib/colvars/colvar.h @@ -551,8 +551,6 @@ protected: size_t runave_stride; /// Name of the file to write the running average std::string runave_outfile; - /// File to write the running average - std::ostream *runave_os; /// Current value of the running average colvarvalue runave; /// Current value of the square deviation from the running average diff --git a/lib/colvars/colvar_UIestimator.h b/lib/colvars/colvar_UIestimator.h index ca1ecc8c43..30a90a5799 100644 --- a/lib/colvars/colvar_UIestimator.h +++ b/lib/colvars/colvar_UIestimator.h @@ -1,4 +1,4 @@ -// -*- c++ -*- +// -*- Mode:c++; c-basic-offset: 4; -*- // This file is part of the Collective Variables module (Colvars). // The original version of Colvars and its updates are located at: @@ -21,6 +21,7 @@ // only for colvar module! // when integrated into other code, just remove this line and "...cvm::backup_file(...)" #include "colvarmodule.h" +#include "colvarproxy.h" namespace UIestimator { const int Y_SIZE = 21; // defines the range of extended CV with respect to a given CV @@ -380,6 +381,8 @@ namespace UIestimator { public: // calculate gradients from the internal variables void calc_pmf() { + colvarproxy *proxy = cvm::main()->proxy; + int norm; int i, j, k; @@ -455,7 +458,7 @@ namespace UIestimator { std::vector grad_temp(dimension, 0); for (k = 0; k < dimension; k++) { diff_av[k] /= (norm > 0 ? norm : 1); - av[k] = cvm::boltzmann() * temperature * av[k] / (norm > 0 ? norm : 1); + av[k] = proxy->boltzmann() * temperature * av[k] / (norm > 0 ? norm : 1); grad_temp[k] = av[k] - krestr[k] * diff_av[k]; } grad.set_value(loop_flag_x, grad_temp); @@ -515,15 +518,16 @@ namespace UIestimator { // only for colvars module! if (written_1D) cvm::backup_file(pmf_filename.c_str()); - std::ostream* ofile_pmf = cvm::proxy->output_stream(pmf_filename.c_str()); + std::ostream &ofile_pmf = cvm::proxy->output_stream(pmf_filename, + "PMF file"); std::vector position(1, 0); for (double i = lowerboundary[0]; i < upperboundary[0] + EPSILON; i += width[0]) { - *ofile_pmf << i << " "; + ofile_pmf << i << " "; position[0] = i + EPSILON; - *ofile_pmf << oneD_pmf.get_value(position) << std::endl; + ofile_pmf << oneD_pmf.get_value(position) << std::endl; } - cvm::proxy->close_output_stream(pmf_filename.c_str()); + cvm::proxy->close_output_stream(pmf_filename); written_1D = true; } @@ -541,7 +545,8 @@ namespace UIestimator { void write_interal_data() { std::string internal_filename = output_filename + ".UI.internal"; - std::ostream* ofile_internal = cvm::proxy->output_stream(internal_filename.c_str()); + std::ostream &ofile_internal = cvm::proxy->output_stream(internal_filename, + "UI internal file"); std::vector loop_flag(dimension, 0); for (int i = 0; i < dimension; i++) { @@ -551,11 +556,11 @@ namespace UIestimator { int n = 0; while (n >= 0) { for (int j = 0; j < dimension; j++) { - *ofile_internal << loop_flag[j] + 0.5 * width[j] << " "; + ofile_internal << loop_flag[j] + 0.5 * width[j] << " "; } for (int k = 0; k < dimension; k++) { - *ofile_internal << grad.get_value(loop_flag)[k] << " "; + ofile_internal << grad.get_value(loop_flag)[k] << " "; } std::vector ii(dimension,0); @@ -563,10 +568,10 @@ namespace UIestimator { for (double j = loop_flag[1] - 10; j< loop_flag[1] + 10 + EPSILON; j+=width[1]) { ii[0] = i; ii[1] = j; - *ofile_internal << i <<" "<output_stream(grad_filename.c_str()); - std::ostream* ofile_hist = cvm::proxy->output_stream(hist_filename.c_str(), std::ios::app); - std::ostream* ofile_count = cvm::proxy->output_stream(count_filename.c_str()); + std::ostream &ofile = cvm::proxy->output_stream(grad_filename, + "gradient file"); + std::ostream &ofile_hist = cvm::proxy->output_stream(hist_filename, + "gradient history file"); + std::ostream &ofile_count = cvm::proxy->output_stream(count_filename, + "count file"); - writehead(*ofile); - writehead(*ofile_hist); - writehead(*ofile_count); + writehead(ofile); + writehead(ofile_hist); + writehead(ofile_count); if (dimension == 1) { calc_1D_pmf(); @@ -617,19 +625,19 @@ namespace UIestimator { i = 0; while (i >= 0) { for (j = 0; j < dimension; j++) { - *ofile << loop_flag[j] + 0.5 * width[j] << " "; - *ofile_hist << loop_flag[j] + 0.5 * width[j] << " "; - *ofile_count << loop_flag[j] + 0.5 * width[j] << " "; + ofile << loop_flag[j] + 0.5 * width[j] << " "; + ofile_hist << loop_flag[j] + 0.5 * width[j] << " "; + ofile_count << loop_flag[j] + 0.5 * width[j] << " "; } if (restart == false) { for (j = 0; j < dimension; j++) { - *ofile << grad.get_value(loop_flag)[j] << " "; - *ofile_hist << grad.get_value(loop_flag)[j] << " "; + ofile << grad.get_value(loop_flag)[j] << " "; + ofile_hist << grad.get_value(loop_flag)[j] << " "; } - *ofile << std::endl; - *ofile_hist << std::endl; - *ofile_count << count.get_value(loop_flag) << " " < upperboundary[i] - width[i] + EPSILON) { loop_flag[i] = lowerboundary[i]; i--; - *ofile << std::endl; - *ofile_hist << std::endl; - *ofile_count << std::endl; + ofile << std::endl; + ofile_hist << std::endl; + ofile_count << std::endl; } else break; } } cvm::proxy->close_output_stream(grad_filename.c_str()); - cvm::proxy->close_output_stream(hist_filename.c_str()); + // cvm::proxy->close_output_stream(hist_filename.c_str()); cvm::proxy->close_output_stream(count_filename.c_str()); written = true; @@ -677,6 +685,7 @@ namespace UIestimator { int dimension_temp; int i, j, k, l, m; + colvarproxy *proxy = cvm::main()->proxy; std::vector loop_bin_size(dimension, 0); std::vector position_temp(dimension, 0); std::vector grad_temp(dimension, 0); @@ -687,8 +696,14 @@ namespace UIestimator { std::string count_filename = filename[i] + ".UI.count"; std::string grad_filename = filename[i] + ".UI.grad"; - std::ifstream count_file(count_filename.c_str(), std::ios::in); - std::ifstream grad_file(grad_filename.c_str(), std::ios::in); + std::istream &count_file = + proxy->input_stream(count_filename, "count filename"); + std::istream &grad_file = + proxy->input_stream(grad_filename, "gradient filename"); + + if (!count_file || !grad_file) { + return; + } count_file >> sharp >> dimension_temp; grad_file >> sharp >> dimension_temp; @@ -724,8 +739,8 @@ namespace UIestimator { input_count.increase_value(position_temp, count_temp); } - count_file.close(); - grad_file.close(); + proxy->close_input_stream(count_filename); + proxy->close_input_stream(grad_filename); } } }; diff --git a/lib/colvars/colvar_arithmeticpath.h b/lib/colvars/colvar_arithmeticpath.h index cf613af389..bea86a1014 100644 --- a/lib/colvars/colvar_arithmeticpath.h +++ b/lib/colvars/colvar_arithmeticpath.h @@ -5,7 +5,6 @@ #include #include -#include #include #include diff --git a/lib/colvars/colvar_geometricpath.h b/lib/colvars/colvar_geometricpath.h index 7f8acfd233..9ff78261f2 100644 --- a/lib/colvars/colvar_geometricpath.h +++ b/lib/colvars/colvar_geometricpath.h @@ -12,10 +12,8 @@ #include #include -#include #include #include -#include namespace GeometricPathCV { diff --git a/lib/colvars/colvar_neuralnetworkcompute.cpp b/lib/colvars/colvar_neuralnetworkcompute.cpp index d0f9633652..a1ad717946 100644 --- a/lib/colvars/colvar_neuralnetworkcompute.cpp +++ b/lib/colvars/colvar_neuralnetworkcompute.cpp @@ -1,6 +1,19 @@ +// -*- Mode:c++; c-basic-offset: 4; -*- + +// This file is part of the Collective Variables module (Colvars). +// The original version of Colvars and its updates are located at: +// https://github.com/Colvars/colvars +// Please update all Colvars source files before making any changes. +// If you wish to distribute your changes, please submit them to the +// Colvars repository at GitHub. + +#include +#include + #if (__cplusplus >= 201103L) #include "colvar_neuralnetworkcompute.h" #include "colvarparse.h" +#include "colvarproxy.h" namespace neuralnetworkCV { std::map, std::function>> activation_function_map @@ -124,12 +137,10 @@ void denseLayer::readFromFile(const std::string& weights_file, const std::string m_weights.clear(); m_biases.clear(); std::string line; - std::ifstream ifs_weights(weights_file.c_str()); - if (!ifs_weights) { - throw std::runtime_error("Cannot open file " + weights_file); - } + colvarproxy *proxy = cvm::main()->proxy; + auto &ifs_weights = proxy->input_stream(weights_file, "weights file"); while (std::getline(ifs_weights, line)) { - if (ifs_weights.bad()) { + if (!ifs_weights) { throw std::runtime_error("I/O error while reading " + weights_file); } std::vector splitted_data; @@ -146,13 +157,12 @@ void denseLayer::readFromFile(const std::string& weights_file, const std::string m_weights.push_back(weights_tmp); } } + proxy->close_input_stream(weights_file); + // parse biases file - std::ifstream ifs_biases(biases_file.c_str()); - if (!ifs_biases) { - throw std::runtime_error("Cannot open file " + biases_file); - } + auto &ifs_biases = proxy->input_stream(biases_file, "biases file"); while (std::getline(ifs_biases, line)) { - if (ifs_biases.bad()) { + if (!ifs_biases) { throw std::runtime_error("I/O error while reading " + biases_file); } std::vector splitted_data; @@ -167,6 +177,8 @@ void denseLayer::readFromFile(const std::string& weights_file, const std::string m_biases.push_back(bias); } } + proxy->close_input_stream(biases_file); + m_input_size = m_weights[0].size(); m_output_size = m_weights.size(); } diff --git a/lib/colvars/colvar_neuralnetworkcompute.h b/lib/colvars/colvar_neuralnetworkcompute.h index a48f8c7f14..5a56887431 100644 --- a/lib/colvars/colvar_neuralnetworkcompute.h +++ b/lib/colvars/colvar_neuralnetworkcompute.h @@ -1,3 +1,12 @@ +// -*- c++ -*- + +// This file is part of the Collective Variables module (Colvars). +// The original version of Colvars and its updates are located at: +// https://github.com/Colvars/colvars +// Please update all Colvars source files before making any changes. +// If you wish to distribute your changes, please submit them to the +// Colvars repository at GitHub. + #if (__cplusplus >= 201103L) #ifndef NEURALNETWORKCOMPUTE_H #define NEURALNETWORKCOMPUTE_H @@ -5,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/lib/colvars/colvaratoms.cpp b/lib/colvars/colvaratoms.cpp index f950bf5965..e31041ea6b 100644 --- a/lib/colvars/colvaratoms.cpp +++ b/lib/colvars/colvaratoms.cpp @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include "colvarmodule.h" #include "colvarproxy.h" @@ -29,12 +31,8 @@ cvm::atom::atom() cvm::atom::atom(int atom_number) { - colvarproxy *p = cvm::proxy; + colvarproxy *p = cvm::main()->proxy; index = p->init_atom(atom_number); - if (cvm::debug()) { - cvm::log("The index of this atom in the colvarproxy arrays is "+ - cvm::to_str(index)+".\n"); - } id = p->get_atom_id(index); update_mass(); update_charge(); @@ -46,12 +44,8 @@ cvm::atom::atom(cvm::residue_id const &residue, std::string const &atom_name, std::string const &segment_id) { - colvarproxy *p = cvm::proxy; + colvarproxy *p = cvm::main()->proxy; index = p->init_atom(residue, atom_name, segment_id); - if (cvm::debug()) { - cvm::log("The index of this atom in the colvarproxy_namd arrays is "+ - cvm::to_str(index)+".\n"); - } id = p->get_atom_id(index); update_mass(); update_charge(); @@ -62,7 +56,9 @@ cvm::atom::atom(cvm::residue_id const &residue, cvm::atom::atom(atom const &a) : index(a.index) { - id = (cvm::proxy)->get_atom_id(index); + colvarproxy *p = cvm::main()->proxy; + id = p->get_atom_id(index); + p->increase_refcount(index); update_mass(); update_charge(); reset_data(); @@ -72,7 +68,7 @@ cvm::atom::atom(atom const &a) cvm::atom::~atom() { if (index >= 0) { - (cvm::proxy)->clear_atom(index); + (cvm::main()->proxy)->clear_atom(index); } } @@ -80,7 +76,7 @@ cvm::atom::~atom() cvm::atom & cvm::atom::operator = (cvm::atom const &a) { index = a.index; - id = (cvm::proxy)->get_atom_id(index); + id = (cvm::main()->proxy)->get_atom_id(index); update_mass(); update_charge(); reset_data(); @@ -113,7 +109,7 @@ cvm::atom_group::atom_group(std::vector const &atoms_in) cvm::atom_group::~atom_group() { if (is_enabled(f_ag_scalable) && !b_dummy) { - (cvm::proxy)->clear_atom_group(index); + (cvm::main()->proxy)->clear_atom_group(index); index = -1; } @@ -330,7 +326,7 @@ void cvm::atom_group::update_total_mass() } if (is_enabled(f_ag_scalable)) { - total_mass = (cvm::proxy)->get_atom_group_mass(index); + total_mass = (cvm::main()->proxy)->get_atom_group_mass(index); } else { total_mass = 0.0; for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) { @@ -351,7 +347,7 @@ void cvm::atom_group::update_total_charge() } if (is_enabled(f_ag_scalable)) { - total_charge = (cvm::proxy)->get_atom_group_charge(index); + total_charge = (cvm::main()->proxy)->get_atom_group_charge(index); } else { total_charge = 0.0; for (cvm::atom_iter ai = this->begin(); ai != this->end(); ai++) { diff --git a/lib/colvars/colvarbias.cpp b/lib/colvars/colvarbias.cpp index bb2f2310f7..18969fc531 100644 --- a/lib/colvars/colvarbias.cpp +++ b/lib/colvars/colvarbias.cpp @@ -7,7 +7,7 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. -#include +#include #include #include "colvarmodule.h" @@ -42,6 +42,8 @@ colvarbias::colvarbias(char const *key) int colvarbias::init(std::string const &conf) { + int error_code = COLVARS_OK; + name = bias_type + cvm::to_str(rank); colvarparse::set_string(conf); @@ -59,9 +61,9 @@ int colvarbias::init(std::string const &conf) if (bias_with_name != NULL) { if ((bias_with_name->rank != this->rank) || (bias_with_name->bias_type != this->bias_type)) { - cvm::error("Error: this bias cannot have the same name, \""+this->name+ - "\", as another bias.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; + error_code |= cvm::error("Error: this bias cannot have the same name, \""+ + this->name+"\", as another bias.\n", + COLVARS_INPUT_ERROR); } } description = "bias " + name; @@ -71,9 +73,9 @@ int colvarbias::init(std::string const &conf) std::vector colvar_names; if (get_keyval(conf, "colvars", colvar_names)) { if (num_variables()) { - cvm::error("Error: cannot redefine the colvars that a bias was already defined on.\n", - COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; + error_code |= cvm::error("Error: cannot redefine the colvars that " + "a bias was already defined on.\n", + COLVARS_INPUT_ERROR); } for (i = 0; i < colvar_names.size(); i++) { add_colvar(colvar_names[i]); @@ -82,8 +84,8 @@ int colvarbias::init(std::string const &conf) } if (!num_variables()) { - cvm::error("Error: no collective variables specified.\n", COLVARS_INPUT_ERROR); - return COLVARS_INPUT_ERROR; + error_code |= cvm::error("Error: no collective variables specified.\n", + COLVARS_INPUT_ERROR); } } else { @@ -112,8 +114,8 @@ int colvarbias::init(std::string const &conf) get_keyval(conf, "timeStepFactor", time_step_factor, time_step_factor); if (time_step_factor < 1) { - cvm::error("Error: timeStepFactor must be 1 or greater.\n"); - return COLVARS_ERROR; + error_code |= cvm::error("Error: timeStepFactor must be 1 or greater.\n", + COLVARS_INPUT_ERROR); } // Use the scaling factors from a grid? @@ -124,25 +126,17 @@ int colvarbias::init(std::string const &conf) std::string biasing_force_scaling_factors_in_filename; get_keyval(conf, "scaledBiasingForceFactorsGrid", biasing_force_scaling_factors_in_filename, std::string()); - std::ifstream is; - cvm::log("Reading scaling factors for the forces of bias " + - name + " from " + biasing_force_scaling_factors_in_filename); - is.open(biasing_force_scaling_factors_in_filename.c_str()); - if (!is.is_open()) { - cvm::error("Error opening the grid file " + - biasing_force_scaling_factors_in_filename + " for reading"); - } biasing_force_scaling_factors = new colvar_grid_scalar(colvars); - biasing_force_scaling_factors->read_multicol(is, true); + error_code |= biasing_force_scaling_factors->read_multicol(biasing_force_scaling_factors_in_filename, + "grid file"); biasing_force_scaling_factors_bin.assign(num_variables(), 0); - is.close(); } // Now that children are defined, we can solve dependencies enable(f_cvb_active); if (cvm::debug()) print_state(); - return COLVARS_OK; + return error_code; } @@ -377,10 +371,11 @@ int colvarbias::calc_forces(std::vector const *) } -void colvarbias::communicate_forces() +int colvarbias::communicate_forces() { + int error_code = COLVARS_OK; if (! is_enabled(f_cvb_apply_force)) { - return; + return error_code; } cvm::real biasing_force_factor = 1.0; size_t i = 0; @@ -409,6 +404,7 @@ void colvarbias::communicate_forces() } previous_colvar_forces[i] = colvar_forces[i]; } + return error_code; } @@ -573,11 +569,11 @@ int colvarbias::write_state_prefix(std::string const &prefix) { std::string const filename = cvm::state_file_prefix(prefix.c_str())+".colvars.state"; - std::ostream *os = cvm::proxy->output_stream(filename.c_str()); + std::ostream &os = cvm::proxy->output_stream(filename.c_str(), "bias state file"); int error_code = COLVARS_OK; - if (os != NULL) { - os->setf(std::ios::scientific, std::ios::floatfield); - error_code = write_state(*os).good() ? COLVARS_OK : COLVARS_FILE_ERROR; + if (os) { + os.setf(std::ios::scientific, std::ios::floatfield); + error_code = write_state(os) ? COLVARS_OK : COLVARS_FILE_ERROR; } else { error_code = COLVARS_FILE_ERROR; } @@ -600,17 +596,19 @@ int colvarbias::write_state_string(std::string &output) int colvarbias::read_state_prefix(std::string const &prefix) { - std::string filename((prefix+std::string(".colvars.state")).c_str()); - std::ifstream is(filename.c_str()); - if (!is.good()) { - // try without the suffix - is.clear(); + std::string filename(prefix+std::string(".colvars.state")); + std::istream *is = &(cvm::main()->proxy->input_stream(filename, + "bias state file", + false)); + if (!*is) { filename = prefix; - is.open(filename.c_str()); + is = &(cvm::main()->proxy->input_stream(filename, "bias state file")); } - return read_state(is).good() ? COLVARS_OK : - cvm::error("Error: in reading state for \""+name+"\" from input file \""+ - std::string(filename)+"\".\n", COLVARS_FILE_ERROR); + + if (read_state(*is)) { + return cvm::main()->proxy->close_input_stream(filename); + } + return COLVARS_FILE_ERROR; } @@ -899,6 +897,8 @@ std::istream & colvarbias_ti::read_state_data(std::istream &is) int colvarbias_ti::write_output_files() { + int error_code = COLVARS_OK; + if (!has_data) { // nothing to write return COLVARS_OK; @@ -906,38 +906,30 @@ int colvarbias_ti::write_output_files() std::string const ti_output_prefix = cvm::output_prefix()+"."+this->name; - std::ostream *os = NULL; - if (is_enabled(f_cvb_write_ti_samples)) { std::string const ti_count_file_name(ti_output_prefix+".ti.count"); - os = cvm::proxy->output_stream(ti_count_file_name); - if (os) { - ti_count->write_multicol(*os); - cvm::proxy->close_output_stream(ti_count_file_name); - } + error_code |= ti_count->write_multicol(ti_count_file_name, "TI count file"); std::string const ti_grad_file_name(ti_output_prefix+".ti.force"); - os = cvm::proxy->output_stream(ti_grad_file_name); - if (os) { - ti_avg_forces->write_multicol(*os); - cvm::proxy->close_output_stream(ti_grad_file_name); - } + error_code |= ti_avg_forces->write_multicol(ti_grad_file_name, "TI gradient file"); } if (is_enabled(f_cvb_write_ti_pmf)) { std::string const pmf_file_name(ti_output_prefix+".ti.pmf"); cvm::log("Writing TI PMF to file \""+pmf_file_name+"\".\n"); - os = cvm::proxy->output_stream(pmf_file_name); + std::ostream &os = cvm::proxy->output_stream(pmf_file_name, "TI PMF"); if (os) { // get the FE gradient ti_avg_forces->multiply_constant(-1.0); - ti_avg_forces->write_1D_integral(*os); + ti_avg_forces->write_1D_integral(os); ti_avg_forces->multiply_constant(-1.0); cvm::proxy->close_output_stream(pmf_file_name); + } else { + error_code |= COLVARS_FILE_ERROR; } } - return COLVARS_OK; + return error_code; } diff --git a/lib/colvars/colvarbias.h b/lib/colvars/colvarbias.h index ecb3e1eff1..e865902be6 100644 --- a/lib/colvars/colvarbias.h +++ b/lib/colvars/colvarbias.h @@ -73,7 +73,7 @@ public: virtual int calc_forces(std::vector const *values); /// Send forces to the collective variables - void communicate_forces(); + int communicate_forces(); /// Carry out operations needed before next step is run virtual int end_of_step(); diff --git a/lib/colvars/colvarbias_abf.cpp b/lib/colvars/colvarbias_abf.cpp index 5cb5e7af24..7d6b7b7fef 100644 --- a/lib/colvars/colvarbias_abf.cpp +++ b/lib/colvars/colvarbias_abf.cpp @@ -7,6 +7,8 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. +#include + #include "colvarmodule.h" #include "colvar.h" #include "colvarbias_abf.h" @@ -38,17 +40,17 @@ colvarbias_abf::colvarbias_abf(char const *key) int colvarbias_abf::init(std::string const &conf) { + colvarproxy *proxy = cvm::main()->proxy; + colvarbias::init(conf); cvm::main()->cite_feature("ABF colvar bias implementation"); - colvarproxy *proxy = cvm::main()->proxy; - enable(f_cvb_scalar_variables); enable(f_cvb_calc_pmf); - // TODO relax this in case of VMD plugin - if (cvm::temperature() == 0.0) + if ((proxy->target_temperature() == 0.0) && proxy->simulation_running()) { cvm::log("WARNING: ABF should not be run without a thermostat or at 0 Kelvin!\n"); + } // ************* parsing general ABF options *********************** @@ -277,7 +279,7 @@ int colvarbias_abf::init(std::string const &conf) cvm::restart_out_freq, UI_restart, // whether restart from a .count and a .grad file input_prefix, // the prefixes of input files - cvm::temperature()); + proxy->target_temperature()); } } @@ -599,17 +601,17 @@ int colvarbias_abf::replica_share() { template int colvarbias_abf::write_grid_to_file(T const *grid, std::string const &filename, bool close) { - std::ostream *os = cvm::proxy->output_stream(filename); + std::ostream &os = cvm::proxy->output_stream(filename); if (!os) { return cvm::error("Error opening file " + filename + " for writing.\n", COLVARS_ERROR | COLVARS_FILE_ERROR); } - grid->write_multicol(*os); + grid->write_multicol(os); if (close) { cvm::proxy->close_output_stream(filename); } else { // Insert empty line between frames in history files - *os << std::endl; - cvm::proxy->flush_output_stream(os); + os << std::endl; + cvm::proxy->flush_output_stream(filename); } // In dimension higher than 2, dx is easier to handle and visualize @@ -617,11 +619,11 @@ template int colvarbias_abf::write_grid_to_file(T const *grid, // (could be implemented as multiple dx files) if (num_variables() > 2 && close) { std::string dx = filename + ".dx"; - std::ostream *dx_os = cvm::proxy->output_stream(dx); + std::ostream &dx_os = cvm::proxy->output_stream(dx); if (!dx_os) { return cvm::error("Error opening file " + dx + " for writing.\n", COLVARS_ERROR | COLVARS_FILE_ERROR); } - grid->write_opendx(*dx_os); + grid->write_opendx(dx_os); // if (close) { cvm::proxy->close_output_stream(dx); // } @@ -637,6 +639,8 @@ template int colvarbias_abf::write_grid_to_file(T const *grid, void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool close) { + colvarproxy *proxy = cvm::main()->proxy; + write_grid_to_file(samples, prefix + ".count", close); write_grid_to_file(gradients, prefix + ".grad", close); @@ -660,7 +664,7 @@ void colvarbias_abf::write_gradients_samples(const std::string &prefix, bool clo czar_gradients->index_ok(ix); czar_gradients->incr(ix)) { for (size_t n = 0; n < czar_gradients->multiplicity(); n++) { czar_gradients->set_value(ix, z_gradients->value_output(ix, n) - - cvm::temperature() * cvm::boltzmann() * z_samples->log_gradient_finite_diff(ix, n), n); + - proxy->target_temperature() * proxy->boltzmann() * z_samples->log_gradient_finite_diff(ix, n), n); } } write_grid_to_file(czar_gradients, prefix + ".czar.grad", close); @@ -698,8 +702,10 @@ int colvarbias_abf::bin_count(int bin_index) { } -void colvarbias_abf::read_gradients_samples() +int colvarbias_abf::read_gradients_samples() { + int error_code = COLVARS_OK; + std::string samples_in_name, gradients_in_name, z_samples_in_name, z_gradients_in_name; for ( size_t i = 0; i < input_prefix.size(); i++ ) { @@ -708,43 +714,30 @@ void colvarbias_abf::read_gradients_samples() z_samples_in_name = input_prefix[i] + ".zcount"; z_gradients_in_name = input_prefix[i] + ".zgrad"; // For user-provided files, the per-bias naming scheme may not apply + cvm::log("Reading sample count from " + samples_in_name + + " and gradient from " + gradients_in_name); - std::ifstream is; + error_code |= samples->read_multicol(samples_in_name, + "ABF samples file", + true); - cvm::log("Reading sample count from " + samples_in_name + " and gradient from " + gradients_in_name); - is.open(samples_in_name.c_str()); - if (!is.is_open()) cvm::error("Error opening ABF samples file " + samples_in_name + " for reading"); - samples->read_multicol(is, true); - is.close(); - is.clear(); - - is.open(gradients_in_name.c_str()); - if (!is.is_open()) { - cvm::error("Error opening ABF gradient file " + - gradients_in_name + " for reading", COLVARS_INPUT_ERROR); - } else { - gradients->read_multicol(is, true); - is.close(); - } + error_code |= gradients->read_multicol(gradients_in_name, + "ABF gradient file", + true); if (b_CZAR_estimator) { // Read eABF z-averaged data for CZAR cvm::log("Reading z-histogram from " + z_samples_in_name + " and z-gradient from " + z_gradients_in_name); - - is.clear(); - is.open(z_samples_in_name.c_str()); - if (!is.is_open()) cvm::error("Error opening eABF z-histogram file " + z_samples_in_name + " for reading"); - z_samples->read_multicol(is, true); - is.close(); - is.clear(); - - is.open(z_gradients_in_name.c_str()); - if (!is.is_open()) cvm::error("Error opening eABF z-gradient file " + z_gradients_in_name + " for reading"); - z_gradients->read_multicol(is, true); - is.close(); + error_code |= z_samples->read_multicol(z_samples_in_name, + "eABF z-histogram file", + true); + error_code |= z_gradients->read_multicol(z_gradients_in_name, + "eABF z-gradient file", + true); } } - return; + + return error_code; } diff --git a/lib/colvars/colvarbias_abf.h b/lib/colvars/colvarbias_abf.h index 3a3120a058..f5d5bd267f 100644 --- a/lib/colvars/colvarbias_abf.h +++ b/lib/colvars/colvarbias_abf.h @@ -155,7 +155,7 @@ private: void write_gradients_samples(const std::string &prefix, bool close = true); /// Read human-readable FE gradients and sample count (if not using restart) - void read_gradients_samples(); + int read_gradients_samples(); /// Template used in write_gradient_samples() template int write_grid_to_file(T const *grid, diff --git a/lib/colvars/colvarbias_alb.cpp b/lib/colvars/colvarbias_alb.cpp index 5f39b0d93a..b432659bf4 100644 --- a/lib/colvars/colvarbias_alb.cpp +++ b/lib/colvars/colvarbias_alb.cpp @@ -7,9 +7,12 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. +#include +#include #include #include "colvarmodule.h" +#include "colvarproxy.h" #include "colvarbias.h" #include "colvarbias_alb.h" @@ -36,6 +39,7 @@ colvarbias_alb::colvarbias_alb(char const *key) int colvarbias_alb::init(std::string const &conf) { + colvarproxy *proxy = cvm::main()->proxy; colvarbias::init(conf); cvm::main()->cite_feature("ALB colvar bias implementation"); @@ -110,10 +114,12 @@ int colvarbias_alb::init(std::string const &conf) if (!get_keyval(conf, "forceRange", max_coupling_range, max_coupling_range)) { //set to default for (i = 0; i < num_variables(); i++) { - if (cvm::temperature() > 0) - max_coupling_range[i] = 3 * cvm::temperature() * cvm::boltzmann(); - else - max_coupling_range[i] = 3 * cvm::boltzmann(); + if (proxy->target_temperature() > 0.0) { + max_coupling_range[i] = 3 * proxy->target_temperature() * + proxy->boltzmann(); + } else { + max_coupling_range[i] = 3 * proxy->boltzmann(); + } } } @@ -139,6 +145,7 @@ colvarbias_alb::~colvarbias_alb() int colvarbias_alb::update() { + colvarproxy *proxy = cvm::main()->proxy; bias_energy = 0.0; update_calls++; @@ -214,10 +221,11 @@ int colvarbias_alb::update() temp = 2. * (means[i] / (static_cast (colvar_centers[i])) - 1) * ssd[i] / (update_calls - 1); - if (cvm::temperature() > 0) - step_size = temp / (cvm::temperature() * cvm::boltzmann()); - else - step_size = temp / cvm::boltzmann(); + if (proxy->target_temperature() > 0.0) { + step_size = temp / (proxy->target_temperature() * proxy->boltzmann()); + } else { + step_size = temp / proxy->boltzmann(); + } means[i] = 0; ssd[i] = 0; diff --git a/lib/colvars/colvarbias_histogram.cpp b/lib/colvars/colvarbias_histogram.cpp index 2719489560..84f1a5bdee 100644 --- a/lib/colvars/colvarbias_histogram.cpp +++ b/lib/colvars/colvarbias_histogram.cpp @@ -179,31 +179,19 @@ int colvarbias_histogram::write_output_files() return COLVARS_OK; } + int error_code = COLVARS_OK; + if (out_name.size() && out_name != "none") { cvm::log("Writing the histogram file \""+out_name+"\".\n"); - cvm::backup_file(out_name.c_str()); - std::ostream *grid_os = cvm::proxy->output_stream(out_name); - if (!grid_os) { - return cvm::error("Error opening histogram file "+out_name+ - " for writing.\n", COLVARS_FILE_ERROR); - } - grid->write_multicol(*grid_os); - cvm::proxy->close_output_stream(out_name); + error_code |= grid->write_multicol(out_name, "histogram output file"); } if (out_name_dx.size() && out_name_dx != "none") { cvm::log("Writing the histogram file \""+out_name_dx+"\".\n"); - cvm::backup_file(out_name_dx.c_str()); - std::ostream *grid_os = cvm::proxy->output_stream(out_name_dx); - if (!grid_os) { - return cvm::error("Error opening histogram file "+out_name_dx+ - " for writing.\n", COLVARS_FILE_ERROR); - } - grid->write_opendx(*grid_os); - cvm::proxy->close_output_stream(out_name_dx); + error_code |= grid->write_opendx(out_name_dx, "histogram DX output file"); } - return COLVARS_OK; + return error_code; } diff --git a/lib/colvars/colvarbias_histogram_reweight_amd.cpp b/lib/colvars/colvarbias_histogram_reweight_amd.cpp index 97c278abcb..85f1bde35c 100644 --- a/lib/colvars/colvarbias_histogram_reweight_amd.cpp +++ b/lib/colvars/colvarbias_histogram_reweight_amd.cpp @@ -81,6 +81,7 @@ int colvarbias_reweightaMD::init(std::string const &conf) { } int colvarbias_reweightaMD::update() { + colvarproxy *proxy = cvm::main()->proxy; int error_code = COLVARS_OK; if (cvm::step_relative() >= start_after_steps) { // update base class @@ -110,7 +111,7 @@ int colvarbias_reweightaMD::update() { grid->acc_value(previous_bin, reweighting_factor); if (b_use_cumulant_expansion) { const cvm::real dV = cvm::logn(reweighting_factor) * - cvm::temperature() * cvm::boltzmann(); + proxy->target_temperature() * proxy->boltzmann(); grid_dV->acc_value(previous_bin, dV); grid_dV_square->acc_value(previous_bin, dV * dV); } @@ -129,7 +130,7 @@ int colvarbias_reweightaMD::update() { grid->acc_value(previous_bin, reweighting_factor); if (b_use_cumulant_expansion) { const cvm::real dV = cvm::logn(reweighting_factor) * - cvm::temperature() * cvm::boltzmann(); + proxy->target_temperature() * proxy->boltzmann(); grid_dV->acc_value(previous_bin, dV); grid_dV_square->acc_value(previous_bin, dV * dV); } @@ -138,10 +139,6 @@ int colvarbias_reweightaMD::update() { } previous_bin.assign(num_variables(), 0); - if (output_freq && (cvm::step_absolute() % output_freq) == 0) { - write_output_files(); - } - error_code |= cvm::get_error(); } return error_code; @@ -160,7 +157,7 @@ int colvarbias_reweightaMD::write_output_files() { (cvm::step_absolute() % history_freq) == 0; if (write_history) { error_code |= write_exponential_reweighted_pmf( - out_name_pmf + ".hist", (cvm::step_relative() > 0)); + out_name_pmf + ".hist", true); error_code |= write_count(out_count_prefix + ".hist", (cvm::step_relative() > 0)); } @@ -170,7 +167,7 @@ int colvarbias_reweightaMD::write_output_files() { error_code |= write_cumulant_expansion_pmf(out_name_cumulant_pmf); if (write_history) { error_code |= write_cumulant_expansion_pmf( - out_name_cumulant_pmf + ".hist", (cvm::step_relative() > 0)); + out_name_cumulant_pmf + ".hist", true); } } error_code |= cvm::get_error(); @@ -178,17 +175,13 @@ int colvarbias_reweightaMD::write_output_files() { } int colvarbias_reweightaMD::write_exponential_reweighted_pmf( - const std::string& p_output_prefix, bool append) { + const std::string& p_output_prefix, bool keep_open) { const std::string output_pmf = p_output_prefix + ".pmf"; + cvm::log("Writing the accelerated MD PMF file \"" + output_pmf + "\".\n"); - if (!append) { - cvm::backup_file(output_pmf.c_str()); - } - const std::ios::openmode mode = (append ? std::ios::app : std::ios::out); - std::ostream *pmf_grid_os = cvm::proxy->output_stream(output_pmf, mode); + std::ostream &pmf_grid_os = cvm::proxy->output_stream(output_pmf, "PMF file"); if (!pmf_grid_os) { - return cvm::error("Error opening PMF file " + output_pmf + - " for writing.\n", COLVARS_FILE_ERROR); + return COLVARS_FILE_ERROR; } pmf_grid_exp_avg->copy_grid(*grid); // compute the average @@ -200,19 +193,18 @@ int colvarbias_reweightaMD::write_exponential_reweighted_pmf( } } hist_to_pmf(pmf_grid_exp_avg, grid_count); - pmf_grid_exp_avg->write_multicol(*pmf_grid_os); - cvm::proxy->close_output_stream(output_pmf); + pmf_grid_exp_avg->write_multicol(pmf_grid_os); + if (!keep_open) { + cvm::proxy->close_output_stream(output_pmf); + } + if (b_write_gradients) { const std::string output_grad = p_output_prefix + ".grad"; cvm::log("Writing the accelerated MD gradients file \"" + output_grad + "\".\n"); - if (!append) { - cvm::backup_file(output_grad.c_str()); - } - std::ostream *grad_grid_os = cvm::proxy->output_stream(output_grad, mode); + std::ostream &grad_grid_os = cvm::proxy->output_stream(output_grad, "gradient file"); if (!grad_grid_os) { - return cvm::error("Error opening grad file " + output_grad + - " for writing.\n", COLVARS_FILE_ERROR); + return COLVARS_FILE_ERROR; } for (std::vector ix = grad_grid_exp_avg->new_index(); grad_grid_exp_avg->index_ok(ix); grad_grid_exp_avg->incr(ix)) { @@ -221,38 +213,37 @@ int colvarbias_reweightaMD::write_exponential_reweighted_pmf( ix, pmf_grid_exp_avg->gradient_finite_diff(ix, n), n); } } - grad_grid_exp_avg->write_multicol(*grad_grid_os); - cvm::proxy->close_output_stream(output_grad); + grad_grid_exp_avg->write_multicol(grad_grid_os); + if (!keep_open) { + cvm::proxy->close_output_stream(output_grad); + } } + return COLVARS_OK; } int colvarbias_reweightaMD::write_cumulant_expansion_pmf( - const std::string& p_output_prefix, bool append) { + const std::string& p_output_prefix, bool keep_open) { const std::string output_pmf = p_output_prefix + ".pmf"; cvm::log("Writing the accelerated MD PMF file using cumulant expansion: \"" + output_pmf + "\".\n"); - if (!append) cvm::backup_file(output_pmf.c_str()); - const std::ios::openmode mode = (append ? std::ios::app : std::ios::out); - std::ostream *pmf_grid_cumulant_os = cvm::proxy->output_stream(output_pmf, mode); + std::ostream &pmf_grid_cumulant_os = cvm::proxy->output_stream(output_pmf, "PMF file"); if (!pmf_grid_cumulant_os) { - return cvm::error("Error opening PMF file " + output_pmf + - " for writing.\n", COLVARS_FILE_ERROR); + return COLVARS_FILE_ERROR; } compute_cumulant_expansion_factor(grid_dV, grid_dV_square, grid_count, pmf_grid_cumulant); hist_to_pmf(pmf_grid_cumulant, grid_count); - pmf_grid_cumulant->write_multicol(*pmf_grid_cumulant_os); - cvm::proxy->close_output_stream(output_pmf); + pmf_grid_cumulant->write_multicol(pmf_grid_cumulant_os); + if (!keep_open) { + cvm::proxy->close_output_stream(output_pmf); + } + if (b_write_gradients) { const std::string output_grad = p_output_prefix + ".grad"; cvm::log("Writing the accelerated MD gradients file \"" + output_grad + "\".\n"); - if (!append) { - cvm::backup_file(output_grad.c_str()); - } - std::ostream *grad_grid_os = cvm::proxy->output_stream(output_grad, mode); + std::ostream &grad_grid_os = cvm::proxy->output_stream(output_grad, "grad file"); if (!grad_grid_os) { - return cvm::error("Error opening grad file " + output_grad + - " for writing.\n", COLVARS_FILE_ERROR); + return COLVARS_FILE_ERROR; } for (std::vector ix = grad_grid_cumulant->new_index(); grad_grid_cumulant->index_ok(ix); grad_grid_cumulant->incr(ix)) { @@ -261,31 +252,33 @@ int colvarbias_reweightaMD::write_cumulant_expansion_pmf( ix, pmf_grid_cumulant->gradient_finite_diff(ix, n), n); } } - grad_grid_cumulant->write_multicol(*grad_grid_os); + grad_grid_cumulant->write_multicol(grad_grid_os); cvm::proxy->close_output_stream(output_grad); } return COLVARS_OK; } -int colvarbias_reweightaMD::write_count(const std::string& p_output_prefix, bool append) { +int colvarbias_reweightaMD::write_count(const std::string& p_output_prefix, bool keep_open) { const std::string output_name = p_output_prefix + ".count"; cvm::log("Writing the accelerated MD count file \""+output_name+"\".\n"); - if (!append) cvm::backup_file(output_name.c_str()); - const std::ios::openmode mode = (append ? std::ios::app : std::ios::out); - std::ostream *grid_count_os = cvm::proxy->output_stream(output_name, mode); + std::ostream &grid_count_os = cvm::proxy->output_stream(output_name, "count file"); if (!grid_count_os) { - return cvm::error("Error opening count file "+output_name+ - " for writing.\n", COLVARS_FILE_ERROR); + return COLVARS_FILE_ERROR; + } + grid_count->write_multicol(grid_count_os); + if (!keep_open) { + cvm::proxy->close_output_stream(output_name); } - grid_count->write_multicol(*grid_count_os); - cvm::proxy->close_output_stream(output_name); return COLVARS_OK; } void colvarbias_reweightaMD::hist_to_pmf( - colvar_grid_scalar* hist, const colvar_grid_scalar* hist_count) const { + colvar_grid_scalar* hist, + const colvar_grid_scalar* hist_count) const +{ + colvarproxy *proxy = cvm::main()->proxy; if (hist->raw_data_num() == 0) return; - const cvm::real kbt = cvm::boltzmann() * cvm::temperature(); + const cvm::real kbt = proxy->boltzmann() * proxy->target_temperature(); bool first_min_element = true; bool first_max_element = true; cvm::real min_element = 0; @@ -329,12 +322,15 @@ void colvarbias_reweightaMD::hist_to_pmf( } } + void colvarbias_reweightaMD::compute_cumulant_expansion_factor( const colvar_grid_scalar* hist_dV, const colvar_grid_scalar* hist_dV_square, const colvar_grid_scalar* hist_count, - colvar_grid_scalar* cumulant_expansion_factor) const { - const cvm::real beta = 1.0 / (cvm::boltzmann() * cvm::temperature()); + colvar_grid_scalar* cumulant_expansion_factor) const +{ + colvarproxy *proxy = cvm::main()->proxy; + const cvm::real beta = 1.0 / (proxy->boltzmann() * proxy->target_temperature()); size_t i = 0; for (i = 0; i < hist_dV->raw_data_num(); ++i) { const cvm::real count = hist_count->value(i); diff --git a/lib/colvars/colvarbias_histogram_reweight_amd.h b/lib/colvars/colvarbias_histogram_reweight_amd.h index 8d74b5315d..f126738305 100644 --- a/lib/colvars/colvarbias_histogram_reweight_amd.h +++ b/lib/colvars/colvarbias_histogram_reweight_amd.h @@ -51,21 +51,21 @@ public: /// @brief output the PMF by the exponential average estimator /// @param[in] p_output_prefix the prefix of the output file - /// @param[in] append append the output to a .hist file if true + /// @param[in] keep_open Allow writing the history of the PMF virtual int write_exponential_reweighted_pmf( - const std::string& p_output_prefix, bool append = false); + const std::string& p_output_prefix, bool keep_open = false); /// @brief output the PMF by the cumulant expansion estimator /// @param[in] p_output_prefix the prefix of the output file - /// @param[in] append append the output to a .hist file if true + /// @param[in] keep_open Allow writing the history of the expansion virtual int write_cumulant_expansion_pmf( - const std::string& p_output_prefix, bool append = false); + const std::string& p_output_prefix, bool keep_open = false); /// @brief output the biased sampling /// @param[in] p_output_prefix the prefix of the output file - /// @param[in] append append the output to a .hist file if true + /// @param[in] keep_open Allow writing the history of the samples virtual int write_count( - const std::string& p_output_prefix, bool append = false); + const std::string& p_output_prefix, bool keep_open = false); protected: /// Current accelMD factor is the from previous frame std::vector previous_bin; diff --git a/lib/colvars/colvarbias_meta.cpp b/lib/colvars/colvarbias_meta.cpp index 0b31479276..90497bf150 100644 --- a/lib/colvars/colvarbias_meta.cpp +++ b/lib/colvars/colvarbias_meta.cpp @@ -36,7 +36,6 @@ colvarbias_meta::colvarbias_meta(char const *key) : colvarbias(key), colvarbias_ti(key) { new_hills_begin = hills.end(); - hills_traj_os = NULL; hill_weight = 0.0; hill_width = 0.0; @@ -268,28 +267,31 @@ int colvarbias_meta::init_well_tempered_params(std::string const &conf) int colvarbias_meta::init_ebmeta_params(std::string const &conf) { + int error_code = COLVARS_OK; // for ebmeta target_dist = NULL; get_keyval(conf, "ebMeta", ebmeta, false); if(ebmeta){ cvm::main()->cite_feature("Ensemble-biased metadynamics (ebMetaD)"); if (use_grids && expand_grids) { - cvm::error("Error: expandBoundaries is not supported with " - "ebMeta please allocate wide enough boundaries for " - "each colvar ahead of time and set targetdistfile " - "accordingly.\n", COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: expandBoundaries is not supported with " + "ebMeta; please allocate wide enough boundaries " + "for each colvar ahead of time and set " + "targetDistFile accordingly.\n", + COLVARS_INPUT_ERROR); } target_dist = new colvar_grid_scalar(); - target_dist->init_from_colvars(colvars); + error_code |= target_dist->init_from_colvars(colvars); std::string target_dist_file; get_keyval(conf, "targetDistFile", target_dist_file); - std::ifstream targetdiststream(target_dist_file.c_str()); - target_dist->read_multicol(targetdiststream); + error_code |= target_dist->read_multicol(target_dist_file, + "ebMeta target histogram"); cvm::real min_val = target_dist->minimum_value(); cvm::real max_val = target_dist->maximum_value(); - if(min_val<0){ - cvm::error("Error: Target distribution of EBMetaD " - "has negative values!.\n", COLVARS_INPUT_ERROR); + if (min_val < 0.0) { + error_code |= cvm::error("Error: Target distribution of EBMetaD " + "has negative values!.\n", + COLVARS_INPUT_ERROR); } cvm::real target_dist_min_val; get_keyval(conf, "targetDistMinVal", target_dist_min_val, 1/1000000.0); @@ -301,17 +303,19 @@ int colvarbias_meta::init_ebmeta_params(std::string const &conf) cvm::log("NOTE: targetDistMinVal is set to zero, the minimum value of the target \n"); cvm::log(" distribution will be set as the minimum positive value.\n"); cvm::real min_pos_val = target_dist->minimum_pos_value(); - if(min_pos_val<=0){ - cvm::error("Error: Target distribution of EBMetaD has negative " - "or zero minimum positive value!.\n", COLVARS_INPUT_ERROR); + if (min_pos_val <= 0.0){ + error_code |= cvm::error("Error: Target distribution of EBMetaD has " + "negative or zero minimum positive value.\n", + COLVARS_INPUT_ERROR); } - if(min_val==0){ + if (min_val == 0.0){ cvm::log("WARNING: Target distribution has zero values.\n"); cvm::log("Zeros will be converted to the minimum positive value.\n"); target_dist->remove_small_values(min_pos_val); } } else { - cvm::error("Error: targetDistMinVal must be a value between 0 and 1!.\n", COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: targetDistMinVal must be a value " + "between 0 and 1.\n", COLVARS_INPUT_ERROR); } } // normalize target distribution and multiply by effective volume = exp(differential entropy) @@ -321,23 +325,18 @@ int colvarbias_meta::init_ebmeta_params(std::string const &conf) get_keyval(conf, "ebMetaEquilSteps", ebmeta_equil_steps, ebmeta_equil_steps); } - return COLVARS_OK; + return error_code; } colvarbias_meta::~colvarbias_meta() { colvarbias_meta::clear_state_data(); - colvarproxy *proxy = cvm::proxy; + colvarproxy *proxy = cvm::main()->proxy; - if (proxy->get_output_stream(replica_hills_file)) { - proxy->close_output_stream(replica_hills_file); - } + proxy->close_output_stream(replica_hills_file); - if (hills_traj_os) { - proxy->close_output_stream(hills_traj_file_name()); - hills_traj_os = NULL; - } + proxy->close_output_stream(hills_traj_file_name()); if (target_dist) { delete target_dist; @@ -392,9 +391,12 @@ colvarbias_meta::add_hill(colvarbias_meta::hill const &h) } // output to trajectory (if specified) - if (hills_traj_os) { - *hills_traj_os << (hills.back()).output_traj(); - cvm::proxy->flush_output_stream(hills_traj_os); + if (b_hills_traj) { + // Open trajectory file or access the one already open + std::ostream &hills_traj_os = + cvm::proxy->output_stream(hills_traj_file_name()); + hills_traj_os << (hills.back()).output_traj(); + cvm::proxy->flush_output_stream(hills_traj_file_name()); } has_data = true; @@ -424,12 +426,14 @@ colvarbias_meta::delete_hill(hill_iter &h) } } - if (hills_traj_os) { + if (b_hills_traj) { // output to the trajectory - *hills_traj_os << "# DELETED this hill: " - << (hills.back()).output_traj() - << "\n"; - cvm::proxy->flush_output_stream(hills_traj_os); + std::ostream &hills_traj_os = + cvm::proxy->output_stream(hills_traj_file_name()); + hills_traj_os << "# DELETED this hill: " + << (hills.back()).output_traj() + << "\n"; + cvm::proxy->flush_output_stream(hills_traj_file_name()); } return hills.erase(h); @@ -573,6 +577,7 @@ int colvarbias_meta::update_grid_params() int colvarbias_meta::update_bias() { + colvarproxy *proxy = cvm::main()->proxy; // add a new hill if the required time interval has passed if (((cvm::step_absolute() % new_hill_freq) == 0) && can_accumulate_data() && is_enabled(f_cvb_history_dependent)) { @@ -603,7 +608,7 @@ int colvarbias_meta::update_bias() } else { calc_hills(new_hills_begin, hills.end(), hills_energy_sum_here, NULL); } - hills_scale *= cvm::exp(-1.0*hills_energy_sum_here/(bias_temperature*cvm::boltzmann())); + hills_scale *= cvm::exp(-1.0*hills_energy_sum_here/(bias_temperature*proxy->boltzmann())); } switch (comm) { @@ -618,10 +623,10 @@ int colvarbias_meta::update_bias() case multiple_replicas: add_hill(hill(cvm::step_absolute(), hill_weight*hills_scale, colvar_values, colvar_sigmas, replica_id)); - std::ostream *replica_hills_os = - cvm::proxy->get_output_stream(replica_hills_file); + std::ostream &replica_hills_os = + cvm::proxy->output_stream(replica_hills_file); if (replica_hills_os) { - *replica_hills_os << hills.back(); + replica_hills_os << hills.back(); } else { return cvm::error("Error: in metadynamics bias \""+this->name+"\""+ ((comm != single_replica) ? ", replica \""+replica_id+"\"" : "")+ @@ -979,25 +984,24 @@ void colvarbias_meta::recount_hills_off_grid(colvarbias_meta::hill_iter h_first int colvarbias_meta::replica_share() { + int error_code = COLVARS_OK; colvarproxy *proxy = cvm::proxy; // sync with the other replicas (if needed) if (comm == multiple_replicas) { // reread the replicas registry - update_replicas_registry(); + error_code |= update_replicas_registry(); // empty the output buffer - std::ostream *replica_hills_os = - proxy->get_output_stream(replica_hills_file); - if (replica_hills_os) { - proxy->flush_output_stream(replica_hills_os); - } - read_replica_files(); + error_code |= proxy->flush_output_stream(replica_hills_file); + error_code |= read_replica_files(); } - return COLVARS_OK; + return error_code; } -void colvarbias_meta::update_replicas_registry() +int colvarbias_meta::update_replicas_registry() { + int error_code = COLVARS_OK; + if (cvm::debug()) cvm::log("Metadynamics bias \""+this->name+"\""+ ": updating the list of replicas, currently containing "+ @@ -1012,8 +1016,9 @@ void colvarbias_meta::update_replicas_registry() while (colvarparse::getline_nocomments(reg_file, line)) replicas_registry.append(line+"\n"); } else { - cvm::error("Error: failed to open file \""+replicas_registry_file+ - "\" for reading.\n", COLVARS_FILE_ERROR); + error_code |= cvm::error("Error: failed to open file \""+ + replicas_registry_file+"\" for reading.\n", + COLVARS_FILE_ERROR); } } @@ -1081,8 +1086,8 @@ void colvarbias_meta::update_replicas_registry() } } } else { - cvm::error("Error: cannot read the replicas registry file \""+ - replicas_registry+"\".\n", COLVARS_FILE_ERROR); + error_code |= cvm::error("Error: cannot read the replicas registry file \""+ + replicas_registry+"\".\n", COLVARS_FILE_ERROR); } // now (re)read the list file of each replica @@ -1122,10 +1127,12 @@ void colvarbias_meta::update_replicas_registry() if (cvm::debug()) cvm::log("Metadynamics bias \""+this->name+"\": the list of replicas contains "+ cvm::to_str(replicas.size())+" elements.\n"); + + return error_code; } -void colvarbias_meta::read_replica_files() +int colvarbias_meta::read_replica_files() { // Note: we start from the 2nd replica. for (size_t ir = 1; ir < replicas.size(); ir++) { @@ -1250,6 +1257,7 @@ void colvarbias_meta::read_replica_files() " steps. Ensure that it is still running.\n"); } } + return COLVARS_OK; } @@ -1413,6 +1421,10 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is) size_t const old_hills_size = hills.size(); hill_iter old_hills_end = hills.end(); hill_iter old_hills_off_grid_end = hills_off_grid.end(); + if (cvm::debug()) { + cvm::log("Before reading hills from the state file, there are "+ + cvm::to_str(hills.size())+" hills in memory.\n"); + } // Read any hills following the grid data (if any) while (read_hill(is)) { @@ -1431,6 +1443,10 @@ std::istream & colvarbias_meta::read_state_data(std::istream& is) if (existing_hills) { hills.erase(hills.begin(), old_hills_end); hills_off_grid.erase(hills_off_grid.begin(), old_hills_off_grid_end); + if (cvm::debug()) { + cvm::log("After pruning the old hills, there are now "+ + cvm::to_str(hills.size())+" hills in memory.\n"); + } } if (rebin_grids) { @@ -1614,6 +1630,8 @@ std::istream & colvarbias_meta::read_hill(std::istream &is) int colvarbias_meta::setup_output() { + int error_code = COLVARS_OK; + output_prefix = cvm::output_prefix(); if (cvm::main()->num_biases_feature(colvardeps::f_cvb_calc_pmf) > 1) { // if this is not the only free energy integrator, append @@ -1626,8 +1644,11 @@ int colvarbias_meta::setup_output() // TODO: one may want to specify the path manually for intricated filesystems? char *pwd = new char[3001]; - if (GETCWD(pwd, 3000) == NULL) - cvm::error("Error: cannot get the path of the current working directory.\n"); + if (GETCWD(pwd, 3000) == NULL) { + return cvm::error("Error: cannot get the path of the current working directory.\n", + COLVARS_BUG_ERROR); + } + replica_list_file = (std::string(pwd)+std::string(PATHSEP)+ this->name+"."+replica_id+".files.txt"); @@ -1680,38 +1701,35 @@ int colvarbias_meta::setup_output() // if we're running without grids, use a growing list of "hills" files // otherwise, just one state file and one "hills" file as buffer - std::ostream *list_os = - cvm::proxy->output_stream(replica_list_file, - (use_grids ? std::ios_base::trunc : - std::ios_base::app)); - if (!list_os) { - return cvm::get_error(); + std::ostream &list_os = cvm::proxy->output_stream(replica_list_file); + if (list_os) { + list_os << "stateFile " << replica_state_file << "\n"; + list_os << "hillsFile " << replica_hills_file << "\n"; + cvm::proxy->close_output_stream(replica_list_file); + } else { + error_code |= COLVARS_FILE_ERROR; } - *list_os << "stateFile " << replica_state_file << "\n"; - *list_os << "hillsFile " << replica_hills_file << "\n"; - cvm::proxy->close_output_stream(replica_list_file); // finally, add a new record for this replica to the registry if (! registered_replica) { - std::ostream *reg_os = - cvm::proxy->output_stream(replicas_registry_file, - std::ios::app); + std::ofstream reg_os(replicas_registry_file.c_str(), std::ios::app); if (!reg_os) { return cvm::get_error(); } - *reg_os << replica_id << " " << replica_list_file << "\n"; + reg_os << replica_id << " " << replica_list_file << "\n"; cvm::proxy->close_output_stream(replicas_registry_file); } } if (b_hills_traj) { + std::ostream &hills_traj_os = + cvm::proxy->output_stream(hills_traj_file_name()); if (!hills_traj_os) { - hills_traj_os = cvm::proxy->output_stream(hills_traj_file_name()); - if (!hills_traj_os) return cvm::get_error(); + error_code |= COLVARS_FILE_ERROR; } } - return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); + return error_code; } @@ -1804,6 +1822,7 @@ int colvarbias_meta::write_output_files() void colvarbias_meta::write_pmf() { + colvarproxy *proxy = cvm::main()->proxy; // allocate a new grid to store the pmf colvar_grid_scalar *pmf = new colvar_grid_scalar(*hills_energy); pmf->setup(); @@ -1820,7 +1839,7 @@ void colvarbias_meta::write_pmf() cvm::real target_val=target_dist->value(i); if (target_val>0) { pmf_val=pmf->value(i); - pmf_val=pmf_val+cvm::temperature() * cvm::boltzmann() * cvm::logn(target_val); + pmf_val=pmf_val + proxy->target_temperature() * proxy->boltzmann() * cvm::logn(target_val); } pmf->set_value(i,pmf_val); } @@ -1830,7 +1849,7 @@ void colvarbias_meta::write_pmf() pmf->add_constant(-1.0 * max); pmf->multiply_constant(-1.0); if (well_tempered) { - cvm::real const well_temper_scale = (bias_temperature + cvm::temperature()) / bias_temperature; + cvm::real const well_temper_scale = (bias_temperature + proxy->target_temperature()) / bias_temperature; pmf->multiply_constant(well_temper_scale); } { @@ -1839,10 +1858,7 @@ void colvarbias_meta::write_pmf() (dump_fes_save ? "."+cvm::to_str(cvm::step_absolute()) : "") + ".pmf"); - cvm::proxy->backup_file(fes_file_name); - std::ostream *fes_os = cvm::proxy->output_stream(fes_file_name); - pmf->write_multicol(*fes_os); - cvm::proxy->close_output_stream(fes_file_name); + pmf->write_multicol(fes_file_name, "PMF file"); } } @@ -1861,7 +1877,7 @@ void colvarbias_meta::write_pmf() cvm::real target_val=target_dist->value(i); if (target_val>0) { pmf_val=pmf->value(i); - pmf_val=pmf_val+cvm::temperature() * cvm::boltzmann() * cvm::logn(target_val); + pmf_val=pmf_val + proxy->target_temperature() * proxy->boltzmann() * cvm::logn(target_val); } pmf->set_value(i,pmf_val); } @@ -1871,17 +1887,14 @@ void colvarbias_meta::write_pmf() pmf->add_constant(-1.0 * max); pmf->multiply_constant(-1.0); if (well_tempered) { - cvm::real const well_temper_scale = (bias_temperature + cvm::temperature()) / bias_temperature; + cvm::real const well_temper_scale = (bias_temperature + proxy->target_temperature()) / bias_temperature; pmf->multiply_constant(well_temper_scale); } std::string const fes_file_name(this->output_prefix + (dump_fes_save ? "."+cvm::to_str(cvm::step_absolute()) : "") + ".pmf"); - cvm::proxy->backup_file(fes_file_name); - std::ostream *fes_os = cvm::proxy->output_stream(fes_file_name); - pmf->write_multicol(*fes_os); - cvm::proxy->close_output_stream(fes_file_name); + pmf->write_multicol(fes_file_name, "partial PMF file"); } delete pmf; @@ -1902,9 +1915,9 @@ int colvarbias_meta::write_replica_state_file() // Write to temporary state file std::string const tmp_state_file(replica_state_file+".tmp"); error_code |= proxy->remove_file(tmp_state_file); - std::ostream *rep_state_os = cvm::proxy->output_stream(tmp_state_file); + std::ostream &rep_state_os = cvm::proxy->output_stream(tmp_state_file); if (rep_state_os) { - if (!write_state(*rep_state_os)) { + if (!write_state(rep_state_os)) { error_code |= cvm::error("Error: in writing to temporary file \""+ tmp_state_file+"\".\n", COLVARS_FILE_ERROR); } @@ -1921,13 +1934,13 @@ int colvarbias_meta::reopen_replica_buffer_file() { int error_code = COLVARS_OK; colvarproxy *proxy = cvm::proxy; - if (proxy->get_output_stream(replica_hills_file) != NULL) { + if (proxy->output_stream(replica_hills_file)) { error_code |= proxy->close_output_stream(replica_hills_file); } error_code |= proxy->remove_file(replica_hills_file); - std::ostream *replica_hills_os = proxy->output_stream(replica_hills_file); + std::ostream &replica_hills_os = proxy->output_stream(replica_hills_file); if (replica_hills_os) { - replica_hills_os->setf(std::ios::scientific, std::ios::floatfield); + replica_hills_os.setf(std::ios::scientific, std::ios::floatfield); } else { error_code |= COLVARS_FILE_ERROR; } diff --git a/lib/colvars/colvarbias_meta.h b/lib/colvars/colvarbias_meta.h index 565534f22b..bac2ff74d4 100644 --- a/lib/colvars/colvarbias_meta.h +++ b/lib/colvars/colvarbias_meta.h @@ -12,8 +12,7 @@ #include #include -#include -#include +#include #include "colvarbias.h" #include "colvargrid.h" @@ -84,9 +83,7 @@ protected: size_t new_hill_freq; /// Write the hill logfile - bool b_hills_traj; - /// Logfile of hill management (creation and deletion) - std::ostream *hills_traj_os; + bool b_hills_traj; /// Name of the hill logfile std::string const hills_traj_file_name() const; @@ -214,10 +211,10 @@ protected: std::string replica_file_name; /// \brief Read the existing replicas on registry - virtual void update_replicas_registry(); + virtual int update_replicas_registry(); /// \brief Read new data from replicas' files - virtual void read_replica_files(); + virtual int read_replica_files(); /// Write full state information to be read by other replicas virtual int write_replica_state_file(); diff --git a/lib/colvars/colvarbias_restraint.cpp b/lib/colvars/colvarbias_restraint.cpp index 0b374db9a8..a7963c4f8f 100644 --- a/lib/colvars/colvarbias_restraint.cpp +++ b/lib/colvars/colvarbias_restraint.cpp @@ -7,6 +7,10 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. +#include +#include +#include + #include "colvarmodule.h" #include "colvarproxy.h" #include "colvarvalue.h" @@ -196,6 +200,8 @@ int colvarbias_restraint_moving::init(std::string const &conf) if (b_chg_centers || b_chg_force_k) { + first_step = cvm::step_absolute(); + get_keyval(conf, "targetNumSteps", target_nsteps, target_nsteps); if (!target_nsteps) { cvm::error("Error: targetNumSteps must be non-zero.\n", COLVARS_INPUT_ERROR); @@ -335,13 +341,17 @@ int colvarbias_restraint_centers_moving::update_centers(cvm::real lambda) int colvarbias_restraint_centers_moving::update() { + if (!cvm::main()->proxy->simulation_running()) { + return COLVARS_OK; + } + if (b_chg_centers) { if (target_nstages) { // Staged update if (stage <= target_nstages) { if ((cvm::step_relative() > 0) && - ((cvm::step_absolute() % target_nsteps) == 1)) { + (((cvm::step_absolute() - first_step) % target_nsteps) == 1)) { cvm::real const lambda = cvm::real(stage)/cvm::real(target_nstages); update_centers(lambda); @@ -358,9 +368,9 @@ int colvarbias_restraint_centers_moving::update() } } else { // Continuous update - if (cvm::step_absolute() <= target_nsteps) { + if (cvm::step_absolute() - first_step <= target_nsteps) { cvm::real const lambda = - cvm::real(cvm::step_absolute())/cvm::real(target_nsteps); + cvm::real(cvm::step_absolute() - first_step)/cvm::real(target_nsteps); update_centers(lambda); } else { for (size_t i = 0; i < num_variables(); i++) { @@ -389,10 +399,13 @@ int colvarbias_restraint_centers_moving::update() int colvarbias_restraint_centers_moving::update_acc_work() { + if (!cvm::main()->proxy->simulation_running()) { + return COLVARS_OK; + } if (b_chg_centers) { if (is_enabled(f_cvb_output_acc_work)) { if ((cvm::step_relative() > 0) && - (cvm::step_absolute() <= target_nsteps)) { + (cvm::step_absolute() - first_step <= target_nsteps)) { for (size_t i = 0; i < num_variables(); i++) { // project forces on the calculated increments at this step acc_work += colvar_forces[i] * centers_incr[i]; @@ -496,10 +509,11 @@ colvarbias_restraint_k_moving::colvarbias_restraint_k_moving(char const *key) colvarbias_restraint_moving(key) { b_chg_force_k = false; + b_decoupling = false; target_equil_steps = 0; target_force_k = -1.0; starting_force_k = -1.0; - force_k_exp = 1.0; + lambda_exp = 1.0; restraint_FE = 0.0; force_k_incr = 0.0; } @@ -509,18 +523,29 @@ int colvarbias_restraint_k_moving::init(std::string const &conf) { colvarbias_restraint_k::init(conf); + get_keyval(conf, "decoupling", b_decoupling, b_decoupling); + if (b_decoupling) { + starting_force_k = 0.0; + target_force_k = force_k; + b_chg_force_k = true; + } + if (get_keyval(conf, "targetForceConstant", target_force_k, target_force_k)) { + if (b_decoupling) { + cvm::error("Error: targetForceConstant may not be specified together with decoupling.\n", COLVARS_INPUT_ERROR); + return COLVARS_ERROR; + } starting_force_k = force_k; b_chg_force_k = true; } - if (b_chg_force_k) { - // parse moving restraint options - colvarbias_restraint_moving::init(conf); - } else { + if (!b_chg_force_k) { return COLVARS_OK; } + // parse moving restraint options + colvarbias_restraint_moving::init(conf); + get_keyval(conf, "targetEquilSteps", target_equil_steps, target_equil_steps); if (get_keyval(conf, "lambdaSchedule", lambda_schedule, lambda_schedule) && @@ -534,12 +559,13 @@ int colvarbias_restraint_k_moving::init(std::string const &conf) target_nstages = lambda_schedule.size() - 1; } - if (get_keyval(conf, "targetForceExponent", force_k_exp, force_k_exp)) { - if (! b_chg_force_k) - cvm::log("Warning: not changing force constant: targetForceExponent will be ignored\n"); + if ((get_keyval(conf, "targetForceExponent", lambda_exp, lambda_exp, parse_deprecated) + || get_keyval(conf, "lambdaExponent", lambda_exp, lambda_exp)) + && !b_chg_force_k) { + cvm::error("Error: cannot set lambdaExponent unless a changing force constant is active.\n", COLVARS_INPUT_ERROR); } - if (force_k_exp < 1.0) { - cvm::log("Warning: for all practical purposes, targetForceExponent should be 1.0 or greater.\n"); + if (lambda_exp < 1.0) { + cvm::log("Warning: for all practical purposes, lambdaExponent should be 1.0 or greater.\n"); } return COLVARS_OK; @@ -548,24 +574,27 @@ int colvarbias_restraint_k_moving::init(std::string const &conf) int colvarbias_restraint_k_moving::update() { + if (!cvm::main()->proxy->simulation_running()) { + return COLVARS_OK; + } if (b_chg_force_k) { cvm::real lambda; if (target_nstages) { - if (cvm::step_absolute() == 0) { + if (cvm::step_absolute() == first_step) { // Setup first stage of staged variable force constant calculation if (lambda_schedule.size()) { lambda = lambda_schedule[0]; } else { - lambda = 0.0; + lambda = (b_decoupling ? 1.0 : 0.0); } force_k = starting_force_k + (target_force_k - starting_force_k) - * cvm::pow(lambda, force_k_exp); + * cvm::pow(lambda, lambda_exp); cvm::log("Restraint " + this->name + ", stage " + cvm::to_str(stage) + " : lambda = " + cvm::to_str(lambda) - + ", k = " + cvm::to_str(force_k)); + + ", k = " + cvm::to_str(force_k)+"\n"); } // TI calculation: estimate free energy derivative @@ -574,9 +603,10 @@ int colvarbias_restraint_k_moving::update() lambda = lambda_schedule[stage]; } else { lambda = cvm::real(stage) / cvm::real(target_nstages); + if (b_decoupling) lambda = 1.0 - lambda; } - if (target_equil_steps == 0 || cvm::step_absolute() % target_nsteps >= target_equil_steps) { + if (target_equil_steps == 0 || (cvm::step_absolute() - first_step) % target_nsteps >= target_equil_steps) { // Start averaging after equilibration period, if requested // Derivative of energy with respect to force_k @@ -584,17 +614,17 @@ int colvarbias_restraint_k_moving::update() for (size_t i = 0; i < num_variables(); i++) { dU_dk += d_restraint_potential_dk(i); } - restraint_FE += force_k_exp * cvm::pow(lambda, force_k_exp - 1.0) + restraint_FE += lambda_exp * cvm::pow(lambda, lambda_exp - 1.0) * (target_force_k - starting_force_k) * dU_dk; } // Finish current stage... - if (cvm::step_absolute() % target_nsteps == 0 && - cvm::step_absolute() > 0) { + if ((cvm::step_absolute() - first_step) % target_nsteps == 0 && + cvm::step_absolute() > first_step) { cvm::log("Restraint " + this->name + " Lambda= " + cvm::to_str(lambda) + " dA/dLambda= " - + cvm::to_str(restraint_FE / cvm::real(target_nsteps - target_equil_steps))); + + cvm::to_str(restraint_FE / cvm::real(target_nsteps - target_equil_steps))+"\n"); // ...and move on to the next one if (stage < target_nstages) { @@ -605,23 +635,24 @@ int colvarbias_restraint_k_moving::update() lambda = lambda_schedule[stage]; } else { lambda = cvm::real(stage) / cvm::real(target_nstages); + if (b_decoupling) lambda = 1.0 - lambda; } force_k = starting_force_k + (target_force_k - starting_force_k) - * cvm::pow(lambda, force_k_exp); + * cvm::pow(lambda, lambda_exp); cvm::log("Restraint " + this->name + ", stage " + cvm::to_str(stage) + " : lambda = " + cvm::to_str(lambda) - + ", k = " + cvm::to_str(force_k)); + + ", k = " + cvm::to_str(force_k)+"\n"); } } - } else if (cvm::step_absolute() <= target_nsteps) { - + } else if (cvm::step_absolute() - first_step <= target_nsteps) { // update force constant (slow growth) - lambda = cvm::real(cvm::step_absolute()) / cvm::real(target_nsteps); + lambda = cvm::real(cvm::step_absolute() - first_step) / cvm::real(target_nsteps); + if (b_decoupling) lambda = 1.0 - lambda; cvm::real const force_k_old = force_k; force_k = starting_force_k + (target_force_k - starting_force_k) - * cvm::pow(lambda, force_k_exp); + * cvm::pow(lambda, lambda_exp); force_k_incr = force_k - force_k_old; } } @@ -632,6 +663,9 @@ int colvarbias_restraint_k_moving::update() int colvarbias_restraint_k_moving::update_acc_work() { + if (!cvm::main()->proxy->simulation_running()) { + return COLVARS_OK; + } if (b_chg_force_k) { if (is_enabled(f_cvb_output_acc_work)) { if (cvm::step_relative() > 0) { @@ -980,7 +1014,7 @@ int colvarbias_restraint_harmonic_walls::init(std::string const &conf) } // Initialize starting value of the force constant (in case it's changing) - starting_force_k = force_k; + starting_force_k = (b_decoupling ? 0.0 : force_k); if (lower_walls.size() > 0) { for (i = 0; i < num_variables(); i++) { @@ -1302,6 +1336,8 @@ colvarbias_restraint_histogram::colvarbias_restraint_histogram(char const *key) int colvarbias_restraint_histogram::init(std::string const &conf) { + int error_code = COLVARS_OK; + colvarbias::init(conf); enable(f_cvb_apply_force); @@ -1312,18 +1348,19 @@ int colvarbias_restraint_histogram::init(std::string const &conf) get_keyval(conf, "width", width, width); if (width <= 0.0) { - cvm::error("Error: \"width\" must be positive.\n", COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: \"width\" must be positive.\n", + COLVARS_INPUT_ERROR); } get_keyval(conf, "gaussianWidth", gaussian_width, 2.0 * width, colvarparse::parse_silent); get_keyval(conf, "gaussianSigma", gaussian_width, 2.0 * width); if (lower_boundary >= upper_boundary) { - cvm::error("Error: the upper boundary, "+ - cvm::to_str(upper_boundary)+ - ", is not higher than the lower boundary, "+ - cvm::to_str(lower_boundary)+".\n", - COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: the upper boundary, "+ + cvm::to_str(upper_boundary)+ + ", is not higher than the lower boundary, "+ + cvm::to_str(lower_boundary)+".\n", + COLVARS_INPUT_ERROR); } cvm::real const nbins = (upper_boundary - lower_boundary) / width; @@ -1347,22 +1384,30 @@ int colvarbias_restraint_histogram::init(std::string const &conf) get_keyval(conf, "refHistogramFile", ref_p_file, std::string("")); if (ref_p_file.size()) { if (inline_ref_p) { - cvm::error("Error: cannot specify both refHistogram and refHistogramFile at the same time.\n", - COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: cannot specify both refHistogram and refHistogramFile at the same time.\n", + COLVARS_INPUT_ERROR); } else { - std::ifstream is(ref_p_file.c_str()); + + std::istream &is = + cvm::main()->proxy->input_stream(ref_p_file, + "reference histogram file"); + std::string data_s = ""; std::string line; while (getline_nocomments(is, line)) { data_s.append(line+"\n"); } if (data_s.size() == 0) { - cvm::error("Error: file \""+ref_p_file+"\" empty or unreadable.\n", COLVARS_FILE_ERROR); + error_code |= cvm::error("Error: file \""+ref_p_file+ + "\" empty or unreadable.\n", + COLVARS_FILE_ERROR); } - is.close(); + error_code |= cvm::main()->proxy->close_input_stream(ref_p_file); + cvm::vector1d data; if (data.from_simple_string(data_s) != 0) { - cvm::error("Error: could not read histogram from file \""+ref_p_file+"\".\n"); + error_code |= cvm::error("Error: could not read histogram from file \""+ + ref_p_file+"\".\n"); } if (data.size() == 2*ref_p.size()) { // file contains both x and p(x) @@ -1373,11 +1418,13 @@ int colvarbias_restraint_histogram::init(std::string const &conf) } else if (data.size() == ref_p.size()) { ref_p = data; } else { - cvm::error("Error: file \""+ref_p_file+"\" contains a histogram of different length.\n", - COLVARS_INPUT_ERROR); + error_code |= cvm::error("Error: file \""+ref_p_file+ + "\" contains a histogram of different length.\n", + COLVARS_INPUT_ERROR); } } } + cvm::real const ref_integral = ref_p.sum() * width; if (cvm::fabs(ref_integral - 1.0) > 1.0e-03) { cvm::log("Reference distribution not normalized, normalizing to unity.\n"); @@ -1387,7 +1434,7 @@ int colvarbias_restraint_histogram::init(std::string const &conf) get_keyval(conf, "writeHistogram", b_write_histogram, false); get_keyval(conf, "forceConstant", force_k, 1.0); - return COLVARS_OK; + return error_code; } @@ -1492,27 +1539,29 @@ int colvarbias_restraint_histogram::update() int colvarbias_restraint_histogram::write_output_files() { if (b_write_histogram) { + colvarproxy *proxy = cvm::main()->proxy; std::string file_name(cvm::output_prefix()+"."+this->name+".hist.dat"); - std::ostream *os = cvm::proxy->output_stream(file_name); - *os << "# " << cvm::wrap_string(variables(0)->name, cvm::cv_width) - << " " << "p(" << cvm::wrap_string(variables(0)->name, cvm::cv_width-3) - << ")\n"; + std::ostream &os = proxy->output_stream(file_name, + "histogram output file"); + os << "# " << cvm::wrap_string(variables(0)->name, cvm::cv_width) + << " " << "p(" << cvm::wrap_string(variables(0)->name, cvm::cv_width-3) + << ")\n"; - os->setf(std::ios::fixed, std::ios::floatfield); + os.setf(std::ios::fixed, std::ios::floatfield); size_t igrid; for (igrid = 0; igrid < p.size(); igrid++) { cvm::real const x_grid = (lower_boundary + (igrid+1)*width); - *os << " " - << std::setprecision(cvm::cv_prec) - << std::setw(cvm::cv_width) - << x_grid - << " " - << std::setprecision(cvm::cv_prec) - << std::setw(cvm::cv_width) - << p[igrid] << "\n"; + os << " " + << std::setprecision(cvm::cv_prec) + << std::setw(cvm::cv_width) + << x_grid + << " " + << std::setprecision(cvm::cv_prec) + << std::setw(cvm::cv_width) + << p[igrid] << "\n"; } - cvm::proxy->close_output_stream(file_name); + proxy->close_output_stream(file_name); } return COLVARS_OK; } diff --git a/lib/colvars/colvarbias_restraint.h b/lib/colvars/colvarbias_restraint.h index b2c9055dfe..45a96d14f8 100644 --- a/lib/colvars/colvarbias_restraint.h +++ b/lib/colvars/colvarbias_restraint.h @@ -123,6 +123,9 @@ protected: /// \brief Changing force constant? bool b_chg_force_k; + /// \brief Perform decoupling of the restraint? + bool b_decoupling; + /// \brief Number of stages over which to perform the change /// If zero, perform a continuous change int target_nstages; @@ -137,6 +140,9 @@ protected: /// or restraint centers cvm::step_number target_nsteps; + /// \brief Timestep at which the restraint starts moving + cvm::step_number first_step; + /// \brief Accumulated work (computed when outputAccumulatedWork == true) cvm::real acc_work; }; @@ -207,7 +213,7 @@ protected: cvm::real starting_force_k; /// \brief Exponent for varying the force constant - cvm::real force_k_exp; + cvm::real lambda_exp; /// \brief Intermediate quantity to compute the restraint free energy /// (in TI, would be the accumulating FE derivative) diff --git a/lib/colvars/colvarcomp.h b/lib/colvars/colvarcomp.h index 9c93de4b49..87d3e27a8f 100644 --- a/lib/colvars/colvarcomp.h +++ b/lib/colvars/colvarcomp.h @@ -616,7 +616,7 @@ public: dipole_magnitude (std::string const &conf); dipole_magnitude (cvm::atom const &a1); dipole_magnitude(); - virtual inline ~dipole_magnitude() {} + virtual ~dipole_magnitude() {} virtual void calc_value(); virtual void calc_gradients(); //virtual void calc_force_invgrads(); diff --git a/lib/colvars/colvarcomp_combination.cpp b/lib/colvars/colvarcomp_combination.cpp index 8aea869983..64745b6472 100644 --- a/lib/colvars/colvarcomp_combination.cpp +++ b/lib/colvars/colvarcomp_combination.cpp @@ -141,13 +141,15 @@ void colvar::linearCombination::apply_force(colvarvalue const &force) { colvar::customColvar::customColvar(std::string const &conf): linearCombination(conf) { use_custom_function = false; // code swipe from colvar::init_custom_function -#ifdef LEPTON std::string expr_in, expr; + size_t pos = 0; // current position in config string +#ifdef LEPTON std::vector pexprs; Lepton::ParsedExpression pexpr; double *ref; - size_t pos = 0; // current position in config string +#endif if (key_lookup(conf, "customFunction", &expr_in, &pos)) { +#ifdef LEPTON use_custom_function = true; cvm::log("This colvar uses a custom function.\n"); do { @@ -208,11 +210,15 @@ colvar::customColvar::customColvar(std::string const &conf): linearCombination(c } else { x.type(colvarvalue::type_scalar); } - } else { - cvm::log(std::string{"Warning: no customFunction specified.\n"}); - cvm::log(std::string{"Warning: use linear combination instead.\n"}); - } +#else + cvm::error("customFunction requires the Lepton library, but it is not enabled during compilation.\n" + "Please refer to the Compilation Notes section of the Colvars manual for more information.\n", + COLVARS_INPUT_ERROR); #endif + } else { + cvm::log("Warning: no customFunction specified.\n"); + cvm::log("Warning: use linear combination instead.\n"); + } } colvar::customColvar::~customColvar() { @@ -227,96 +233,111 @@ colvar::customColvar::~customColvar() { } void colvar::customColvar::calc_value() { -#ifdef LEPTON - for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { - cv[i_cv]->calc_value(); - } - x.reset(); - size_t l = 0; - for (size_t i = 0; i < x.size(); ++i) { - for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { - const colvarvalue& current_cv_value = cv[i_cv]->value(); - for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) { - if (current_cv_value.type() == colvarvalue::type_scalar) { - *(value_eval_var_refs[l++]) = cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, cv[i_cv]->sup_np)); - } else { - *(value_eval_var_refs[l++]) = cv[i_cv]->sup_coeff * current_cv_value[j_elem]; - } - } - } - x[i] = value_evaluators[i]->evaluate(); - } -#endif if (!use_custom_function) { colvar::linearCombination::calc_value(); + } else { +#ifdef LEPTON + for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { + cv[i_cv]->calc_value(); + } + x.reset(); + size_t l = 0; + for (size_t i = 0; i < x.size(); ++i) { + for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { + const colvarvalue& current_cv_value = cv[i_cv]->value(); + for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) { + if (current_cv_value.type() == colvarvalue::type_scalar) { + *(value_eval_var_refs[l++]) = cv[i_cv]->sup_coeff * (cvm::pow(current_cv_value.real_value, cv[i_cv]->sup_np)); + } else { + *(value_eval_var_refs[l++]) = cv[i_cv]->sup_coeff * current_cv_value[j_elem]; + } + } + } + x[i] = value_evaluators[i]->evaluate(); + } +#else + cvm::error("customFunction requires the Lepton library, but it is not enabled during compilation.\n" + "Please refer to the Compilation Notes section of the Colvars manual for more information.\n", + COLVARS_INPUT_ERROR); +#endif } } void colvar::customColvar::calc_gradients() { + if (!use_custom_function) { + colvar::linearCombination::calc_gradients(); + } else { #ifdef LEPTON - size_t r = 0; // index in the vector of variable references - size_t e = 0; // index of the gradient evaluator - for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { // for each CV - cv[i_cv]->calc_gradients(); - if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) { - const colvarvalue& current_cv_value = cv[i_cv]->value(); - const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv); - for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) { // for each element in this CV - for (size_t c = 0; c < x.size(); ++c) { // for each custom function expression - for (size_t k = 0; k < cv.size(); ++k) { // this is required since we need to feed all CV values to this expression - const cvm::real factor_polynomial_k = getPolynomialFactorOfCVGradient(k); - for (size_t l = 0; l < cv[k]->value().size(); ++l) { - *(grad_eval_var_refs[r++]) = factor_polynomial_k * cv[k]->value()[l]; + size_t r = 0; // index in the vector of variable references + size_t e = 0; // index of the gradient evaluator + for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { // for each CV + cv[i_cv]->calc_gradients(); + if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) { + const colvarvalue& current_cv_value = cv[i_cv]->value(); + const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv); + for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) { // for each element in this CV + for (size_t c = 0; c < x.size(); ++c) { // for each custom function expression + for (size_t k = 0; k < cv.size(); ++k) { // this is required since we need to feed all CV values to this expression + const cvm::real factor_polynomial_k = getPolynomialFactorOfCVGradient(k); + for (size_t l = 0; l < cv[k]->value().size(); ++l) { + *(grad_eval_var_refs[r++]) = factor_polynomial_k * cv[k]->value()[l]; + } } - } - const double expr_grad = gradient_evaluators[e++]->evaluate(); - for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) { - for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) { - (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = expr_grad * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad; + const double expr_grad = gradient_evaluators[e++]->evaluate(); + for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) { + for (size_t l_atom = 0; l_atom < (cv[i_cv]->atom_groups)[k_ag]->size(); ++l_atom) { + (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad = expr_grad * factor_polynomial * (*(cv[i_cv]->atom_groups)[k_ag])[l_atom].grad; + } } } } } } - } +#else + cvm::error("customFunction requires the Lepton library, but it is not enabled during compilation.\n" + "Please refer to the Compilation Notes section of the Colvars manual for more information.\n", + COLVARS_INPUT_ERROR); #endif - if (!use_custom_function) { - colvar::linearCombination::calc_gradients(); } } void colvar::customColvar::apply_force(colvarvalue const &force) { -#ifdef LEPTON - size_t r = 0; // index in the vector of variable references - size_t e = 0; // index of the gradient evaluator - for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { - // If this CV us explicit gradients, then atomic gradients is already calculated - // We can apply the force to atom groups directly - if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) { - for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) { - (cv[i_cv]->atom_groups)[k_ag]->apply_colvar_force(force.real_value); - } - } else { - const colvarvalue& current_cv_value = cv[i_cv]->value(); - colvarvalue cv_force(current_cv_value.type()); - const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv); - for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) { - for (size_t c = 0; c < x.size(); ++c) { - for (size_t k = 0; k < cv.size(); ++k) { - const cvm::real factor_polynomial_k = getPolynomialFactorOfCVGradient(k); - for (size_t l = 0; l < cv[k]->value().size(); ++l) { - *(grad_eval_var_refs[r++]) = factor_polynomial_k * cv[k]->value()[l]; - } - } - cv_force[j_elem] += factor_polynomial * gradient_evaluators[e++]->evaluate() * force.real_value; - } - } - cv[i_cv]->apply_force(cv_force); - } - } -#endif if (!use_custom_function) { colvar::linearCombination::apply_force(force); + } else { +#ifdef LEPTON + size_t r = 0; // index in the vector of variable references + size_t e = 0; // index of the gradient evaluator + for (size_t i_cv = 0; i_cv < cv.size(); ++i_cv) { + // If this CV us explicit gradients, then atomic gradients is already calculated + // We can apply the force to atom groups directly + if (cv[i_cv]->is_enabled(f_cvc_explicit_gradient)) { + for (size_t k_ag = 0 ; k_ag < cv[i_cv]->atom_groups.size(); ++k_ag) { + (cv[i_cv]->atom_groups)[k_ag]->apply_colvar_force(force.real_value); + } + } else { + const colvarvalue& current_cv_value = cv[i_cv]->value(); + colvarvalue cv_force(current_cv_value.type()); + const cvm::real factor_polynomial = getPolynomialFactorOfCVGradient(i_cv); + for (size_t j_elem = 0; j_elem < current_cv_value.size(); ++j_elem) { + for (size_t c = 0; c < x.size(); ++c) { + for (size_t k = 0; k < cv.size(); ++k) { + const cvm::real factor_polynomial_k = getPolynomialFactorOfCVGradient(k); + for (size_t l = 0; l < cv[k]->value().size(); ++l) { + *(grad_eval_var_refs[r++]) = factor_polynomial_k * cv[k]->value()[l]; + } + } + cv_force[j_elem] += factor_polynomial * gradient_evaluators[e++]->evaluate() * force.real_value; + } + } + cv[i_cv]->apply_force(cv_force); + } + } +#else + cvm::error("customFunction requires the Lepton library, but it is not enabled during compilation.\n" + "Please refer to the Compilation Notes section of the Colvars manual for more information.\n", + COLVARS_INPUT_ERROR); +#endif } } diff --git a/lib/colvars/colvarcomp_coordnums.cpp b/lib/colvars/colvarcomp_coordnums.cpp index 80ec3177a9..3d618ff805 100644 --- a/lib/colvars/colvarcomp_coordnums.cpp +++ b/lib/colvars/colvarcomp_coordnums.cpp @@ -121,12 +121,12 @@ colvar::coordnum::coordnum(std::string const &conf) } bool const b_isotropic = get_keyval(conf, "cutoff", r0, - cvm::real(4.0 * proxy->angstrom_value)); + cvm::real(proxy->angstrom_to_internal(4.0))); if (get_keyval(conf, "cutoff3", r0_vec, - cvm::rvector(4.0 * proxy->angstrom_value, - 4.0 * proxy->angstrom_value, - 4.0 * proxy->angstrom_value))) { + cvm::rvector(proxy->angstrom_to_internal(4.0), + proxy->angstrom_to_internal(4.0), + proxy->angstrom_to_internal(4.0)))) { if (b_isotropic) { cvm::error("Error: cannot specify \"cutoff\" and \"cutoff3\" " "at the same time.\n", @@ -328,7 +328,7 @@ colvar::h_bond::h_bond(std::string const &conf) atom_groups[0]->add_atom(acceptor); atom_groups[0]->add_atom(donor); - get_keyval(conf, "cutoff", r0, (3.3 * proxy->angstrom_value)); + get_keyval(conf, "cutoff", r0, proxy->angstrom_to_internal(3.3)); get_keyval(conf, "expNumer", en, 6); get_keyval(conf, "expDenom", ed, 8); @@ -405,7 +405,7 @@ colvar::selfcoordnum::selfcoordnum(std::string const &conf) group1 = parse_group(conf, "group1"); - get_keyval(conf, "cutoff", r0, cvm::real(4.0 * proxy->angstrom_value)); + get_keyval(conf, "cutoff", r0, cvm::real(proxy->angstrom_to_internal(4.0))); get_keyval(conf, "expNumer", en, 6); get_keyval(conf, "expDenom", ed, 12); @@ -556,7 +556,7 @@ colvar::groupcoordnum::groupcoordnum(std::string const &conf) } bool const b_scale = get_keyval(conf, "cutoff", r0, - cvm::real(4.0 * proxy->angstrom_value)); + cvm::real(proxy->angstrom_to_internal(4.0))); if (get_keyval(conf, "cutoff3", r0_vec, cvm::rvector(4.0, 4.0, 4.0), parse_silent)) { diff --git a/lib/colvars/colvarcomp_distances.cpp b/lib/colvars/colvarcomp_distances.cpp index fa27e5345e..d96cb33482 100644 --- a/lib/colvars/colvarcomp_distances.cpp +++ b/lib/colvars/colvarcomp_distances.cpp @@ -1055,6 +1055,7 @@ colvar::rmsd::rmsd(std::string const &conf) n_permutations = 1; while (key_lookup(conf, "atomPermutation", &perm_conf, &pos)) { + cvm::main()->cite_feature("Symmetry-adapted RMSD"); std::vector perm; if (perm_conf.size()) { std::istringstream is(perm_conf); diff --git a/lib/colvars/colvarcomp_gpath.cpp b/lib/colvars/colvarcomp_gpath.cpp index bff432fdbe..c73ab4f6c1 100644 --- a/lib/colvars/colvarcomp_gpath.cpp +++ b/lib/colvars/colvarcomp_gpath.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include "colvarmodule.h" #include "colvarvalue.h" @@ -426,9 +427,8 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { std::string path_filename; get_keyval(conf, "pathFile", path_filename); cvm::log(std::string("Reading path file: ") + path_filename + std::string("\n")); - std::ifstream ifs_path(path_filename); - if (!ifs_path.is_open()) { - cvm::error("Error: failed to open path file.\n"); + auto &ifs_path = cvm::main()->proxy->input_stream(path_filename); + if (!ifs_path) { return; } std::string line; @@ -459,6 +459,7 @@ colvar::CVBasedPath::CVBasedPath(std::string const &conf): cvc(conf) { ++total_reference_frames; } } + cvm::main()->proxy->close_input_stream(path_filename); if (total_reference_frames <= 1) { cvm::error("Error: there is only 1 or 0 reference frame, which doesn't constitute a path.\n"); return; diff --git a/lib/colvars/colvarcomp_protein.cpp b/lib/colvars/colvarcomp_protein.cpp index b92cb533b7..80ef9b855c 100644 --- a/lib/colvars/colvarcomp_protein.cpp +++ b/lib/colvars/colvarcomp_protein.cpp @@ -86,7 +86,7 @@ colvar::alpha_angles::alpha_angles(std::string const &conf) { cvm::real r0; size_t en, ed; - get_keyval(conf, "hBondCutoff", r0, (3.3 * proxy->angstrom_value)); + get_keyval(conf, "hBondCutoff", r0, proxy->angstrom_to_internal(3.3)); get_keyval(conf, "hBondExpNumer", en, 6); get_keyval(conf, "hBondExpDenom", ed, 8); @@ -333,10 +333,11 @@ colvar::dihedPC::dihedPC(std::string const &conf) return; } - std::ifstream vecFile; - vecFile.open(vecFileName.c_str()); - if (!vecFile.good()) { - cvm::error("Error opening dihedral PCA vector file " + vecFileName + " for reading"); + std::istream &vecFile = + cvm::main()->proxy->input_stream(vecFileName, + "dihedral PCA vector file"); + if (!vecFile) { + return; } // TODO: adapt to different formats by setting this flag @@ -375,7 +376,7 @@ colvar::dihedPC::dihedPC(std::string const &conf) } } */ - vecFile.close(); + cvm::main()->proxy->close_input_stream(vecFileName); } else { get_keyval(conf, "vector", coeffs, coeffs); diff --git a/lib/colvars/colvarcomp_rotations.cpp b/lib/colvars/colvarcomp_rotations.cpp index 2e0d25ab81..f469174a62 100644 --- a/lib/colvars/colvarcomp_rotations.cpp +++ b/lib/colvars/colvarcomp_rotations.cpp @@ -67,15 +67,17 @@ int colvar::orientation::init(std::string const &conf) } - cvm::log("Centering the reference coordinates: it is " - "assumed that each atom is the closest " - "periodic image to the center of geometry.\n"); cvm::rvector ref_cog(0.0, 0.0, 0.0); size_t i; for (i = 0; i < ref_pos.size(); i++) { ref_cog += ref_pos[i]; } ref_cog /= cvm::real(ref_pos.size()); + cvm::log("Centering the reference coordinates on the origin by subtracting " + "the center of geometry at "+ + cvm::to_str(-1.0 * ref_cog)+"; it is " + "assumed that each atom is the closest " + "periodic image to the center of geometry.\n"); for (i = 0; i < ref_pos.size(); i++) { ref_pos[i] -= ref_cog; } diff --git a/lib/colvars/colvargrid.cpp b/lib/colvars/colvargrid.cpp index 96eb7cb5e1..2fd385ccec 100644 --- a/lib/colvars/colvargrid.cpp +++ b/lib/colvars/colvargrid.cpp @@ -7,14 +7,18 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. +#include +#include + #include "colvarmodule.h" #include "colvarvalue.h" #include "colvarparse.h" #include "colvar.h" #include "colvarcomp.h" #include "colvargrid.h" +#include "colvargrid_def.h" + -#include colvar_grid_count::colvar_grid_count() : colvar_grid() @@ -33,6 +37,42 @@ colvar_grid_count::colvar_grid_count(std::vector &colvars, : colvar_grid(colvars, def_count, 1, margin) {} +std::istream & colvar_grid_count::read_multicol(std::istream &is, bool add) +{ + return colvar_grid::read_multicol(is, add); +} + +int colvar_grid_count::read_multicol(std::string const &filename, + std::string description, + bool add) +{ + return colvar_grid::read_multicol(filename, description, add); +} + +std::ostream & colvar_grid_count::write_multicol(std::ostream &os) const +{ + return colvar_grid::write_multicol(os); +} + +int colvar_grid_count::write_multicol(std::string const &filename, + std::string description) const +{ + return colvar_grid::write_multicol(filename, description); +} + +std::ostream & colvar_grid_count::write_opendx(std::ostream &os) const +{ + return colvar_grid::write_opendx(os); +} + +int colvar_grid_count::write_opendx(std::string const &filename, + std::string description) const +{ + return colvar_grid::write_opendx(filename, description); +} + + + colvar_grid_scalar::colvar_grid_scalar() : colvar_grid(), samples(NULL) {} @@ -56,6 +96,41 @@ colvar_grid_scalar::~colvar_grid_scalar() { } +std::istream & colvar_grid_scalar::read_multicol(std::istream &is, bool add) +{ + return colvar_grid::read_multicol(is, add); +} + +int colvar_grid_scalar::read_multicol(std::string const &filename, + std::string description, + bool add) +{ + return colvar_grid::read_multicol(filename, description, add); +} + +std::ostream & colvar_grid_scalar::write_multicol(std::ostream &os) const +{ + return colvar_grid::write_multicol(os); +} + +int colvar_grid_scalar::write_multicol(std::string const &filename, + std::string description) const +{ + return colvar_grid::write_multicol(filename, description); +} + +std::ostream & colvar_grid_scalar::write_opendx(std::ostream &os) const +{ + return colvar_grid::write_opendx(os); +} + +int colvar_grid_scalar::write_opendx(std::string const &filename, + std::string description) const +{ + return colvar_grid::write_opendx(filename, description); +} + + cvm::real colvar_grid_scalar::maximum_value() const { cvm::real max = data[0]; @@ -145,10 +220,9 @@ colvar_grid_gradient::colvar_grid_gradient(std::string &filename) samples(NULL), weights(NULL) { - std::ifstream is; - is.open(filename.c_str()); - if (!is.is_open()) { - cvm::error("Error opening multicol gradient file " + filename + " for reading.\n"); + std::istream &is = cvm::main()->proxy->input_stream(filename, + "gradient file"); + if (!is) { return; } @@ -203,7 +277,42 @@ colvar_grid_gradient::colvar_grid_gradient(std::string &filename) is.clear(); is.seekg(0); read_multicol(is); - is.close(); + cvm::main()->proxy->close_input_stream(filename); +} + + +std::istream & colvar_grid_gradient::read_multicol(std::istream &is, bool add) +{ + return colvar_grid::read_multicol(is, add); +} + +int colvar_grid_gradient::read_multicol(std::string const &filename, + std::string description, + bool add) +{ + return colvar_grid::read_multicol(filename, description, add); +} + +std::ostream & colvar_grid_gradient::write_multicol(std::ostream &os) const +{ + return colvar_grid::write_multicol(os); +} + +int colvar_grid_gradient::write_multicol(std::string const &filename, + std::string description) const +{ + return colvar_grid::write_multicol(filename, description); +} + +std::ostream & colvar_grid_gradient::write_opendx(std::ostream &os) const +{ + return colvar_grid::write_opendx(os); +} + +int colvar_grid_gradient::write_opendx(std::string const &filename, + std::string description) const +{ + return colvar_grid::write_opendx(filename, description); } diff --git a/lib/colvars/colvargrid.h b/lib/colvars/colvargrid.h index f34c5eccab..e2fc1e0fe2 100644 --- a/lib/colvars/colvargrid.h +++ b/lib/colvars/colvargrid.h @@ -732,8 +732,8 @@ public: /// \brief Return the value suitable for output purposes (so that it /// may be rescaled or manipulated without changing it permanently) - virtual inline T value_output(std::vector const &ix, - size_t const &imult = 0) const + virtual T value_output(std::vector const &ix, + size_t const &imult = 0) const { return value(ix, imult); } @@ -741,10 +741,10 @@ public: /// \brief Get the value from a formatted output and transform it /// into the internal representation (the two may be different, /// e.g. when using colvar_grid_count) - virtual inline void value_input(std::vector const &ix, - T const &t, - size_t const &imult = 0, - bool add = false) + virtual void value_input(std::vector const &ix, + T const &t, + size_t const &imult = 0, + bool add = false) { if ( add ) data[address(ix) + imult] += t; @@ -803,7 +803,7 @@ public: } } - /// \brief Write the grid parameters (number of colvars, boundaries, width and number of points) + /// Write the grid parameters (number of colvars, boundaries, width and number of points) std::ostream & write_params(std::ostream &os) { size_t i; @@ -1028,188 +1028,27 @@ public: return is; } - /// \brief Write the grid in a format which is both human readable - /// and suitable for visualization e.g. with gnuplot - void write_multicol(std::ostream &os) const - { - std::streamsize const w = os.width(); - std::streamsize const p = os.precision(); + /// Read a grid written by write_multicol(), incrementing if add is true + std::istream & read_multicol(std::istream &is, bool add = false); - // Data in the header: nColvars, then for each - // xiMin, dXi, nPoints, periodic + /// Read a grid written by write_multicol(), incrementing if add is true + int read_multicol(std::string const &filename, + std::string description = "grid file", + bool add = false); - os << std::setw(2) << "# " << nd << "\n"; - for (size_t i = 0; i < nd; i++) { - os << "# " - << std::setw(10) << lower_boundaries[i] - << std::setw(10) << widths[i] - << std::setw(10) << nx[i] << " " - << periodic[i] << "\n"; - } + /// Write grid in a format which is both human-readable and gnuplot-friendly + std::ostream & write_multicol(std::ostream &os) const; + /// Write grid in a format which is both human-readable and gnuplot-friendly + int write_multicol(std::string const &filename, + std::string description = "grid file") const; - for (std::vector ix = new_index(); index_ok(ix); incr(ix) ) { + /// Write the grid data without labels, as they are represented in memory + std::ostream & write_opendx(std::ostream &os) const; - if (ix.back() == 0) { - // if the last index is 0, add a new line to mark the new record - os << "\n"; - } - - for (size_t i = 0; i < nd; i++) { - os << " " - << std::setw(w) << std::setprecision(p) - << bin_to_value_scalar(ix[i], i); - } - os << " "; - for (size_t imult = 0; imult < mult; imult++) { - os << " " - << std::setw(w) << std::setprecision(p) - << value_output(ix, imult); - } - os << "\n"; - } - } - - /// \brief Read a grid written by colvar_grid::write_multicol() - /// Adding data if add is true, replacing if false - std::istream & read_multicol(std::istream &is, bool add = false) - { - // Data in the header: nColvars, then for each - // xiMin, dXi, nPoints, periodic flag - - std::string hash; - cvm::real lower, width, x; - size_t n, periodic_flag; - bool remap; - std::vector new_value; - std::vector nx_read; - std::vector bin; - - if ( cv.size() > 0 && cv.size() != nd ) { - cvm::error("Cannot read grid file: number of variables in file differs from number referenced by grid.\n"); - return is; - } - - if ( !(is >> hash) || (hash != "#") ) { - cvm::error("Error reading grid at position "+ - cvm::to_str(static_cast(is.tellg()))+ - " in stream(read \"" + hash + "\")\n"); - return is; - } - - is >> n; - if ( n != nd ) { - cvm::error("Error reading grid: wrong number of collective variables.\n"); - return is; - } - - nx_read.resize(n); - bin.resize(n); - new_value.resize(mult); - - if (this->has_parent_data && add) { - new_data.resize(data.size()); - } - - remap = false; - for (size_t i = 0; i < nd; i++ ) { - if ( !(is >> hash) || (hash != "#") ) { - cvm::error("Error reading grid at position "+ - cvm::to_str(static_cast(is.tellg()))+ - " in stream(read \"" + hash + "\")\n"); - return is; - } - - is >> lower >> width >> nx_read[i] >> periodic_flag; - - - if ( (cvm::fabs(lower - lower_boundaries[i].real_value) > 1.0e-10) || - (cvm::fabs(width - widths[i] ) > 1.0e-10) || - (nx_read[i] != nx[i]) ) { - cvm::log("Warning: reading from different grid definition (colvar " - + cvm::to_str(i+1) + "); remapping data on new grid.\n"); - remap = true; - } - } - - if ( remap ) { - // re-grid data - while (is.good()) { - bool end_of_file = false; - - for (size_t i = 0; i < nd; i++ ) { - if ( !(is >> x) ) end_of_file = true; - bin[i] = value_to_bin_scalar(x, i); - } - if (end_of_file) break; - - for (size_t imult = 0; imult < mult; imult++) { - is >> new_value[imult]; - } - - if ( index_ok(bin) ) { - for (size_t imult = 0; imult < mult; imult++) { - value_input(bin, new_value[imult], imult, add); - } - } - } - } else { - // do not re-grid the data but assume the same grid is used - for (std::vector ix = new_index(); index_ok(ix); incr(ix) ) { - for (size_t i = 0; i < nd; i++ ) { - is >> x; - } - for (size_t imult = 0; imult < mult; imult++) { - is >> new_value[imult]; - value_input(ix, new_value[imult], imult, add); - } - } - } - has_data = true; - return is; - } - - /// \brief Write the grid data without labels, as they are - /// represented in memory - std::ostream & write_opendx(std::ostream &os) const - { - // write the header - os << "object 1 class gridpositions counts"; - size_t icv; - for (icv = 0; icv < num_variables(); icv++) { - os << " " << number_of_points(icv); - } - os << "\n"; - - os << "origin"; - for (icv = 0; icv < num_variables(); icv++) { - os << " " << (lower_boundaries[icv].real_value + 0.5 * widths[icv]); - } - os << "\n"; - - for (icv = 0; icv < num_variables(); icv++) { - os << "delta"; - for (size_t icv2 = 0; icv2 < num_variables(); icv2++) { - if (icv == icv2) os << " " << widths[icv]; - else os << " " << 0.0; - } - os << "\n"; - } - - os << "object 2 class gridconnections counts"; - for (icv = 0; icv < num_variables(); icv++) { - os << " " << number_of_points(icv); - } - os << "\n"; - - os << "object 3 class array type double rank 0 items " - << number_of_points() << " data follows\n"; - - write_raw(os); - - os << "object \"collective variables scalar field\" class field\n"; - return os; - } + /// Write the grid data without labels, as they are represented in memory + int write_opendx(std::string const &filename, + std::string description = "grid file") const; }; @@ -1224,7 +1063,7 @@ public: colvar_grid_count(); /// Destructor - virtual inline ~colvar_grid_count() + virtual ~colvar_grid_count() {} /// Constructor @@ -1249,13 +1088,33 @@ public: return new_data[address(ix) + imult]; } - /// \brief Get the value from a formatted output and transform it - /// into the internal representation (it may have been rescaled or - /// manipulated) - virtual inline void value_input(std::vector const &ix, - size_t const &t, - size_t const &imult = 0, - bool add = false) + /// Read a grid written by write_multicol(), incrementin if data is true + std::istream & read_multicol(std::istream &is, bool add = false); + + /// Read a grid written by write_multicol(), incrementin if data is true + int read_multicol(std::string const &filename, + std::string description = "grid file", + bool add = false); + + /// Write grid in a format which is both human-readable and gnuplot-friendly + std::ostream & write_multicol(std::ostream &os) const; + + /// Write grid in a format which is both human-readable and gnuplot-friendly + int write_multicol(std::string const &filename, + std::string description = "grid file") const; + + /// Write the grid data without labels, as they are represented in memory + std::ostream & write_opendx(std::ostream &os) const; + + /// Write the grid data without labels, as they are represented in memory + int write_opendx(std::string const &filename, + std::string description = "grid file") const; + + /// Enter or add a value, but also handle parent grid + virtual void value_input(std::vector const &ix, + size_t const &t, + size_t const &imult = 0, + bool add = false) { (void) imult; if (add) { @@ -1322,7 +1181,7 @@ public: /// \brief Return the gradient of discrete count from finite differences /// on the *same* grid for dimension n inline cvm::real gradient_finite_diff(const std::vector &ix0, - int n = 0) + int n = 0) { cvm::real A0, A1, A2; std::vector ix = ix0; @@ -1380,7 +1239,7 @@ public: colvar_grid_scalar(colvar_grid_scalar const &g); /// Destructor - ~colvar_grid_scalar(); + virtual ~colvar_grid_scalar(); /// Constructor from specific sizes arrays colvar_grid_scalar(std::vector const &nx_i); @@ -1402,6 +1261,28 @@ public: has_data = true; } + /// Read a grid written by write_multicol(), incrementin if data is true + std::istream & read_multicol(std::istream &is, bool add = false); + + /// Read a grid written by write_multicol(), incrementin if data is true + int read_multicol(std::string const &filename, + std::string description = "grid file", + bool add = false); + + /// Write grid in a format which is both human-readable and gnuplot-friendly + std::ostream & write_multicol(std::ostream &os) const; + + /// Write grid in a format which is both human-readable and gnuplot-friendly + int write_multicol(std::string const &filename, + std::string description = "grid file") const; + + /// Write the grid data without labels, as they are represented in memory + std::ostream & write_opendx(std::ostream &os) const; + + /// Write the grid data without labels, as they are represented in memory + int write_opendx(std::string const &filename, + std::string description = "grid file") const; + /// \brief Return the gradient of the scalar field from finite differences /// Input coordinates are those of gradient grid, shifted wrt scalar grid /// Should not be called on edges of scalar grid, provided the latter has margins @@ -1458,7 +1339,7 @@ public: /// \brief Return the gradient of discrete count from finite differences /// on the *same* grid for dimension n inline cvm::real gradient_finite_diff(const std::vector &ix0, - int n = 0) + int n = 0) { cvm::real A0, A1, A2; std::vector ix = ix0; @@ -1517,9 +1398,7 @@ public: } } - /// \brief Get the value from a formatted output and transform it - /// into the internal representation (it may have been rescaled or - /// manipulated) + /// Enter or add value but also deal with count grid virtual void value_input(std::vector const &ix, cvm::real const &new_value, size_t const &imult = 0, @@ -1580,7 +1459,7 @@ public: colvar_grid_gradient(); /// Destructor - virtual inline ~colvar_grid_gradient() + virtual ~colvar_grid_gradient() {} /// Constructor from specific sizes arrays @@ -1592,6 +1471,28 @@ public: /// Constructor from a multicol file colvar_grid_gradient(std::string &filename); + /// Read a grid written by write_multicol(), incrementin if data is true + virtual std::istream & read_multicol(std::istream &is, bool add = false); + + /// Read a grid written by write_multicol(), incrementin if data is true + virtual int read_multicol(std::string const &filename, + std::string description = "grid file", + bool add = false); + + /// Write grid in a format which is both human-readable and gnuplot-friendly + virtual std::ostream & write_multicol(std::ostream &os) const; + + /// Write grid in a format which is both human-readable and gnuplot-friendly + virtual int write_multicol(std::string const &filename, + std::string description = "grid file") const; + + /// Write the grid data without labels, as they are represented in memory + virtual std::ostream & write_opendx(std::ostream &os) const; + + /// Write the grid data without labels, as they are represented in memory + virtual int write_opendx(std::string const &filename, + std::string description = "grid file") const; + /// \brief Get a vector with the binned value(s) indexed by ix, normalized if applicable inline void vector_value(std::vector const &ix, std::vector &v) const { @@ -1647,8 +1548,8 @@ public: /// \brief Return the value of the function at ix divided by its /// number of samples (if the count grid is defined) - virtual inline cvm::real value_output(std::vector const &ix, - size_t const &imult = 0) const + virtual cvm::real value_output(std::vector const &ix, + size_t const &imult = 0) const { if (samples) return (samples->value(ix) > 0) ? @@ -1661,10 +1562,10 @@ public: /// \brief Get the value from a formatted output and transform it /// into the internal representation (it may have been rescaled or /// manipulated) - virtual inline void value_input(std::vector const &ix, - cvm::real const &new_value, - size_t const &imult = 0, - bool add = false) + virtual void value_input(std::vector const &ix, + cvm::real const &new_value, + size_t const &imult = 0, + bool add = false) { if (add) { if (samples) diff --git a/lib/colvars/colvargrid_def.h b/lib/colvars/colvargrid_def.h new file mode 100644 index 0000000000..f2245f3d81 --- /dev/null +++ b/lib/colvars/colvargrid_def.h @@ -0,0 +1,261 @@ +// -*- c++ -*- + +// This file is part of the Collective Variables module (Colvars). +// The original version of Colvars and its updates are located at: +// https://github.com/Colvars/colvars +// Please update all Colvars source files before making any changes. +// If you wish to distribute your changes, please submit them to the +// Colvars repository at GitHub. + +/// \file Definition of the more complex members of colvar_grid<> template + +#ifndef COLVARGRID_DEF_H +#define COLVARGRID_DEF_H + +#include +#include + +#include "colvarmodule.h" +#include "colvarproxy.h" +#include "colvar.h" +#include "colvargrid.h" + + +template +std::istream & colvar_grid::read_multicol(std::istream &is, bool add) +{ + // Data in the header: nColvars, then for each + // xiMin, dXi, nPoints, periodic flag + + std::string hash; + cvm::real lower, width, x; + size_t n, periodic_flag; + bool remap; + std::vector new_value; + std::vector nx_read; + std::vector bin; + + if ( cv.size() > 0 && cv.size() != nd ) { + cvm::error("Cannot read grid file: number of variables in file differs from number referenced by grid.\n"); + return is; + } + + if ( !(is >> hash) || (hash != "#") ) { + cvm::error("Error reading grid at position "+ + cvm::to_str(static_cast(is.tellg()))+ + " in stream(read \"" + hash + "\")\n", COLVARS_INPUT_ERROR); + return is; + } + + is >> n; + if ( n != nd ) { + cvm::error("Error reading grid: wrong number of collective variables.\n"); + return is; + } + + nx_read.resize(n); + bin.resize(n); + new_value.resize(mult); + + if (this->has_parent_data && add) { + new_data.resize(data.size()); + } + + remap = false; + for (size_t i = 0; i < nd; i++ ) { + if ( !(is >> hash) || (hash != "#") ) { + cvm::error("Error reading grid at position "+ + cvm::to_str(static_cast(is.tellg()))+ + " in stream(read \"" + hash + "\")\n"); + return is; + } + + is >> lower >> width >> nx_read[i] >> periodic_flag; + + + if ( (cvm::fabs(lower - lower_boundaries[i].real_value) > 1.0e-10) || + (cvm::fabs(width - widths[i] ) > 1.0e-10) || + (nx_read[i] != nx[i]) ) { + cvm::log("Warning: reading from different grid definition (colvar " + + cvm::to_str(i+1) + "); remapping data on new grid.\n"); + remap = true; + } + } + + if ( remap ) { + // re-grid data + while (is.good()) { + bool end_of_file = false; + + for (size_t i = 0; i < nd; i++ ) { + if ( !(is >> x) ) end_of_file = true; + bin[i] = value_to_bin_scalar(x, i); + } + if (end_of_file) break; + + for (size_t imult = 0; imult < mult; imult++) { + is >> new_value[imult]; + } + + if ( index_ok(bin) ) { + for (size_t imult = 0; imult < mult; imult++) { + value_input(bin, new_value[imult], imult, add); + } + } + } + } else { + // do not re-grid the data but assume the same grid is used + for (std::vector ix = new_index(); index_ok(ix); incr(ix) ) { + for (size_t i = 0; i < nd; i++ ) { + is >> x; + } + for (size_t imult = 0; imult < mult; imult++) { + is >> new_value[imult]; + value_input(ix, new_value[imult], imult, add); + } + } + } + has_data = true; + return is; +} + + +template +int colvar_grid::read_multicol(std::string const &filename, + std::string description, + bool add) +{ + std::istream &is = cvm::main()->proxy->input_stream(filename, description); + if (!is) { + return COLVARS_FILE_ERROR; + } + if (colvar_grid::read_multicol(is, add)) { + cvm::main()->proxy->close_input_stream(filename); + return COLVARS_OK; + } + return COLVARS_FILE_ERROR; +} + + +template +std::ostream & colvar_grid::write_multicol(std::ostream &os) const +{ + // Save the output formats + std::ios_base::fmtflags prev_flags(os.flags()); + + // Data in the header: nColvars, then for each + // xiMin, dXi, nPoints, periodic + + os << std::setw(2) << "# " << nd << "\n"; + // Write the floating numbers in full precision + os.setf(std::ios::scientific, std::ios::floatfield); + for (size_t i = 0; i < nd; i++) { + os << "# " + << std::setw(cvm::cv_width) << std::setprecision(cvm::cv_prec) << lower_boundaries[i] << " " + << std::setw(cvm::cv_width) << std::setprecision(cvm::cv_prec) << widths[i] << " " + << std::setw(10) << nx[i] << " " + << periodic[i] << "\n"; + } + + for (std::vector ix = new_index(); index_ok(ix); incr(ix) ) { + + if (ix.back() == 0) { + // if the last index is 0, add a new line to mark the new record + os << "\n"; + } + + for (size_t i = 0; i < nd; i++) { + os << " " + << std::setw(cvm::cv_width) << std::setprecision(cvm::cv_prec) + << bin_to_value_scalar(ix[i], i); + } + os << " "; + for (size_t imult = 0; imult < mult; imult++) { + os << " " + << std::setw(cvm::cv_width) << std::setprecision(cvm::cv_prec) + << value_output(ix, imult); + } + os << "\n"; + } + + // Restore the output formats + os.flags(prev_flags); + + return os; +} + + +template +int colvar_grid::write_multicol(std::string const &filename, + std::string description) const +{ + int error_code = COLVARS_OK; + std::ostream &os = cvm::main()->proxy->output_stream(filename, description); + if (!os) { + return COLVARS_FILE_ERROR; + } + error_code |= colvar_grid::write_multicol(os) ? COLVARS_OK : + COLVARS_FILE_ERROR; + cvm::main()->proxy->close_output_stream(filename); + return error_code; +} + + +template +std::ostream & colvar_grid::write_opendx(std::ostream &os) const +{ + // write the header + os << "object 1 class gridpositions counts"; + size_t icv; + for (icv = 0; icv < num_variables(); icv++) { + os << " " << number_of_points(icv); + } + os << "\n"; + + os << "origin"; + for (icv = 0; icv < num_variables(); icv++) { + os << " " << (lower_boundaries[icv].real_value + 0.5 * widths[icv]); + } + os << "\n"; + + for (icv = 0; icv < num_variables(); icv++) { + os << "delta"; + for (size_t icv2 = 0; icv2 < num_variables(); icv2++) { + if (icv == icv2) os << " " << widths[icv]; + else os << " " << 0.0; + } + os << "\n"; + } + + os << "object 2 class gridconnections counts"; + for (icv = 0; icv < num_variables(); icv++) { + os << " " << number_of_points(icv); + } + os << "\n"; + + os << "object 3 class array type double rank 0 items " + << number_of_points() << " data follows\n"; + + write_raw(os); + + os << "object \"collective variables scalar field\" class field\n"; + return os; +} + + +template +int colvar_grid::write_opendx(std::string const &filename, + std::string description) const +{ + int error_code = COLVARS_OK; + std::ostream &os = cvm::main()->proxy->output_stream(filename, description); + if (!os) { + return COLVARS_FILE_ERROR; + } + error_code |= colvar_grid::write_opendx(os) ? COLVARS_OK : + COLVARS_FILE_ERROR; + cvm::main()->proxy->close_output_stream(filename); + return error_code; +} + +#endif diff --git a/lib/colvars/colvarmodule.cpp b/lib/colvars/colvarmodule.cpp index 6ad945202e..68cd402e1c 100644 --- a/lib/colvars/colvarmodule.cpp +++ b/lib/colvars/colvarmodule.cpp @@ -7,7 +7,10 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. +#include +#include #include +#include #include #include #include @@ -71,8 +74,6 @@ colvarmodule::colvarmodule(colvarproxy *proxy_in) depth_s = 0; log_level_ = 10; - cv_traj_os = NULL; - xyz_reader_use_count = 0; num_biases_types_used_ = @@ -132,8 +133,6 @@ colvarmodule::colvarmodule(colvarproxy *proxy_in) cv_traj_freq = 100; restart_out_freq = proxy->default_restart_frequency(); - // by default overwrite the existing trajectory file - cv_traj_append = false; cv_traj_write_labels = true; // Removes the need for proxy specializations to create this @@ -190,12 +189,12 @@ int colvarmodule::read_config_file(char const *config_filename) std::string(config_filename)+"\":\n"); // open the configfile - config_s.open(config_filename); - if (!config_s.is_open()) { - cvm::error("Error: in opening configuration file \""+ - std::string(config_filename)+"\".\n", - COLVARS_FILE_ERROR); - return COLVARS_ERROR; + std::istream &config_s = proxy->input_stream(config_filename, + "configuration file/string"); + if (!config_s) { + return cvm::error("Error: in opening configuration file \""+ + std::string(config_filename)+"\".\n", + COLVARS_FILE_ERROR); } // read the config file into a string @@ -206,7 +205,7 @@ int colvarmodule::read_config_file(char const *config_filename) if (line.find_first_not_of(colvarparse::white_space) != std::string::npos) conf.append(line+"\n"); } - config_s.close(); + proxy->close_input_stream(config_filename); return parse_config(conf); } @@ -299,9 +298,6 @@ int colvarmodule::parse_config(std::string &conf) cvm::log("Collective variables module (re)initialized.\n"); cvm::log(cvm::line_marker); - // Update any necessary proxy data - proxy->setup(); - if (source_Tcl_script.size() > 0) { run_tcl_script(source_Tcl_script); } @@ -385,10 +381,6 @@ int colvarmodule::parse_global_params(std::string const &conf) parse->get_keyval(conf, "colvarsRestartFrequency", restart_out_freq, restart_out_freq); - // Deprecate append flag - parse->get_keyval(conf, "colvarsTrajAppend", - cv_traj_append, cv_traj_append, colvarparse::parse_silent); - parse->get_keyval(conf, "scriptedColvarForces", use_scripted_forces, use_scripted_forces); @@ -433,6 +425,7 @@ int colvarmodule::parse_colvars(std::string const &conf) cvm::log("Error while constructing colvar number " + cvm::to_str(colvars.size()) + " : deleting."); delete colvars.back(); // the colvar destructor updates the colvars array + cvm::decrease_depth(); return COLVARS_ERROR; } cvm::decrease_depth(); @@ -855,11 +848,13 @@ int colvarmodule::calc_colvars() // so they can activate colvars as needed std::vector::iterator bi; for (bi = biases.begin(); bi != biases.end(); bi++) { - int tsf = (*bi)->get_time_step_factor(); - if (tsf > 0 && (step_absolute() % tsf == 0)) { - (*bi)->enable(colvardeps::f_cvb_awake); - } else { - (*bi)->disable(colvardeps::f_cvb_awake); + int const tsf = (*bi)->get_time_step_factor(); + if (tsf > 1) { + if (step_absolute() % tsf == 0) { + (*bi)->enable(colvardeps::f_cvb_awake); + } else { + (*bi)->disable(colvardeps::f_cvb_awake); + } } } @@ -870,12 +865,14 @@ int colvarmodule::calc_colvars() variables_active()->clear(); variables_active()->reserve(variables()->size()); for (cvi = variables()->begin(); cvi != variables()->end(); cvi++) { - // Wake up or put to sleep variables + // Wake up or put to sleep variables with MTS int tsf = (*cvi)->get_time_step_factor(); - if (tsf > 0 && (step_absolute() % tsf == 0)) { - (*cvi)->enable(colvardeps::f_cv_awake); - } else { - (*cvi)->disable(colvardeps::f_cv_awake); + if (tsf > 1) { + if (step_absolute() % tsf == 0) { + (*cvi)->enable(colvardeps::f_cv_awake); + } else { + (*cvi)->disable(colvardeps::f_cv_awake); + } } if ((*cvi)->is_enabled()) { @@ -1013,10 +1010,7 @@ int colvarmodule::update_colvar_forces() cvm::log("Collecting forces from all biases.\n"); cvm::increase_depth(); for (bi = biases_active()->begin(); bi != biases_active()->end(); bi++) { - (*bi)->communicate_forces(); - if (cvm::get_error()) { - return COLVARS_ERROR; - } + error_code |= (*bi)->communicate_forces(); } cvm::decrease_depth(); @@ -1040,9 +1034,6 @@ int colvarmodule::update_colvar_forces() for (cvi = variables()->begin(); cvi != variables()->end(); cvi++) { // Inactive colvars will only reset their forces and return 0 energy total_colvar_energy += (*cvi)->update_forces_energy(); - if (cvm::get_error()) { - return COLVARS_ERROR; - } } cvm::decrease_depth(); if (cvm::debug()) @@ -1064,7 +1055,7 @@ int colvarmodule::update_colvar_forces() } cvm::decrease_depth(); - return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); + return error_code; } @@ -1089,17 +1080,15 @@ int colvarmodule::calc_scripted_forces() int colvarmodule::write_restart_file(std::string const &out_name) { cvm::log("Saving collective variables state to \""+out_name+"\".\n"); - proxy->backup_file(out_name); - std::ostream *restart_out_os = proxy->output_stream(out_name); - if (!restart_out_os) return cvm::get_error(); - if (!write_restart(*restart_out_os)) { + std::ostream &restart_out_os = proxy->output_stream(out_name, "state file"); + if (!restart_out_os) return COLVARS_FILE_ERROR; + if (!write_restart(restart_out_os)) { return cvm::error("Error: in writing restart file.\n", COLVARS_FILE_ERROR); } proxy->close_output_stream(out_name); - if (cv_traj_os != NULL) { - // Take the opportunity to flush colvars.traj - proxy->flush_output_stream(cv_traj_os); - } + + // Take the opportunity to flush colvars.traj + return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); } @@ -1118,38 +1107,46 @@ int colvarmodule::write_restart_string(std::string &output) int colvarmodule::write_traj_files() { + int error_code = COLVARS_OK; + if (cvm::debug()) { cvm::log("colvarmodule::write_traj_files()\n"); } - if (cv_traj_os == NULL) { - if (open_traj_file(cv_traj_name) != COLVARS_OK) { - return cvm::get_error(); - } else { - cv_traj_write_labels = true; - } + std::ostream &cv_traj_os = proxy->output_stream(cv_traj_name, + "colvars trajectory"); + + if (!cv_traj_os) { + return COLVARS_FILE_ERROR; } - // write labels in the traj file every 1000 lines and at first timestep - if ((cvm::step_absolute() % (cv_traj_freq * 1000)) == 0 || - cvm::step_relative() == 0 || - cv_traj_write_labels) { - write_traj_label(*cv_traj_os); + // Write labels in the traj file at beginning and then every 1000 lines + if ( (cvm::step_relative() == 0) || cv_traj_write_labels || + ((cvm::step_absolute() % (cv_traj_freq * 1000)) == 0) ) { + error_code |= + write_traj_label(cv_traj_os) ? COLVARS_OK : COLVARS_FILE_ERROR; + cv_traj_write_labels = false; + } + + if (cvm::debug()) { + proxy->flush_output_stream(cv_traj_name); } - cv_traj_write_labels = false; if ((cvm::step_absolute() % cv_traj_freq) == 0) { - write_traj(*cv_traj_os); + error_code |= write_traj(cv_traj_os) ? COLVARS_OK : COLVARS_FILE_ERROR; } - if (restart_out_freq && (cv_traj_os != NULL) && - ((cvm::step_absolute() % restart_out_freq) == 0)) { + if (cvm::debug()) { + proxy->flush_output_stream(cv_traj_name); + } + + if (restart_out_freq && ((cvm::step_absolute() % restart_out_freq) == 0)) { cvm::log("Synchronizing (emptying the buffer of) trajectory file \""+ cv_traj_name+"\".\n"); - proxy->flush_output_stream(cv_traj_os); + error_code |= proxy->flush_output_stream(cv_traj_name); } - return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); + return error_code; } @@ -1208,7 +1205,7 @@ int colvarmodule::end_of_step() } -int colvarmodule::setup() +int colvarmodule::update_engine_parameters() { if (this->size() == 0) return cvm::get_error(); for (std::vector::iterator cvi = variables()->begin(); @@ -1221,8 +1218,8 @@ int colvarmodule::setup() colvarmodule::~colvarmodule() { - if ((proxy->smp_thread_id() == COLVARS_NOT_IMPLEMENTED) || - (proxy->smp_thread_id() == 0)) { + if ((proxy->smp_thread_id() < 0) || // not using threads + (proxy->smp_thread_id() == 0)) { // or this is thread 0 reset(); @@ -1250,8 +1247,6 @@ colvarmodule::~colvarmodule() int colvarmodule::reset() { - cvm::log("Resetting the Collective Variables module.\n"); - parse->clear(); // Iterate backwards because we are deleting the elements as we go @@ -1289,30 +1284,34 @@ int colvarmodule::setup_input() // Read a state file std::string restart_in_name(proxy->input_prefix()+ std::string(".colvars.state")); - std::ifstream input_is(restart_in_name.c_str()); - if (!input_is.good()) { - // Try without the suffix - input_is.clear(); + std::istream *input_is = &(proxy->input_stream(restart_in_name, + "restart file/channel", + false)); + if (!*input_is) { + // Try without the suffix ".colvars.state" restart_in_name = proxy->input_prefix(); - input_is.open(restart_in_name.c_str()); + input_is = &(proxy->input_stream(restart_in_name, + "restart file/channel")); + if (!*input_is) { + return COLVARS_FILE_ERROR; + } } - // Now that the file has been opened, clear this for the next round + // Now that the file has been opened, clear this field so that this + // function will not be called twice proxy->input_prefix().clear(); - if (!input_is.good()) { - return cvm::error("Error: in opening input state file \""+ - std::string(restart_in_name)+"\".\n", - COLVARS_FILE_ERROR); - } else { - cvm::log(cvm::line_marker); - cvm::log("Loading state from file \""+restart_in_name+"\".\n"); - read_restart(input_is); - cvm::log(cvm::line_marker); - return cvm::get_error(); - } + cvm::log(cvm::line_marker); + cvm::log("Loading state from file \""+restart_in_name+"\".\n"); + read_restart(*input_is); + cvm::log(cvm::line_marker); + + proxy->close_input_stream(restart_in_name); + + return cvm::get_error(); } + // TODO This could soon be redundant if (proxy->input_buffer() != NULL) { // Read a string buffer char const *buffer = proxy->input_buffer(); @@ -1364,10 +1363,6 @@ int colvarmodule::setup_output() std::string(output_prefix()+".colvars.traj") : std::string("")); - if (cv_traj_freq && cv_traj_name.size()) { - error_code |= open_traj_file(cv_traj_name); - } - for (std::vector::iterator bi = biases.begin(); bi != biases.end(); bi++) { @@ -1572,7 +1567,7 @@ int colvarmodule::write_output_files() error_code |= (*bi)->write_state_to_replicas(); } cvm::decrease_depth(); - return (cvm::get_error() ? COLVARS_ERROR : COLVARS_OK); + return error_code; } @@ -1582,6 +1577,9 @@ int colvarmodule::read_traj(char const *traj_filename, { cvm::log("Opening trajectory file \""+ std::string(traj_filename)+"\".\n"); + // NB: this function is not currently used, but when it will it should + // retain the ability for direct file-based access (in case traj files + // exceed memory) std::ifstream traj_is(traj_filename); while (true) { @@ -1683,42 +1681,6 @@ std::ostream & colvarmodule::write_restart(std::ostream &os) } -int colvarmodule::open_traj_file(std::string const &file_name) -{ - if (cv_traj_os != NULL) { - return COLVARS_OK; - } - - // (re)open trajectory file - if (cv_traj_append) { - cvm::log("Appending to trajectory file \""+file_name+"\".\n"); - cv_traj_os = (cvm::proxy)->output_stream(file_name, std::ios::app); - } else { - cvm::log("Opening trajectory file \""+file_name+"\".\n"); - proxy->backup_file(file_name.c_str()); - cv_traj_os = (cvm::proxy)->output_stream(file_name); - } - - if (cv_traj_os == NULL) { - cvm::error("Error: cannot write to file \""+file_name+"\".\n", - COLVARS_FILE_ERROR); - } - - return cvm::get_error(); -} - - -int colvarmodule::close_traj_file() -{ - if (cv_traj_os != NULL) { - cvm::log("Closing trajectory file \""+cv_traj_name+"\".\n"); - proxy->close_output_stream(cv_traj_name); - cv_traj_os = NULL; - } - return cvm::get_error(); -} - - std::ostream & colvarmodule::write_traj_label(std::ostream &os) { os.setf(std::ios::scientific, std::ios::floatfield); @@ -1739,10 +1701,6 @@ std::ostream & colvarmodule::write_traj_label(std::ostream &os) } os << "\n"; - if (cvm::debug()) { - proxy->flush_output_stream(&os); - } - cvm::decrease_depth(); return os; } @@ -1768,10 +1726,6 @@ std::ostream & colvarmodule::write_traj(std::ostream &os) } os << "\n"; - if (cvm::debug()) { - proxy->flush_output_stream(&os); - } - cvm::decrease_depth(); return os; } @@ -1780,12 +1734,15 @@ std::ostream & colvarmodule::write_traj(std::ostream &os) void colvarmodule::log(std::string const &message, int min_log_level) { if (cvm::log_level() < min_log_level) return; + + std::string const trailing_newline = (message.size() > 0) ? + (message[message.size()-1] == '\n' ? "" : "\n") : ""; // allow logging when the module is not fully initialized size_t const d = (cvm::main() != NULL) ? depth() : 0; if (d > 0) { - proxy->log((std::string(2*d, ' '))+message); + proxy->log((std::string(2*d, ' ')) + message + trailing_newline); } else { - proxy->log(message); + proxy->log(message + trailing_newline); } } @@ -1854,18 +1811,26 @@ void colvarmodule::clear_error() int colvarmodule::error(std::string const &message, int code) { set_error_bits(code); - proxy->error(message); + + std::string const trailing_newline = (message.size() > 0) ? + (message[message.size()-1] == '\n' ? "" : "\n") : ""; + size_t const d = depth(); + if (d > 0) { + proxy->error((std::string(2*d, ' ')) + message + trailing_newline); + } else { + proxy->error(message + trailing_newline); + } + return get_error(); } int cvm::read_index_file(char const *filename) { - std::ifstream is(filename, std::ios::binary); - if (!is.good()) { - return cvm::error("Error: in opening index file \""+ - std::string(filename)+"\".\n", - COLVARS_FILE_ERROR); + std::istream &is = proxy->input_stream(filename, "index file"); + + if (!is) { + return COLVARS_FILE_ERROR; } else { index_file_names.push_back(std::string(filename)); } @@ -1947,7 +1912,7 @@ int cvm::read_index_file(char const *filename) cvm::to_str((index_groups[i])->size())+" atoms)\n"); } - return COLVARS_OK; + return proxy->close_input_stream(filename); } @@ -2016,9 +1981,10 @@ int cvm::load_coords(char const *file_name, int cvm::load_coords_xyz(char const *filename, std::vector *pos, - cvm::atom_group *atoms) + cvm::atom_group *atoms, + bool keep_open) { - std::ifstream xyz_is(filename); + std::istream &xyz_is = proxy->input_stream(filename, "XYZ file"); unsigned int natoms; char symbol[256]; std::string line; @@ -2028,7 +1994,8 @@ int cvm::load_coords_xyz(char const *filename, std::string(filename)+"\".\n"); if ( ! (xyz_is >> natoms) ) { - return cvm::error(error_msg, COLVARS_INPUT_ERROR); + // Return silent error when reaching the end of multi-frame files + return keep_open ? COLVARS_NO_SUCH_FRAME : cvm::error(error_msg, COLVARS_INPUT_ERROR); } ++xyz_reader_use_count; @@ -2049,6 +2016,12 @@ int cvm::load_coords_xyz(char const *filename, size_t xyz_natoms = 0; if (pos->size() != natoms) { // Use specified indices int next = 0; // indices are zero-based + if (!atoms) { + // In the other branch of this test, reading all positions from the file, + // a valid atom group pointer is not necessary + return cvm::error("Trying to read partial positions with invalid atom group pointer", + COLVARS_BUG_ERROR); + } std::vector::const_iterator index = atoms->sorted_ids().begin(); for ( ; pos_i != pos->end() ; pos_i++, index++) { @@ -2092,7 +2065,11 @@ int cvm::load_coords_xyz(char const *filename, cvm::to_str(pos->size())+".\n", COLVARS_INPUT_ERROR); } - return COLVARS_OK; + if (keep_open) { + return COLVARS_OK; + } else { + return proxy->close_input_stream(filename); + } } @@ -2100,18 +2077,6 @@ int cvm::load_coords_xyz(char const *filename, // Wrappers to proxy functions: these may go in the future -cvm::real cvm::boltzmann() -{ - return proxy->boltzmann(); -} - - -cvm::real cvm::temperature() -{ - return proxy->temperature(); -} - - cvm::real cvm::dt() { return proxy->dt(); diff --git a/lib/colvars/colvarmodule.h b/lib/colvars/colvarmodule.h index ae29e94505..236d432a95 100644 --- a/lib/colvars/colvarmodule.h +++ b/lib/colvars/colvarmodule.h @@ -40,15 +40,13 @@ You can browse the class hierarchy or the list of source files. #define COLVARS_BUG_ERROR (1<<3) // Inconsistent state indicating bug #define COLVARS_FILE_ERROR (1<<4) #define COLVARS_MEMORY_ERROR (1<<5) -#define COLVARS_NO_SUCH_FRAME (1<<6) // Cannot load the requested frame +#define COLVARS_NO_SUCH_FRAME (1<<6) // Cannot load the requested frame -#include -#include -#include #include #include #include #include +#include class colvarparse; class colvar; @@ -441,9 +439,9 @@ public: // from the proxy that may change during program execution) // No additional parsing is done within these functions - /// (Re)initialize internal data (currently used by LAMMPS) + /// (Re)initialize any internal data affected by changes in the engine /// Also calls setup() member functions of colvars and biases - int setup(); + int update_engine_parameters(); /// (Re)initialize and (re)read the input state file calling read_restart() int setup_input(); @@ -634,12 +632,6 @@ public: // proxy functions - /// \brief Boltmann constant - static real boltzmann(); - - /// \brief Temperature of the simulation (K) - static real temperature(); - /// \brief Time step of MD integrator (fs) static real dt(); @@ -751,7 +743,8 @@ public: /// Load coordinates into an atom group from an XYZ file (assumes Angstroms) int load_coords_xyz(char const *filename, std::vector *pos, - atom_group *atoms); + atom_group *atoms, + bool keep_open = false); /// Frequency for collective variables trajectory output static size_t cv_traj_freq; @@ -766,21 +759,12 @@ public: protected: - /// Configuration file - std::ifstream config_s; - /// Configuration file parser object colvarparse *parse; /// Name of the trajectory file std::string cv_traj_name; - /// Collective variables output trajectory file - std::ostream *cv_traj_os; - - /// Appending to the existing trajectory file? - bool cv_traj_append; - /// Write labels at the next iteration bool cv_traj_write_labels; diff --git a/lib/colvars/colvarmodule_refs.h b/lib/colvars/colvarmodule_refs.h index 0b8791ce34..c3fccf297c 100644 --- a/lib/colvars/colvarmodule_refs.h +++ b/lib/colvars/colvarmodule_refs.h @@ -63,6 +63,22 @@ " url = {https://doi.org/10.1021/ct500874p}\n" "}\n"; + paper_count_[std::string("Ebrahimi2022")] = 0; + paper_url_[std::string("Ebrahimi2022")] = "https://doi.org/10.1021/acs.jctc.1c01235"; + paper_bibtex_[std::string("Ebrahimi2022")] = + "\n" + "@article {Ebrahimi2022,\n" + " author = {Ebrahimi, Mina and H\\'enin, J\\'er\\^ome},\n" + " title = {Symmetry-Adapted Restraints for Binding Free Energy Calculations},\n" + " journal = {Journal of Chemical Theory and Computation},\n" + " volume = {18},\n" + " number = {4},\n" + " pages = {2494-2502},\n" + " year = {2022},\n" + " doi = {10.1021/acs.jctc.1c01235},\n" + " url = {https://doi.org/10.1021/acs.jctc.1c01235}\n" + "}\n"; + paper_count_[std::string("Fiorin2013")] = 0; paper_url_[std::string("Fiorin2013")] = "https://doi.org/10.1080/00268976.2013.813594"; paper_bibtex_[std::string("Fiorin2013")] = @@ -246,20 +262,19 @@ " url = {https://doi.org/10.1063/5.0014475}\n" "}\n"; - paper_count_[std::string("Plimpton1995")] = 0; - paper_url_[std::string("Plimpton1995")] = "https://doi.org/10.1006/jcph.1995.1039"; - paper_bibtex_[std::string("Plimpton1995")] = + paper_count_[std::string("Thompson2022")] = 0; + paper_url_[std::string("Thompson2022")] = "https://doi.org/10.1016/j.cpc.2021.108171"; + paper_bibtex_[std::string("Thompson2022")] = "\n" - "@article{Plimpton1995,\n" - " title = {Fast parallel algorithms for short-range molecular dynamics},\n" - " author = {Plimpton, Steve},\n" - " journal = {J. Comp. Phys.},\n" - " year = {1995},\n" - " volume = {117},\n" - " number = {1},\n" - " pages = {1--19},\n" - " doi = {10.1006/jcph.1995.1039},\n" - " url = {https://doi.org/10.1006/jcph.1995.1039}\n" + "@article{Thompson2022,\n" + " title = {{LAMMPS} - a flexible simulation tool for particle-based materials modeling at the atomic, meso, and continuum scales},\n" + " author = {Thompson, Aidan P. and Aktulga, H. Metin and Berger, Richard and Bolintineanu, Dan S. and Brown, W. Michael and Crozier, Paul S. and {in't Veld}, Pieter J. and Kohlmeyer, Axel and Moore, Stan G. and Nguyen, Trung Dac and Shan, Ray and Stevens, Mark J. and Tranchida, Julien and Trott, Christian and Plimpton, Steven J.},\n" + " journal = {Comp. Phys. Comm.},\n" + " volume = {271},\n" + " pages = {108171},\n" + " year = {2022},\n" + " doi = {10.1016/j.cpc.2021.108171},\n" + " url = {https://doi.org/10.1016/j.cpc.2021.108171}\n" "}\n"; paper_count_[std::string("Shen2015")] = 0; @@ -329,6 +344,9 @@ feature_count_[std::string("Multiple-walker ABF implementation")] = 0; feature_paper_map_[std::string("Multiple-walker ABF implementation")] = "Comer2014c"; + feature_count_[std::string("Symmetry-adapted RMSD")] = 0; + feature_paper_map_[std::string("Symmetry-adapted RMSD")] = "Ebrahimi2022"; + feature_count_[std::string("Colvars module")] = 0; feature_paper_map_[std::string("Colvars module")] = "Fiorin2013"; @@ -504,7 +522,7 @@ feature_paper_map_[std::string("Scalable center-of-mass computation (NAMD)")] = "Phillips2020"; feature_count_[std::string("LAMMPS engine")] = 0; - feature_paper_map_[std::string("LAMMPS engine")] = "Plimpton1995"; + feature_paper_map_[std::string("LAMMPS engine")] = "Thompson2022"; feature_count_[std::string("distancePairs colvar component")] = 0; feature_paper_map_[std::string("distancePairs colvar component")] = "Shen2015"; diff --git a/lib/colvars/colvarproxy.cpp b/lib/colvars/colvarproxy.cpp index 3d4c9c439b..b09ea6667c 100644 --- a/lib/colvars/colvarproxy.cpp +++ b/lib/colvars/colvarproxy.cpp @@ -7,23 +7,9 @@ // If you wish to distribute your changes, please submit them to the // Colvars repository at GitHub. -// Using access() to check if a file exists (until we can assume C++14/17) -#if !defined(_WIN32) || defined(__CYGWIN__) -#include -#endif -#if defined(_WIN32) -#include -#endif - -#include - -#include -#include -#include - -#if defined(_OPENMP) -#include -#endif +#include +#include +#include #include "colvarmodule.h" #include "colvarproxy.h" @@ -33,205 +19,6 @@ -colvarproxy_system::colvarproxy_system() -{ - angstrom_value = 0.0; - kcal_mol_value = 0.0; - boundaries_type = boundaries_unsupported; - total_force_requested = false; - indirect_lambda_biasing_force = 0.0; - cached_alch_lambda_changed = false; - cached_alch_lambda = -1.0; - reset_pbc_lattice(); -} - - -colvarproxy_system::~colvarproxy_system() {} - - -int colvarproxy_system::set_unit_system(std::string const & /* units */, - bool /* check_only */) -{ - return COLVARS_NOT_IMPLEMENTED; -} - - -cvm::real colvarproxy_system::backend_angstrom_value() -{ - return 1.0; -} - - -cvm::real colvarproxy_system::boltzmann() -{ - return 0.001987191; -} - - -cvm::real colvarproxy_system::temperature() -{ - // TODO define, document and implement a user method to set the value of this - return 300.0; -} - - -cvm::real colvarproxy_system::dt() -{ - // TODO define, document and implement a user method to set the value of this - return 1.0; -} - - -cvm::real colvarproxy_system::rand_gaussian() -{ - // TODO define, document and implement a user method to set the value of this - return 0.0; -} - - -void colvarproxy_system::add_energy(cvm::real /* energy */) {} - - -void colvarproxy_system::request_total_force(bool yesno) -{ - if (yesno == true) - cvm::error("Error: total forces are currently not implemented.\n", - COLVARS_NOT_IMPLEMENTED); -} - - -bool colvarproxy_system::total_forces_enabled() const -{ - return false; -} - - -bool colvarproxy_system::total_forces_same_step() const -{ - return false; -} - - -inline int round_to_integer(cvm::real x) -{ - return int(cvm::floor(x+0.5)); -} - - -void colvarproxy_system::update_pbc_lattice() -{ - // Periodicity is assumed in all directions - - if (boundaries_type == boundaries_unsupported || - boundaries_type == boundaries_non_periodic) { - cvm::error("Error: setting PBC lattice with unsupported boundaries.\n", - COLVARS_BUG_ERROR); - return; - } - - { - cvm::rvector const v = cvm::rvector::outer(unit_cell_y, unit_cell_z); - reciprocal_cell_x = v/(v*unit_cell_x); - } - { - cvm::rvector const v = cvm::rvector::outer(unit_cell_z, unit_cell_x); - reciprocal_cell_y = v/(v*unit_cell_y); - } - { - cvm::rvector const v = cvm::rvector::outer(unit_cell_x, unit_cell_y); - reciprocal_cell_z = v/(v*unit_cell_z); - } -} - - -void colvarproxy_system::reset_pbc_lattice() -{ - unit_cell_x.reset(); - unit_cell_y.reset(); - unit_cell_z.reset(); - reciprocal_cell_x.reset(); - reciprocal_cell_y.reset(); - reciprocal_cell_z.reset(); -} - - -cvm::rvector colvarproxy_system::position_distance(cvm::atom_pos const &pos1, - cvm::atom_pos const &pos2) - const -{ - if (boundaries_type == boundaries_unsupported) { - cvm::error("Error: unsupported boundary conditions.\n", COLVARS_INPUT_ERROR); - } - - cvm::rvector diff = (pos2 - pos1); - - if (boundaries_type == boundaries_non_periodic) return diff; - - cvm::real const x_shift = round_to_integer(reciprocal_cell_x*diff); - cvm::real const y_shift = round_to_integer(reciprocal_cell_y*diff); - cvm::real const z_shift = round_to_integer(reciprocal_cell_z*diff); - - diff.x -= x_shift*unit_cell_x.x + y_shift*unit_cell_y.x + - z_shift*unit_cell_z.x; - diff.y -= x_shift*unit_cell_x.y + y_shift*unit_cell_y.y + - z_shift*unit_cell_z.y; - diff.z -= x_shift*unit_cell_x.z + y_shift*unit_cell_y.z + - z_shift*unit_cell_z.z; - - return diff; -} - - -int colvarproxy_system::get_molid(int &) -{ - cvm::error("Error: only VMD allows the use of multiple \"molecules\", " - "i.e. multiple molecular systems.", COLVARS_NOT_IMPLEMENTED); - return -1; -} - - -int colvarproxy_system::get_alch_lambda(cvm::real * /* lambda */) -{ - return cvm::error("Error in get_alch_lambda: alchemical lambda dynamics is not supported by this build.", - COLVARS_NOT_IMPLEMENTED); -} - - -void colvarproxy_system::set_alch_lambda(cvm::real lambda) -{ - cached_alch_lambda = lambda; - cached_alch_lambda_changed = true; -} - - -int colvarproxy_system::send_alch_lambda() -{ - return cvm::error("Error in set_alch_lambda: alchemical lambda dynamics is not supported by this build.", - COLVARS_NOT_IMPLEMENTED); -} - - -int colvarproxy_system::get_dE_dlambda(cvm::real * /* force */) -{ - return cvm::error("Error in get_dE_dlambda: alchemical lambda dynamics is not supported by this build.", - COLVARS_NOT_IMPLEMENTED); -} - - -int colvarproxy_system::apply_force_dE_dlambda(cvm::real* /* force */) -{ - return cvm::error("Error in apply_force_dE_dlambda: function is not implemented by this build.", - COLVARS_NOT_IMPLEMENTED); -} - - -int colvarproxy_system::get_d2E_dlambda2(cvm::real*) -{ - return cvm::error("Error in get_d2E_dlambda2: function is not implemented by this build.", - COLVARS_NOT_IMPLEMENTED); -} - - colvarproxy_atoms::colvarproxy_atoms() { atoms_rms_applied_force_ = atoms_max_applied_force_ = 0.0; @@ -249,7 +36,7 @@ colvarproxy_atoms::~colvarproxy_atoms() int colvarproxy_atoms::reset() { atoms_ids.clear(); - atoms_ncopies.clear(); + atoms_refcount.clear(); atoms_masses.clear(); atoms_charges.clear(); atoms_positions.clear(); @@ -262,7 +49,7 @@ int colvarproxy_atoms::reset() int colvarproxy_atoms::add_atom_slot(int atom_id) { atoms_ids.push_back(atom_id); - atoms_ncopies.push_back(1); + atoms_refcount.push_back(1); atoms_masses.push_back(1.0); atoms_charges.push_back(0.0); atoms_positions.push_back(cvm::rvector(0.0, 0.0, 0.0)); @@ -309,12 +96,22 @@ void colvarproxy_atoms::clear_atom(int index) cvm::error("Error: trying to disable an atom that was not previously requested.\n", COLVARS_INPUT_ERROR); } - if (atoms_ncopies[index] > 0) { - atoms_ncopies[index] -= 1; + if (atoms_refcount[index] > 0) { + atoms_refcount[index] -= 1; } } +size_t colvarproxy_atoms::get_num_active_atoms() const +{ + size_t result = 0; + for (size_t i = 0; i < atoms_refcount.size(); i++) { + if (atoms_refcount[i] > 0) result++; + } + return result; +} + + int colvarproxy_atoms::load_atoms(char const * /* filename */, cvm::atom_group & /* atoms */, std::string const & /* pdb_field */, @@ -382,7 +179,7 @@ colvarproxy_atom_groups::~colvarproxy_atom_groups() int colvarproxy_atom_groups::reset() { atom_groups_ids.clear(); - atom_groups_ncopies.clear(); + atom_groups_refcount.clear(); atom_groups_masses.clear(); atom_groups_charges.clear(); atom_groups_coms.clear(); @@ -395,7 +192,7 @@ int colvarproxy_atom_groups::reset() int colvarproxy_atom_groups::add_atom_group_slot(int atom_group_id) { atom_groups_ids.push_back(atom_group_id); - atom_groups_ncopies.push_back(1); + atom_groups_refcount.push_back(1); atom_groups_masses.push_back(1.0); atom_groups_charges.push_back(0.0); atom_groups_coms.push_back(cvm::rvector(0.0, 0.0, 0.0)); @@ -427,12 +224,22 @@ void colvarproxy_atom_groups::clear_atom_group(int index) "that was not previously requested.\n", COLVARS_INPUT_ERROR); } - if (atom_groups_ncopies[index] > 0) { - atom_groups_ncopies[index] -= 1; + if (atom_groups_refcount[index] > 0) { + atom_groups_refcount[index] -= 1; } } +size_t colvarproxy_atom_groups::get_num_active_atom_groups() const +{ + size_t result = 0; + for (size_t i = 0; i < atom_groups_refcount.size(); i++) { + if (atom_groups_refcount[i] > 0) result++; + } + return result; +} + + void colvarproxy_atom_groups::compute_rms_atom_groups_applied_force() { atom_groups_rms_applied_force_ = @@ -454,8 +261,8 @@ colvarproxy_smp::colvarproxy_smp() omp_lock_state = NULL; #if defined(_OPENMP) if (omp_get_thread_num() == 0) { - omp_lock_state = reinterpret_cast(new omp_lock_t); - omp_init_lock(reinterpret_cast(omp_lock_state)); + omp_lock_state = new omp_lock_t; + omp_init_lock(omp_lock_state); } #endif } @@ -466,7 +273,7 @@ colvarproxy_smp::~colvarproxy_smp() #if defined(_OPENMP) if (omp_get_thread_num() == 0) { if (omp_lock_state) { - delete reinterpret_cast(omp_lock_state); + delete omp_lock_state; } } #endif @@ -567,7 +374,7 @@ int colvarproxy_smp::smp_thread_id() #if defined(_OPENMP) return omp_get_thread_num(); #else - return COLVARS_NOT_IMPLEMENTED; + return -1; #endif } @@ -577,7 +384,7 @@ int colvarproxy_smp::smp_num_threads() #if defined(_OPENMP) return omp_get_max_threads(); #else - return COLVARS_NOT_IMPLEMENTED; + return -1; #endif } @@ -585,7 +392,7 @@ int colvarproxy_smp::smp_num_threads() int colvarproxy_smp::smp_lock() { #if defined(_OPENMP) - omp_set_lock(reinterpret_cast(omp_lock_state)); + omp_set_lock(omp_lock_state); #endif return COLVARS_OK; } @@ -594,8 +401,7 @@ int colvarproxy_smp::smp_lock() int colvarproxy_smp::smp_trylock() { #if defined(_OPENMP) - return omp_test_lock(reinterpret_cast(omp_lock_state)) ? - COLVARS_OK : COLVARS_ERROR; + return omp_test_lock(omp_lock_state) ? COLVARS_OK : COLVARS_ERROR; #else return COLVARS_OK; #endif @@ -605,7 +411,7 @@ int colvarproxy_smp::smp_trylock() int colvarproxy_smp::smp_unlock() { #if defined(_OPENMP) - omp_unset_lock(reinterpret_cast(omp_lock_state)); + omp_unset_lock(omp_lock_state); #endif return COLVARS_OK; } @@ -651,151 +457,35 @@ int colvarproxy_script::run_colvar_gradient_callback(std::string const & /* name -colvarproxy_io::colvarproxy_io() -{ - input_buffer_ = NULL; - restart_frequency_engine = 0; -} - - -colvarproxy_io::~colvarproxy_io() {} - - -int colvarproxy_io::get_frame(long int&) -{ - return COLVARS_NOT_IMPLEMENTED; -} - - -int colvarproxy_io::set_frame(long int) -{ - return COLVARS_NOT_IMPLEMENTED; -} - - -int colvarproxy_io::backup_file(char const *filename) -{ - // Simplified version of NAMD_file_exists() - int exit_code; - do { -#if defined(_WIN32) && !defined(__CYGWIN__) - // We could use _access_s here, but it is probably too new - exit_code = _access(filename, 00); -#else - exit_code = access(filename, F_OK); -#endif - } while ((exit_code != 0) && (errno == EINTR)); - if (exit_code != 0) { - if (errno == ENOENT) { - // File does not exist - return COLVARS_OK; - } else { - return cvm::error("Unknown error while checking if file \""+ - std::string(filename)+"\" exists.\n", COLVARS_ERROR); - } - } - - // The file exists, then rename it - if (std::string(filename).rfind(std::string(".colvars.state")) != - std::string::npos) { - return rename_file(filename, (std::string(filename)+".old").c_str()); - } else { - return rename_file(filename, (std::string(filename)+".BAK").c_str()); - } -} - - -int colvarproxy_io::remove_file(char const *filename) -{ - int error_code = COLVARS_OK; -#if defined(_WIN32) && !defined(__CYGWIN__) - // Because the file may be open by other processes, rename it to filename.old - std::string const renamed_file(std::string(filename)+".old"); - // It may still be there from an interrupted run, so remove it to be safe - std::remove(renamed_file.c_str()); - int rename_exit_code = 0; - while ((rename_exit_code = std::rename(filename, - renamed_file.c_str())) != 0) { - if (errno == EINTR) continue; - error_code |= COLVARS_FILE_ERROR; - break; - } - // Ask to remove filename.old, but ignore any errors raised - std::remove(renamed_file.c_str()); -#else - if (std::remove(filename)) { - if (errno != ENOENT) { - error_code |= COLVARS_FILE_ERROR; - } - } -#endif - if (error_code != COLVARS_OK) { - return cvm::error("Error: in removing file \""+std::string(filename)+ - "\".\n.", - error_code); - } - return COLVARS_OK; -} - - -int colvarproxy_io::rename_file(char const *filename, char const *newfilename) -{ - int error_code = COLVARS_OK; -#if defined(_WIN32) && !defined(__CYGWIN__) - // On straight Windows, must remove the destination before renaming it - error_code |= remove_file(newfilename); -#endif - int rename_exit_code = 0; - while ((rename_exit_code = std::rename(filename, newfilename)) != 0) { - if (errno == EINTR) continue; - // Call log() instead of error to allow the next try - cvm::log("Error: in renaming file \""+std::string(filename)+"\" to \""+ - std::string(newfilename)+"\".\n."); - error_code |= COLVARS_FILE_ERROR; - if (errno == EXDEV) continue; - break; - } - return rename_exit_code ? error_code : COLVARS_OK; -} - - - colvarproxy::colvarproxy() { colvars = NULL; + // By default, simulation engines allow to immediately request atoms + engine_ready_ = true; b_simulation_running = true; b_simulation_continuing = false; b_delete_requested = false; version_int = -1; features_hash = 0; + config_queue_ = reinterpret_cast(new std::list >); } colvarproxy::~colvarproxy() { - close_files(); + close_output_streams(); if (colvars != NULL) { delete colvars; colvars = NULL; } + delete reinterpret_cast > *>(config_queue_); } -int colvarproxy::close_files() +bool colvarproxy::io_available() { - if (smp_enabled() == COLVARS_OK && smp_thread_id() > 0) { - // Nothing to do on non-master threads - return COLVARS_OK; - } - std::list::iterator osni = output_stream_names.begin(); - std::list::iterator osi = output_files.begin(); - for ( ; osi != output_files.end(); osi++, osni++) { - ((std::ofstream *) (*osi))->close(); - delete *osi; - } - output_files.clear(); - output_stream_names.clear(); - return COLVARS_OK; + return (smp_enabled() == COLVARS_OK && smp_thread_id() == 0) || + (smp_enabled() != COLVARS_OK); } @@ -816,12 +506,41 @@ int colvarproxy::request_deletion() } +void colvarproxy::add_config(std::string const &cmd, std::string const &conf) +{ + reinterpret_cast > *>(config_queue_)->push_back(std::make_pair(cmd, conf)); +} + + int colvarproxy::setup() { return COLVARS_OK; } +int colvarproxy::parse_module_config() +{ + int error_code = COLVARS_OK; + // Read any configuration queued up for Colvars + std::list > *config_queue = reinterpret_cast > *>(config_queue_); + while (config_queue->size() > 0) { + std::pair const &p = config_queue->front(); + if (p.first == "config") { + error_code |= colvars->read_config_string(p.second); + } else if (p.first == "configfile") { + error_code |= colvars->read_config_file(p.second.c_str()); + } else { + error_code |= cvm::error(std::string("Error: invalid keyword \"") + + p.first + + std::string("\" in colvarproxy::setup()\n"), + COLVARS_BUG_ERROR); + } + config_queue->pop_front(); + } + return error_code; +} + + int colvarproxy::update_input() { return COLVARS_OK; @@ -874,7 +593,7 @@ void colvarproxy::print_input_atomic_data() cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ "atoms_ids = "+cvm::to_str(atoms_ids)+"\n"); cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ - "atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n"); + "atoms_refcount = "+cvm::to_str(atoms_refcount)+"\n"); cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ "atoms_masses = "+cvm::to_str(atoms_masses)+"\n"); cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ @@ -893,7 +612,7 @@ void colvarproxy::print_input_atomic_data() cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ "atom_groups_ids = "+cvm::to_str(atom_groups_ids)+"\n"); cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ - "atom_groups_ncopies = "+cvm::to_str(atom_groups_ncopies)+"\n"); + "atom_groups_refcount = "+cvm::to_str(atom_groups_refcount)+"\n"); cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ "atom_groups_masses = "+cvm::to_str(atom_groups_masses)+"\n"); cvm::log("Step "+cvm::to_str(cvm::step_absolute())+", "+ @@ -988,103 +707,3 @@ int colvarproxy::get_version_from_string(char const *version_string) } -void colvarproxy::smp_stream_error() -{ - cvm::error("Error: trying to access an output stream from a " - "multi-threaded region (bug). For a quick workaround, use " - "\"smp off\" in the Colvars config.\n", COLVARS_BUG_ERROR); -} - - -std::ostream * colvarproxy::output_stream(std::string const &output_name, - std::ios_base::openmode mode) -{ - if (cvm::debug()) { - cvm::log("Using colvarproxy::output_stream()\n"); - } - - std::ostream *os = get_output_stream(output_name); - if (os != NULL) return os; - - if (!(mode & (std::ios_base::app | std::ios_base::ate))) { - backup_file(output_name); - } - std::ofstream *osf = new std::ofstream(output_name.c_str(), mode); - if (!osf->is_open()) { - cvm::error("Error: cannot write to file/channel \""+output_name+"\".\n", - COLVARS_FILE_ERROR); - return NULL; - } - output_stream_names.push_back(output_name); - output_files.push_back(osf); - return osf; -} - - -std::ostream *colvarproxy::get_output_stream(std::string const &output_name) -{ - if (smp_enabled() == COLVARS_OK) { - if (smp_thread_id() > 0) smp_stream_error(); - } - std::list::iterator osi = output_files.begin(); - std::list::iterator osni = output_stream_names.begin(); - for ( ; osi != output_files.end(); osi++, osni++) { - if (*osni == output_name) { - return *osi; - } - } - return NULL; -} - - - -int colvarproxy::flush_output_stream(std::ostream *os) -{ - if (smp_enabled() == COLVARS_OK) { - if (smp_thread_id() > 0) smp_stream_error(); - } - std::list::iterator osi = output_files.begin(); - std::list::iterator osni = output_stream_names.begin(); - for ( ; osi != output_files.end(); osi++, osni++) { - if (*osi == os) { - ((std::ofstream *) (*osi))->flush(); - return COLVARS_OK; - } - } - return cvm::error("Error: trying to flush an output file/channel " - "that wasn't open.\n", COLVARS_BUG_ERROR); -} - - -int colvarproxy::flush_output_streams() -{ - if (smp_enabled() == COLVARS_OK && smp_thread_id() > 0) - return COLVARS_OK; - - std::list::iterator osi = output_files.begin(); - for ( ; osi != output_files.end(); osi++) { - ((std::ofstream *) (*osi))->flush(); - } - return COLVARS_OK; -} - - -int colvarproxy::close_output_stream(std::string const &output_name) -{ - if (smp_enabled() == COLVARS_OK) { - if (smp_thread_id() > 0) smp_stream_error(); - } - std::list::iterator osi = output_files.begin(); - std::list::iterator osni = output_stream_names.begin(); - for ( ; osi != output_files.end(); osi++, osni++) { - if (*osni == output_name) { - ((std::ofstream *) (*osi))->close(); - delete *osi; - output_files.erase(osi); - output_stream_names.erase(osni); - return COLVARS_OK; - } - } - return cvm::error("Error: trying to close an output file/channel " - "that wasn't open.\n", COLVARS_BUG_ERROR); -} diff --git a/lib/colvars/colvarproxy.h b/lib/colvars/colvarproxy.h index 3ed3768aef..5733b8b66d 100644 --- a/lib/colvars/colvarproxy.h +++ b/lib/colvars/colvarproxy.h @@ -10,12 +10,11 @@ #ifndef COLVARPROXY_H #define COLVARPROXY_H -#include -#include - #include "colvarmodule.h" #include "colvartypes.h" #include "colvarvalue.h" +#include "colvarproxy_io.h" +#include "colvarproxy_system.h" #include "colvarproxy_tcl.h" #include "colvarproxy_volmaps.h" @@ -38,165 +37,6 @@ class colvarscript; -/// Methods for accessing the simulation system (PBCs, integrator, etc) -class colvarproxy_system { - -public: - - /// Constructor - colvarproxy_system(); - - /// Destructor - virtual ~colvarproxy_system(); - - /// \brief Name of the unit system used internally by Colvars (by default, that of the back-end). - /// Supported depending on the back-end: real (A, kcal/mol), metal (A, eV), electron (Bohr, Hartree), gromacs (nm, kJ/mol) - /// Note: calls to back-end PBC functions assume back-end length unit - /// We use different unit from back-end in VMD bc using PBC functions from colvarproxy base class - /// Colvars internal units are user specified, because the module exchanges info in unknown - /// composite dimensions with user input, while it only exchanges quantities of known - /// dimension with the back-end (length and forces) - std::string units; - - /// \brief Request to set the units used internally by Colvars - virtual int set_unit_system(std::string const &units, bool check_only); - - /// \brief Value of 1 Angstrom in the internal (front-end) Colvars unit for atomic coordinates - /// * defaults to 0. in the base class; derived proxy classes must set it - /// * in VMD proxy, can only be changed when no variables are defined - /// as user-defined values in composite units must be compatible with that system - cvm::real angstrom_value; - - /// \brief Value of 1 Angstrom in the backend's unit for atomic coordinates - virtual cvm::real backend_angstrom_value(); - - /// \brief Value of 1 kcal/mol in the internal Colvars unit for energy - cvm::real kcal_mol_value; - - /// \brief Convert a length from Angstrom to internal - inline cvm::real angstrom_to_internal(cvm::real l) const - { - return l * angstrom_value; - } - - /// \brief Convert a length from internal to Angstrom - inline cvm::real internal_to_angstrom(cvm::real l) const - { - return l / angstrom_value; - } - - // /// \brief Convert a length from back-end unit to internal - // inline cvm::real back_end_to_internal_unit(cvm::real l) { - // if (angstrom_value == 0.) { - // return l / backend_angstrom_value(); - // } - // return l * angstrom_value / backend_angstrom_value(); - // } - - /// \brief Boltzmann constant in internal Colvars units - virtual cvm::real boltzmann(); - - /// \brief Target temperature of the simulation (K units) - virtual cvm::real temperature(); - - /// \brief Time step of the simulation (fs) - virtual cvm::real dt(); - - /// \brief Pseudo-random number with Gaussian distribution - virtual cvm::real rand_gaussian(void); - - /// Pass restraint energy value for current timestep to MD engine - virtual void add_energy(cvm::real energy); - - /// \brief Get the PBC-aware distance vector between two positions - virtual cvm::rvector position_distance(cvm::atom_pos const &pos1, - cvm::atom_pos const &pos2) const; - - /// Recompute PBC reciprocal lattice (assumes XYZ periodicity) - void update_pbc_lattice(); - - /// Set the lattice vectors to zero - void reset_pbc_lattice(); - - /// \brief Tell the proxy whether total forces are needed (they may not - /// always be available) - virtual void request_total_force(bool yesno); - - /// Are total forces being used? - virtual bool total_forces_enabled() const; - - /// Are total forces from the current step available? - virtual bool total_forces_same_step() const; - - /// Get the molecule ID when called in VMD; raise error otherwise - /// \param molid Set this argument equal to the current VMD molid - virtual int get_molid(int &molid); - - /// Get value of alchemical lambda parameter from back-end (if available) - virtual int get_alch_lambda(cvm::real* lambda); - - /// Set value of alchemical lambda parameter to be sent to back-end at end of timestep - void set_alch_lambda(cvm::real lambda); - - /// Send cached value of alchemical lambda parameter to back-end (if available) - virtual int send_alch_lambda(); - - /// Get energy derivative with respect to lambda (if available) - virtual int get_dE_dlambda(cvm::real* dE_dlambda); - - /// Apply a scalar force on dE_dlambda (back-end distributes it onto atoms) - virtual int apply_force_dE_dlambda(cvm::real* force); - - /// Get energy second derivative with respect to lambda (if available) - virtual int get_d2E_dlambda2(cvm::real* d2E_dlambda2); - - /// Force to be applied onto alch. lambda, propagated from biasing forces on dE_dlambda - cvm::real indirect_lambda_biasing_force; - - /// Get weight factor from accelMD - virtual cvm::real get_accelMD_factor() const { - cvm::error("Error: accessing the reweighting factor of accelerated MD " - "is not yet implemented in the MD engine.\n", - COLVARS_NOT_IMPLEMENTED); - return 1.0; - } - virtual bool accelMD_enabled() const { - return false; - } - -protected: - /// Next value of lambda to be sent to back-end - cvm::real cached_alch_lambda; - - /// Whether lambda has been set and needs to be updated in backend - bool cached_alch_lambda_changed; - - /// Whether the total forces have been requested - bool total_force_requested; - - /// \brief Type of boundary conditions - /// - /// Orthogonal and triclinic cells are made available to objects. - /// For any other conditions (mixed periodicity, triclinic cells in LAMMPS) - /// minimum-image distances are computed by the host engine regardless. - enum Boundaries_type { - boundaries_non_periodic, - boundaries_pbc_ortho, - boundaries_pbc_triclinic, - boundaries_unsupported - }; - - /// Type of boundary conditions - Boundaries_type boundaries_type; - - /// Bravais lattice vectors - cvm::rvector unit_cell_x, unit_cell_y, unit_cell_z; - - /// Reciprocal lattice vectors - cvm::rvector reciprocal_cell_x, reciprocal_cell_y, reciprocal_cell_z; -}; - - /// \brief Container of atomic data for processing by Colvars class colvarproxy_atoms { @@ -229,7 +69,7 @@ public: std::string const &segment_id); /// \brief Used by the atom class destructor: rather than deleting the array slot - /// (costly) set the corresponding atoms_ncopies to zero + /// (costly) set the corresponding atoms_refcount to zero virtual void clear_atom(int index); /// \brief Select atom IDs from a file (usually PDB) \param filename name of @@ -260,37 +100,51 @@ public: /// Clear atomic data int reset(); - /// Get the numeric ID of the given atom (for the program) + /// Get the numeric ID of the given atom + /// \param index Internal index in the Colvars arrays inline int get_atom_id(int index) const { return atoms_ids[index]; } /// Get the mass of the given atom + /// \param index Internal index in the Colvars arrays inline cvm::real get_atom_mass(int index) const { return atoms_masses[index]; } + /// Increase the reference count of the given atom + /// \param index Internal index in the Colvars arrays + inline void increase_refcount(int index) + { + atoms_refcount[index] += 1; + } + /// Get the charge of the given atom + /// \param index Internal index in the Colvars arrays inline cvm::real get_atom_charge(int index) const { return atoms_charges[index]; } /// Read the current position of the given atom + /// \param index Internal index in the Colvars arrays inline cvm::rvector get_atom_position(int index) const { return atoms_positions[index]; } /// Read the current total force of the given atom + /// \param index Internal index in the Colvars arrays inline cvm::rvector get_atom_total_force(int index) const { return atoms_total_forces[index]; } /// Request that this force is applied to the given atom + /// \param index Internal index in the Colvars arrays + /// \param new_force Force to add inline void apply_atom_force(int index, cvm::rvector const &new_force) { atoms_new_colvar_forces[index] += new_force; @@ -310,6 +164,9 @@ public: return &atoms_ids; } + /// Return number of atoms with positive reference count + size_t get_num_active_atoms() const; + inline std::vector const *get_atom_masses() const { return &atoms_masses; @@ -406,7 +263,7 @@ protected: /// within the host program std::vector atoms_ids; /// \brief Keep track of how many times each atom is used by a separate colvar object - std::vector atoms_ncopies; + std::vector atoms_refcount; /// \brief Masses of the atoms (allow redefinition during a run, as done e.g. in LAMMPS) std::vector atoms_masses; /// \brief Charges of the atoms (allow redefinition during a run, as done e.g. in LAMMPS) @@ -510,6 +367,9 @@ public: return &atom_groups_ids; } + /// Return number of atom groups with positive reference count + size_t get_num_active_atom_groups() const; + inline std::vector *modify_atom_group_masses() { // TODO updated_masses @@ -561,7 +421,7 @@ protected: /// within the host program std::vector atom_groups_ids; /// \brief Keep track of how many times each group is used by a separate cvc - std::vector atom_groups_ncopies; + std::vector atom_groups_refcount; /// \brief Total masses of the atom groups std::vector atom_groups_masses; /// \brief Total charges of the atom groups (allow redefinition during a run, as done e.g. in LAMMPS) @@ -584,6 +444,12 @@ protected: }; +#if defined(_OPENMP) +#include +#else +struct omp_lock_t; +#endif + /// \brief Methods for SMP parallelization class colvarproxy_smp { @@ -629,7 +495,7 @@ public: protected: /// Lock state for OpenMP - void *omp_lock_state; + omp_lock_t *omp_lock_state; }; @@ -698,108 +564,6 @@ public: }; -/// Methods for data input/output -class colvarproxy_io { - -public: - - /// Constructor - colvarproxy_io(); - - /// Destructor - virtual ~colvarproxy_io(); - - /// \brief Save the current frame number in the argument given - // Returns error code - virtual int get_frame(long int &); - - /// \brief Set the current frame number (as well as colvarmodule::it) - // Returns error code - virtual int set_frame(long int); - - /// \brief Rename the given file, before overwriting it - virtual int backup_file(char const *filename); - - /// \brief Rename the given file, before overwriting it - inline int backup_file(std::string const &filename) - { - return backup_file(filename.c_str()); - } - - /// Remove the given file (on Windows only, rename to filename.old) - virtual int remove_file(char const *filename); - - /// Remove the given file (on Windows only, rename to filename.old) - inline int remove_file(std::string const &filename) - { - return remove_file(filename.c_str()); - } - - /// Rename the given file - virtual int rename_file(char const *filename, char const *newfilename); - - /// Rename the given file - inline int rename_file(std::string const &filename, - std::string const &newfilename) - { - return rename_file(filename.c_str(), newfilename.c_str()); - } - - /// Prefix of the input state file to be read next - inline std::string & input_prefix() - { - return input_prefix_str; - } - - /// Default prefix to be used for all output files (final configuration) - inline std::string & output_prefix() - { - return output_prefix_str; - } - - /// Prefix of the restart (checkpoint) file to be written next - inline std::string & restart_output_prefix() - { - return restart_output_prefix_str; - } - - /// Default restart frequency (as set by the simulation engine) - inline int default_restart_frequency() const - { - return restart_frequency_engine; - } - - /// Buffer from which the input state information may be read - inline char const * & input_buffer() - { - return input_buffer_; - } - -protected: - - /// Prefix of the input state file to be read next - std::string input_prefix_str; - - /// Default prefix to be used for all output files (final configuration) - std::string output_prefix_str; - - /// Prefix of the restart (checkpoint) file to be written next - std::string restart_output_prefix_str; - - /// How often the simulation engine will write its own restart - int restart_frequency_engine; - - /// \brief Currently opened output files: by default, these are ofstream objects. - /// Allows redefinition to implement different output mechanisms - std::list output_files; - /// \brief Identifiers for output_stream objects: by default, these are the names of the files - std::list output_stream_names; - - /// Buffer from which the input state information may be read - char const *input_buffer_; -}; - - /// \brief Interface between the collective variables module and /// the simulation or analysis program (NAMD, VMD, LAMMPS...). @@ -827,6 +591,8 @@ public: /// Destructor virtual ~colvarproxy(); + virtual bool io_available() /* override */; + /// Request deallocation of the module (currently only implemented by VMD) virtual int request_deletion(); @@ -839,21 +605,30 @@ public: /// \brief Reset proxy state, e.g. requested atoms virtual int reset(); - /// Close any open files to prevent data loss - int close_files(); + /// (Re)initialize the module + virtual int parse_module_config(); - /// (Re)initialize required member data after construction + /// (Re)initialize required member data (called after the module) virtual int setup(); - /// \brief Update data required by the colvars module (e.g. cache atom positions) + /// Whether the engine allows to fully initialize Colvars immediately + inline bool engine_ready() const + { + return engine_ready_; + } + + /// Enqueue new configuration text, to be parsed as soon as possible + void add_config(std::string const &cmd, std::string const &conf); + + /// Update data required by Colvars module (e.g. read atom positions) /// /// TODO Break up colvarproxy_namd and colvarproxy_lammps function into these virtual int update_input(); - /// \brief Update data based from the results of a module update (e.g. send forces) + /// Update data based on the results of a Colvars call (e.g. send forces) virtual int update_output(); - /// Carry out operations needed before next step is run + /// Carry out operations needed before next simulation step is run int end_of_step(); /// Print a message to the main log @@ -903,26 +678,11 @@ public: return version_int; } - /// \brief Returns a reference to the given output channel; - /// if this is not open already, then open it - virtual std::ostream *output_stream(std::string const &output_name, - std::ios_base::openmode mode = - std::ios_base::out); - - /// Returns a reference to output_name if it exists, NULL otherwise - virtual std::ostream *get_output_stream(std::string const &output_name); - - /// \brief Flushes the given output channel - virtual int flush_output_stream(std::ostream *os); - - /// \brief Flushes all output channels - virtual int flush_output_streams(); - - /// \brief Closes the given output channel - virtual int close_output_stream(std::string const &output_name); - protected: + /// Whether the engine allows to fully initialize Colvars immediately + bool engine_ready_; + /// Collected error messages std::string error_output; @@ -943,8 +703,10 @@ protected: /// Track which features have been acknowledged during the last run size_t features_hash; - /// Raise when the output stream functions are used on threads other than 0 - void smp_stream_error(); +private: + + /// Queue of config strings or files to be fed to the module + void *config_queue_; }; diff --git a/lib/colvars/colvarproxy_io.cpp b/lib/colvars/colvarproxy_io.cpp new file mode 100644 index 0000000000..225ca40bef --- /dev/null +++ b/lib/colvars/colvarproxy_io.cpp @@ -0,0 +1,310 @@ +// -*- c++ -*- + +// This file is part of the Collective Variables module (Colvars). +// The original version of Colvars and its updates are located at: +// https://github.com/Colvars/colvars +// Please update all Colvars source files before making any changes. +// If you wish to distribute your changes, please submit them to the +// Colvars repository at GitHub. + +// Using access() to check if a file exists (until we can assume C++14/17) +#if !defined(_WIN32) || defined(__CYGWIN__) +#include +#endif +#if defined(_WIN32) +#include +#endif + +#include +#include + +#include +#include +#include +#include + +#include "colvarmodule.h" +#include "colvarproxy_io.h" + + +colvarproxy_io::colvarproxy_io() +{ + input_buffer_ = NULL; + restart_frequency_engine = 0; + input_stream_error_ = new std::istringstream(); + input_stream_error_->setstate(std::ios::badbit); + output_stream_error_ = new std::ostringstream(); + output_stream_error_->setstate(std::ios::badbit); +} + + +colvarproxy_io::~colvarproxy_io() +{ + delete input_stream_error_; + close_input_streams(); + delete output_stream_error_; + close_output_streams(); +} + + +bool colvarproxy_io::io_available() +{ + return false; +} + + +int colvarproxy_io::get_frame(long int&) +{ + return COLVARS_NOT_IMPLEMENTED; +} + + +int colvarproxy_io::set_frame(long int) +{ + return COLVARS_NOT_IMPLEMENTED; +} + + +int colvarproxy_io::backup_file(char const *filename) +{ + // Simplified version of NAMD_file_exists() + int exit_code; + do { +#if defined(_WIN32) && !defined(__CYGWIN__) + // We could use _access_s here, but it is probably too new + exit_code = _access(filename, 00); +#else + exit_code = access(filename, F_OK); +#endif + } while ((exit_code != 0) && (errno == EINTR)); + if (exit_code != 0) { + if (errno == ENOENT) { + // File does not exist + return COLVARS_OK; + } else { + return cvm::error("Unknown error while checking if file \""+ + std::string(filename)+"\" exists.\n", COLVARS_ERROR); + } + } + + // The file exists, then rename it + if (std::string(filename).rfind(std::string(".colvars.state")) != + std::string::npos) { + return rename_file(filename, (std::string(filename)+".old").c_str()); + } else { + return rename_file(filename, (std::string(filename)+".BAK").c_str()); + } +} + + +int colvarproxy_io::remove_file(char const *filename) +{ + int error_code = COLVARS_OK; +#if defined(_WIN32) && !defined(__CYGWIN__) + // Because the file may be open by other processes, rename it to filename.old + std::string const renamed_file(std::string(filename)+".old"); + // It may still be there from an interrupted run, so remove it to be safe + std::remove(renamed_file.c_str()); + int rename_exit_code = 0; + while ((rename_exit_code = std::rename(filename, + renamed_file.c_str())) != 0) { + if (errno == EINTR) continue; + error_code |= COLVARS_FILE_ERROR; + break; + } + // Ask to remove filename.old, but ignore any errors raised + std::remove(renamed_file.c_str()); +#else + if (std::remove(filename)) { + if (errno != ENOENT) { + error_code |= COLVARS_FILE_ERROR; + } + } +#endif + if (error_code != COLVARS_OK) { + return cvm::error("Error: in removing file \""+std::string(filename)+ + "\".\n.", + error_code); + } + return COLVARS_OK; +} + + +int colvarproxy_io::rename_file(char const *filename, char const *newfilename) +{ + int error_code = COLVARS_OK; +#if defined(_WIN32) && !defined(__CYGWIN__) + // On straight Windows, must remove the destination before renaming it + error_code |= remove_file(newfilename); +#endif + int rename_exit_code = 0; + while ((rename_exit_code = std::rename(filename, newfilename)) != 0) { + if (errno == EINTR) continue; + // Call log() instead of error to allow the next try + cvm::log("Error: in renaming file \""+std::string(filename)+"\" to \""+ + std::string(newfilename)+"\".\n."); + error_code |= COLVARS_FILE_ERROR; + if (errno == EXDEV) continue; + break; + } + return rename_exit_code ? error_code : COLVARS_OK; +} + + +std::istream &colvarproxy_io::input_stream(std::string const &input_name, + std::string const description, + bool error_on_fail) +{ + if (!io_available()) { + cvm::error("Error: trying to access an input file/channel " + "from the wrong thread.\n", COLVARS_BUG_ERROR); + return *input_stream_error_; + } + + if (colvarproxy_io::input_stream_exists(input_name)) { + return *(input_streams_[input_name]); + } + + // Using binary to work around differences in line termination conventions + // See https://github.com/Colvars/colvars/commit/8236879f7de4 + input_streams_[input_name] = new std::ifstream(input_name.c_str(), + std::ios::binary); + + if (input_streams_[input_name]->fail() && error_on_fail) { + cvm::error("Error: cannot open "+description+" \""+input_name+"\".\n", + COLVARS_FILE_ERROR); + } + + return *(input_streams_[input_name]); +} + + +bool colvarproxy_io::input_stream_exists(std::string const &input_name) +{ + return (input_streams_.count(input_name) > 0); +} + + +int colvarproxy_io::close_input_stream(std::string const &input_name) +{ + if (colvarproxy_io::input_stream_exists(input_name)) { + delete input_streams_[input_name]; + input_streams_.erase(input_name); + return COLVARS_OK; + } + return cvm::error("Error: input file/channel \""+input_name+ + "\" does not exist.\n", COLVARS_FILE_ERROR); +} + + +int colvarproxy_io::close_input_streams() +{ + for (std::map::iterator ii = input_streams_.begin(); + ii != input_streams_.end(); + ii++) { + delete ii->second; + } + input_streams_.clear(); + return COLVARS_OK; +} + + +std::ostream & colvarproxy_io::output_stream(std::string const &output_name, + std::string const description) +{ + if (cvm::debug()) { + cvm::log("Using colvarproxy_io::output_stream()\n"); + } + + if (!io_available()) { + cvm::error("Error: trying to access an output file/channel " + "from the wrong thread.\n", COLVARS_BUG_ERROR); + return *output_stream_error_; + } + + if (colvarproxy_io::output_stream_exists(output_name)) { + return *(output_streams_[output_name]); + } + + backup_file(output_name.c_str()); + + output_streams_[output_name] = new std::ofstream(output_name.c_str()); + if (!*(output_streams_[output_name])) { + cvm::error("Error: cannot write to "+description+" \""+output_name+"\".\n", + COLVARS_FILE_ERROR); + } + + return *(output_streams_[output_name]); +} + + +bool colvarproxy_io::output_stream_exists(std::string const &output_name) +{ + return (output_streams_.count(output_name) > 0); +} + + +int colvarproxy_io::flush_output_stream(std::string const &output_name) +{ + if (!io_available()) { + // No-op + return COLVARS_OK; + } + + if (colvarproxy_io::output_stream_exists(output_name)) { + (dynamic_cast(output_streams_[output_name]))->flush(); + return COLVARS_OK; + } + + return COLVARS_OK; +} + + +int colvarproxy_io::flush_output_streams() +{ + if (!io_available()) { + return COLVARS_OK; + } + + for (std::map::iterator osi = output_streams_.begin(); + osi != output_streams_.end(); + osi++) { + (dynamic_cast(osi->second))->flush(); + } + + return COLVARS_OK; +} + + +int colvarproxy_io::close_output_stream(std::string const &output_name) +{ + if (!io_available()) { + return cvm::error("Error: trying to access an output file/channel " + "from the wrong thread.\n", COLVARS_BUG_ERROR); + } + + if (colvarproxy_io::output_stream_exists(output_name)) { + (dynamic_cast(output_streams_[output_name]))->close(); + delete output_streams_[output_name]; + output_streams_.erase(output_name); + } + + return COLVARS_OK; +} + + +int colvarproxy_io::close_output_streams() +{ + if (! io_available()) { + return COLVARS_OK; + } + + for (std::map::iterator osi = output_streams_.begin(); + osi != output_streams_.end(); + osi++) { + (dynamic_cast(osi->second))->close(); + } + output_streams_.clear(); + + return COLVARS_OK; +} diff --git a/lib/colvars/colvarproxy_io.h b/lib/colvars/colvarproxy_io.h new file mode 100644 index 0000000000..ee217362d4 --- /dev/null +++ b/lib/colvars/colvarproxy_io.h @@ -0,0 +1,167 @@ +// -*- c++ -*- + +// This file is part of the Collective Variables module (Colvars). +// The original version of Colvars and its updates are located at: +// https://github.com/Colvars/colvars +// Please update all Colvars source files before making any changes. +// If you wish to distribute your changes, please submit them to the +// Colvars repository at GitHub. + +#ifndef COLVARPROXY_IO_H +#define COLVARPROXY_IO_H + +#include +#include +#include + + +/// Methods for data input/output +class colvarproxy_io { + +public: + + /// Constructor + colvarproxy_io(); + + /// Destructor + virtual ~colvarproxy_io(); + + /// Ensure that we're on the main thread (derived class will do actual check) + virtual bool io_available(); + + /// \brief Save the current frame number in the argument given + // Returns error code + virtual int get_frame(long int &); + + /// \brief Set the current frame number (as well as colvarmodule::it) + // Returns error code + virtual int set_frame(long int); + + /// \brief Rename the given file, before overwriting it + virtual int backup_file(char const *filename); + + /// \brief Rename the given file, before overwriting it + inline int backup_file(std::string const &filename) + { + return backup_file(filename.c_str()); + } + + /// Remove the given file (on Windows only, rename to filename.old) + virtual int remove_file(char const *filename); + + /// Remove the given file (on Windows only, rename to filename.old) + inline int remove_file(std::string const &filename) + { + return remove_file(filename.c_str()); + } + + /// Rename the given file + virtual int rename_file(char const *filename, char const *newfilename); + + /// Rename the given file + inline int rename_file(std::string const &filename, + std::string const &newfilename) + { + return rename_file(filename.c_str(), newfilename.c_str()); + } + + /// Prefix of the input state file to be read next + inline std::string & input_prefix() + { + return input_prefix_str; + } + + /// Default prefix to be used for all output files (final configuration) + inline std::string & output_prefix() + { + return output_prefix_str; + } + + /// Prefix of the restart (checkpoint) file to be written next + inline std::string & restart_output_prefix() + { + return restart_output_prefix_str; + } + + /// Default restart frequency (as set by the simulation engine) + inline int default_restart_frequency() const + { + return restart_frequency_engine; + } + + /// Buffer from which the input state information may be read + inline char const * & input_buffer() + { + return input_buffer_; + } + + /// Returns a reference to given input stream, creating it if needed + /// \param input_name File name (later only a handle) + /// \param description Purpose of the file + /// \param error_on_fail Raise error when failing to open (allow testing) + virtual std::istream &input_stream(std::string const &input_name, + std::string const description = "file/channel", + bool error_on_fail = true); + + /// Check if the file/channel is open (without opening it if not) + virtual bool input_stream_exists(std::string const &input_name); + + /// Closes the given input stream + virtual int close_input_stream(std::string const &input_name); + + /// Closes all input streams + virtual int close_input_streams(); + + /// Returns a reference to the named output file/channel (open it if needed) + /// \param output_name File name or identifier + /// \param description Purpose of the file + virtual std::ostream &output_stream(std::string const &output_name, + std::string const description = "file/channel"); + + /// Check if the file/channel is open (without opening it if not) + virtual bool output_stream_exists(std::string const &output_name); + + /// Flushes the given output file/channel + virtual int flush_output_stream(std::string const &output_name); + + /// Flushes all output files/channels + virtual int flush_output_streams(); + + /// Closes the given output file/channel + virtual int close_output_stream(std::string const &output_name); + + /// Close all open files/channels to prevent data loss + virtual int close_output_streams(); + +protected: + + /// Prefix of the input state file to be read next + std::string input_prefix_str; + + /// Default prefix to be used for all output files (final configuration) + std::string output_prefix_str; + + /// Prefix of the restart (checkpoint) file to be written next + std::string restart_output_prefix_str; + + /// How often the simulation engine will write its own restart + int restart_frequency_engine; + + /// Container of input files/channels indexed by path name + std::map input_streams_; + + /// Object whose reference is returned when read errors occur + std::istream *input_stream_error_; + + /// Currently open output files/channels + std::map output_streams_; + + /// Object whose reference is returned when write errors occur + std::ostream *output_stream_error_; + + /// Buffer from which the input state information may be read + char const *input_buffer_; +}; + + +#endif diff --git a/lib/colvars/colvarproxy_system.cpp b/lib/colvars/colvarproxy_system.cpp new file mode 100644 index 0000000000..0a2769dcc9 --- /dev/null +++ b/lib/colvars/colvarproxy_system.cpp @@ -0,0 +1,203 @@ +// -*- c++ -*- + +// This file is part of the Collective Variables module (Colvars). +// The original version of Colvars and its updates are located at: +// https://github.com/Colvars/colvars +// Please update all Colvars source files before making any changes. +// If you wish to distribute your changes, please submit them to the +// Colvars repository at GitHub. + + +#include "colvarmodule.h" +#include "colvartypes.h" +#include "colvarproxy_system.h" + + + +colvarproxy_system::colvarproxy_system() +{ + angstrom_value_ = 0.0; + kcal_mol_value_ = 0.0; + target_temperature_ = 0.0; + boltzmann_ = 0.001987191; // Default: kcal/mol/K + boundaries_type = boundaries_unsupported; + total_force_requested = false; + indirect_lambda_biasing_force = 0.0; + cached_alch_lambda_changed = false; + cached_alch_lambda = -1.0; + reset_pbc_lattice(); +} + + +colvarproxy_system::~colvarproxy_system() {} + + +int colvarproxy_system::set_unit_system(std::string const & /* units */, + bool /* check_only */) +{ + return COLVARS_NOT_IMPLEMENTED; +} + + +int colvarproxy_system::set_target_temperature(cvm::real T) +{ + target_temperature_ = T; + return COLVARS_OK; +} + + +cvm::real colvarproxy_system::dt() +{ + // TODO define, document and implement a user method to set the value of this + return 1.0; +} + + +cvm::real colvarproxy_system::rand_gaussian() +{ + // TODO define, document and implement a user method to set the value of this + return 0.0; +} + + +void colvarproxy_system::add_energy(cvm::real /* energy */) {} + + +void colvarproxy_system::request_total_force(bool yesno) +{ + if (yesno == true) + cvm::error("Error: total forces are currently not implemented.\n", + COLVARS_NOT_IMPLEMENTED); +} + + +bool colvarproxy_system::total_forces_enabled() const +{ + return false; +} + + +bool colvarproxy_system::total_forces_same_step() const +{ + return false; +} + + +inline int round_to_integer(cvm::real x) +{ + return int(cvm::floor(x+0.5)); +} + + +void colvarproxy_system::update_pbc_lattice() +{ + // Periodicity is assumed in all directions + + if (boundaries_type == boundaries_unsupported || + boundaries_type == boundaries_non_periodic) { + cvm::error("Error: setting PBC lattice with unsupported boundaries.\n", + COLVARS_BUG_ERROR); + return; + } + + { + cvm::rvector const v = cvm::rvector::outer(unit_cell_y, unit_cell_z); + reciprocal_cell_x = v/(v*unit_cell_x); + } + { + cvm::rvector const v = cvm::rvector::outer(unit_cell_z, unit_cell_x); + reciprocal_cell_y = v/(v*unit_cell_y); + } + { + cvm::rvector const v = cvm::rvector::outer(unit_cell_x, unit_cell_y); + reciprocal_cell_z = v/(v*unit_cell_z); + } +} + + +void colvarproxy_system::reset_pbc_lattice() +{ + unit_cell_x.reset(); + unit_cell_y.reset(); + unit_cell_z.reset(); + reciprocal_cell_x.reset(); + reciprocal_cell_y.reset(); + reciprocal_cell_z.reset(); +} + + +cvm::rvector colvarproxy_system::position_distance(cvm::atom_pos const &pos1, + cvm::atom_pos const &pos2) + const +{ + if (boundaries_type == boundaries_unsupported) { + cvm::error("Error: unsupported boundary conditions.\n", COLVARS_INPUT_ERROR); + } + + cvm::rvector diff = (pos2 - pos1); + + if (boundaries_type == boundaries_non_periodic) return diff; + + cvm::real const x_shift = round_to_integer(reciprocal_cell_x*diff); + cvm::real const y_shift = round_to_integer(reciprocal_cell_y*diff); + cvm::real const z_shift = round_to_integer(reciprocal_cell_z*diff); + + diff.x -= x_shift*unit_cell_x.x + y_shift*unit_cell_y.x + + z_shift*unit_cell_z.x; + diff.y -= x_shift*unit_cell_x.y + y_shift*unit_cell_y.y + + z_shift*unit_cell_z.y; + diff.z -= x_shift*unit_cell_x.z + y_shift*unit_cell_y.z + + z_shift*unit_cell_z.z; + + return diff; +} + + +int colvarproxy_system::get_molid(int &) +{ + cvm::error("Error: only VMD allows the use of multiple \"molecules\", " + "i.e. multiple molecular systems.", COLVARS_NOT_IMPLEMENTED); + return -1; +} + + +int colvarproxy_system::get_alch_lambda(cvm::real * /* lambda */) +{ + return cvm::error("Error in get_alch_lambda: alchemical lambda dynamics is not supported by this build.", + COLVARS_NOT_IMPLEMENTED); +} + + +void colvarproxy_system::set_alch_lambda(cvm::real lambda) +{ + cached_alch_lambda = lambda; + cached_alch_lambda_changed = true; +} + + +int colvarproxy_system::send_alch_lambda() +{ + return cvm::error("Error in set_alch_lambda: alchemical lambda dynamics is not supported by this build.", + COLVARS_NOT_IMPLEMENTED); +} + + +int colvarproxy_system::get_dE_dlambda(cvm::real * /* force */) +{ + return cvm::error("Error in get_dE_dlambda: alchemical lambda dynamics is not supported by this build.", + COLVARS_NOT_IMPLEMENTED); +} + + +int colvarproxy_system::apply_force_dE_dlambda(cvm::real* /* force */) +{ + return cvm::error("Error in apply_force_dE_dlambda: function is not implemented by this build.", + COLVARS_NOT_IMPLEMENTED); +} + + +int colvarproxy_system::get_d2E_dlambda2(cvm::real*) +{ + return cvm::error("Error in get_d2E_dlambda2: function is not implemented by this build.", + COLVARS_NOT_IMPLEMENTED); +} diff --git a/lib/colvars/colvarproxy_system.h b/lib/colvars/colvarproxy_system.h new file mode 100644 index 0000000000..be3cd346c2 --- /dev/null +++ b/lib/colvars/colvarproxy_system.h @@ -0,0 +1,177 @@ +// -*- c++ -*- + +// This file is part of the Collective Variables module (Colvars). +// The original version of Colvars and its updates are located at: +// https://github.com/Colvars/colvars +// Please update all Colvars source files before making any changes. +// If you wish to distribute your changes, please submit them to the +// Colvars repository at GitHub. + +#ifndef COLVARPROXY_SYSTEM_H +#define COLVARPROXY_SYSTEM_H + + +/// Methods for accessing the simulation system (PBCs, integrator, etc) +class colvarproxy_system { + +public: + + /// Constructor + colvarproxy_system(); + + /// Destructor + virtual ~colvarproxy_system(); + + /// \brief Name of the unit system used internally by Colvars (by default, that of the back-end). + /// Supported depending on the back-end: real (A, kcal/mol), metal (A, eV), electron (Bohr, Hartree), gromacs (nm, kJ/mol) + /// Note: calls to back-end PBC functions assume back-end length unit + /// We use different unit from back-end in VMD bc using PBC functions from colvarproxy base class + /// Colvars internal units are user specified, because the module exchanges info in unknown + /// composite dimensions with user input, while it only exchanges quantities of known + /// dimension with the back-end (length and forces) + std::string units; + + /// \brief Request to set the units used internally by Colvars + virtual int set_unit_system(std::string const &units, bool check_only); + + /// \brief Convert a length from Angstrom to internal + inline cvm::real angstrom_to_internal(cvm::real l) const + { + return l * angstrom_value_; + } + + /// \brief Convert a length from internal to Angstrom + inline cvm::real internal_to_angstrom(cvm::real l) const + { + return l / angstrom_value_; + } + + /// Boltzmann constant, with unit the same as energy / K + inline cvm::real boltzmann() const + { + return boltzmann_; + } + + /// Current target temperature of the simulation (K units) + inline cvm::real target_temperature() const + { + return target_temperature_; + } + + /// Set the current target temperature of the simulation (K units) + virtual int set_target_temperature(cvm::real T); + + /// \brief Time step of the simulation (fs) + virtual cvm::real dt(); + + /// \brief Pseudo-random number with Gaussian distribution + virtual cvm::real rand_gaussian(void); + + /// Pass restraint energy value for current timestep to MD engine + virtual void add_energy(cvm::real energy); + + /// \brief Get the PBC-aware distance vector between two positions + virtual cvm::rvector position_distance(cvm::atom_pos const &pos1, + cvm::atom_pos const &pos2) const; + + /// Recompute PBC reciprocal lattice (assumes XYZ periodicity) + void update_pbc_lattice(); + + /// Set the lattice vectors to zero + void reset_pbc_lattice(); + + /// \brief Tell the proxy whether total forces are needed (they may not + /// always be available) + virtual void request_total_force(bool yesno); + + /// Are total forces being used? + virtual bool total_forces_enabled() const; + + /// Are total forces from the current step available? + virtual bool total_forces_same_step() const; + + /// Get the molecule ID when called in VMD; raise error otherwise + /// \param molid Set this argument equal to the current VMD molid + virtual int get_molid(int &molid); + + /// Get value of alchemical lambda parameter from back-end (if available) + virtual int get_alch_lambda(cvm::real* lambda); + + /// Set value of alchemical lambda parameter to be sent to back-end at end of timestep + void set_alch_lambda(cvm::real lambda); + + /// Send cached value of alchemical lambda parameter to back-end (if available) + virtual int send_alch_lambda(); + + /// Get energy derivative with respect to lambda (if available) + virtual int get_dE_dlambda(cvm::real* dE_dlambda); + + /// Apply a scalar force on dE_dlambda (back-end distributes it onto atoms) + virtual int apply_force_dE_dlambda(cvm::real* force); + + /// Get energy second derivative with respect to lambda (if available) + virtual int get_d2E_dlambda2(cvm::real* d2E_dlambda2); + + /// Force to be applied onto alch. lambda, propagated from biasing forces on dE_dlambda + cvm::real indirect_lambda_biasing_force; + + /// Get weight factor from accelMD + virtual cvm::real get_accelMD_factor() const { + cvm::error("Error: accessing the reweighting factor of accelerated MD " + "is not yet implemented in the MD engine.\n", + COLVARS_NOT_IMPLEMENTED); + return 1.0; + } + virtual bool accelMD_enabled() const { + return false; + } + +protected: + + /// Next value of lambda to be sent to back-end + cvm::real cached_alch_lambda; + + /// Whether lambda has been set and needs to be updated in backend + bool cached_alch_lambda_changed; + + /// Boltzmann constant in internal Colvars units + cvm::real boltzmann_; + + /// Most up to date target temperature for the system (in K) + cvm::real target_temperature_; + + /// \brief Value of 1 Angstrom in the internal (front-end) Colvars unit for atomic coordinates + /// * defaults to 0 in the base class; derived proxy classes must set it + /// * in VMD proxy, can only be changed when no variables are defined + /// as user-defined values in composite units must be compatible with that system + cvm::real angstrom_value_; + + /// \brief Value of 1 kcal/mol in the internal Colvars unit for energy + cvm::real kcal_mol_value_; + + /// Whether the total forces have been requested + bool total_force_requested; + + /// \brief Type of boundary conditions + /// + /// Orthogonal and triclinic cells are made available to objects. + /// For any other conditions (mixed periodicity, triclinic cells in LAMMPS) + /// minimum-image distances are computed by the host engine regardless. + enum Boundaries_type { + boundaries_non_periodic, + boundaries_pbc_ortho, + boundaries_pbc_triclinic, + boundaries_unsupported + }; + + /// Type of boundary conditions + Boundaries_type boundaries_type; + + /// Bravais lattice vectors + cvm::rvector unit_cell_x, unit_cell_y, unit_cell_z; + + /// Reciprocal lattice vectors + cvm::rvector reciprocal_cell_x, reciprocal_cell_y, reciprocal_cell_z; +}; + +#endif diff --git a/lib/colvars/colvarproxy_tcl.cpp b/lib/colvars/colvarproxy_tcl.cpp index 700492f0e7..5bf97a0d98 100644 --- a/lib/colvars/colvarproxy_tcl.cpp +++ b/lib/colvars/colvarproxy_tcl.cpp @@ -8,6 +8,7 @@ // Colvars repository at GitHub. #include +#include #include "colvarmodule.h" #include "colvarproxy.h" diff --git a/lib/colvars/colvarproxy_volmaps.cpp b/lib/colvars/colvarproxy_volmaps.cpp index d0ae8b51ff..6c1f11e32e 100644 --- a/lib/colvars/colvarproxy_volmaps.cpp +++ b/lib/colvars/colvarproxy_volmaps.cpp @@ -33,7 +33,7 @@ int colvarproxy_volmaps::reset() clear_volmap(i); } volmaps_ids.clear(); - volmaps_ncopies.clear(); + volmaps_refcount.clear(); volmaps_values.clear(); volmaps_new_colvar_forces.clear(); return COLVARS_OK; @@ -43,7 +43,7 @@ int colvarproxy_volmaps::reset() int colvarproxy_volmaps::add_volmap_slot(int volmap_id) { volmaps_ids.push_back(volmap_id); - volmaps_ncopies.push_back(1); + volmaps_refcount.push_back(1); volmaps_values.push_back(0.0); volmaps_new_colvar_forces.push_back(0.0); return (volmaps_ids.size() - 1); @@ -95,8 +95,8 @@ void colvarproxy_volmaps::clear_volmap(int index) "previously requested.\n", COLVARS_INPUT_ERROR); } - if (volmaps_ncopies[index] > 0) { - volmaps_ncopies[index] -= 1; + if (volmaps_refcount[index] > 0) { + volmaps_refcount[index] -= 1; } } diff --git a/lib/colvars/colvarproxy_volmaps.h b/lib/colvars/colvarproxy_volmaps.h index 6e88ee83f9..f8c9ba8539 100644 --- a/lib/colvars/colvarproxy_volmaps.h +++ b/lib/colvars/colvarproxy_volmaps.h @@ -108,7 +108,7 @@ protected: /// \brief Keep track of how many times each vol map is used by a /// separate colvar object - std::vector volmaps_ncopies; + std::vector volmaps_refcount; /// \brief Current values of the vol maps std::vector volmaps_values; diff --git a/lib/colvars/colvars_version.h b/lib/colvars/colvars_version.h index d2a48f8af7..d500c0e5ec 100644 --- a/lib/colvars/colvars_version.h +++ b/lib/colvars/colvars_version.h @@ -1,3 +1,3 @@ #ifndef COLVARS_VERSION -#define COLVARS_VERSION "2022-05-24" +#define COLVARS_VERSION "2023-05-01" #endif diff --git a/lib/colvars/colvarscript_commands.h b/lib/colvars/colvarscript_commands.h index 7f208e5da6..6dd63d82d2 100644 --- a/lib/colvars/colvarscript_commands.h +++ b/lib/colvars/colvarscript_commands.h @@ -134,11 +134,19 @@ CVSCRIPT(cv_config, char const *conf_str = script->obj_to_str(script->get_module_cmd_arg(0, objc, objv)); std::string const conf(conf_str); - if (cvm::main()->read_config_string(conf) == COLVARS_OK) { - return COLVARS_OK; + script->proxy()->add_config("config", conf); + if (script->proxy()->engine_ready()) { + // Engine allows immediate initialization + if ((script->proxy()->parse_module_config() | + script->proxy()->setup()) == COLVARS_OK) { + return COLVARS_OK; + } else { + script->add_error_msg("Error parsing configuration string"); + return COLVARSCRIPT_ERROR; + } } - script->add_error_msg("Error parsing configuration string"); - return COLVARSCRIPT_ERROR; + // Engine not ready, config will be read during proxy->setup() + return COLVARS_OK; ) CVSCRIPT(cv_configfile, @@ -146,13 +154,20 @@ CVSCRIPT(cv_configfile, 1, 1, "conf_file : string - Path to configuration file", char const *conf_file_name = - script->obj_to_str(script->get_module_cmd_arg(0, objc, objv)); - if (script->module()->read_config_file(conf_file_name) == COLVARS_OK) { - return COLVARS_OK; - } else { - script->add_error_msg("Error parsing configuration file"); - return COLVARSCRIPT_ERROR; + script->obj_to_str(script->get_module_cmd_arg(0, objc, objv)); + script->proxy()->add_config("configfile", std::string(conf_file_name)); + if (script->proxy()->engine_ready()) { + // Engine allows immediate initialization + if ((script->proxy()->parse_module_config() | + script->proxy()->setup()) == COLVARS_OK) { + return COLVARS_OK; + } else { + script->add_error_msg("Error parsing configuration file"); + return COLVARSCRIPT_ERROR; + } } + // Engine not ready, config will be read during proxy->setup() + return COLVARS_OK; ) CVSCRIPT(cv_delete, @@ -309,6 +324,51 @@ CVSCRIPT(cv_getenergy, return COLVARS_OK; ) +CVSCRIPT(cv_getnumactiveatomgroups, + "Get the number of atom groups that currently have positive ref counts\n" + "count : integer - Total number of atom groups", + 0, 0, + "", + script->set_result_int(static_cast(script->proxy()->get_num_active_atom_groups())); + return COLVARS_OK; + ) + +CVSCRIPT(cv_getnumactiveatoms, + "Get the number of atoms that currently have positive ref counts\n" + "count : integer - Total number of atoms", + 0, 0, + "", + script->set_result_int(static_cast(script->proxy()->get_num_active_atoms())); + return COLVARS_OK; + ) + +CVSCRIPT(cv_getnumatoms, + "Get the number of requested atoms, including those not in use now\n" + "count : integer - Total number of atoms", + 0, 0, + "", + script->set_result_int(static_cast(script->proxy()->get_atom_ids()->size())); + return COLVARS_OK; + ) + +CVSCRIPT(cv_getstepabsolute, + "Get the current step number of the simulation (including restarts)\n" + "step : int - Absolute step number", + 0, 0, + "", + script->set_result_int(cvm::step_absolute()); + return COLVARS_OK; + ) + +CVSCRIPT(cv_getsteprelative, + "Get the current step number from the start of this job\n" + "step : int - Relative step number", + 0, 0, + "", + script->set_result_int(cvm::step_relative()); + return COLVARS_OK; + ) + CVSCRIPT(cv_help, "Get the help string of the Colvars scripting interface\n" "help : string - Help string", @@ -481,6 +541,7 @@ CVSCRIPT(cv_reset, "Delete all internal configuration", 0, 0, "", + cvm::log("Resetting the Collective Variables module."); return script->module()->reset(); ) @@ -516,6 +577,20 @@ CVSCRIPT(cv_savetostring, return script->module()->write_restart_string(script->modify_str_result()); ) +CVSCRIPT(cv_targettemperature, + "Get/set target temperature, overriding what the MD engine provides\n" + "T : float - Current target temperature in K", + 0, 1, + "T : float - New target temperature in K", + char const *Targ = + script->obj_to_str(script->get_module_cmd_arg(0, objc, objv)); + if (Targ == NULL) { + return script->set_result_real(script->proxy()->target_temperature()); + } else { + return script->proxy()->set_target_temperature(strtod(Targ, NULL)); + } + ) + CVSCRIPT(cv_units, "Get or set the current Colvars unit system\n" "units : string - The current unit system", diff --git a/lib/colvars/colvartypes.cpp b/lib/colvars/colvartypes.cpp index 47117bf2ff..04e007cbc0 100644 --- a/lib/colvars/colvartypes.cpp +++ b/lib/colvars/colvartypes.cpp @@ -125,46 +125,16 @@ std::ostream & operator << (std::ostream &os, colvarmodule::quaternion const &q) std::istream & operator >> (std::istream &is, colvarmodule::quaternion &q) { std::streampos const start_pos = is.tellg(); - - std::string euler(""); - - if ( (is >> euler) && (colvarparse::to_lower_cppstr(euler) == - std::string("euler")) ) { - - // parse the Euler angles - - char sep; - cvm::real phi, theta, psi; - if ( !(is >> sep) || !(sep == '(') || - !(is >> phi) || !(is >> sep) || !(sep == ',') || - !(is >> theta) || !(is >> sep) || !(sep == ',') || - !(is >> psi) || !(is >> sep) || !(sep == ')') ) { - is.clear(); - is.seekg(start_pos, std::ios::beg); - is.setstate(std::ios::failbit); - return is; - } - - q = colvarmodule::quaternion(phi, theta, psi); - - } else { - - // parse the quaternion components - + char sep; + if ( !(is >> sep) || !(sep == '(') || + !(is >> q.q0) || !(is >> sep) || !(sep == ',') || + !(is >> q.q1) || !(is >> sep) || !(sep == ',') || + !(is >> q.q2) || !(is >> sep) || !(sep == ',') || + !(is >> q.q3) || !(is >> sep) || !(sep == ')') ) { + is.clear(); is.seekg(start_pos, std::ios::beg); - char sep; - if ( !(is >> sep) || !(sep == '(') || - !(is >> q.q0) || !(is >> sep) || !(sep == ',') || - !(is >> q.q1) || !(is >> sep) || !(sep == ',') || - !(is >> q.q2) || !(is >> sep) || !(sep == ',') || - !(is >> q.q3) || !(is >> sep) || !(sep == ')') ) { - is.clear(); - is.seekg(start_pos, std::ios::beg); - is.setstate(std::ios::failbit); - return is; - } + is.setstate(std::ios::failbit); } - return is; } @@ -318,15 +288,15 @@ void colvarmodule::rotation::build_correlation_matrix( // build the correlation matrix size_t i; for (i = 0; i < pos1.size(); i++) { - C.xx() += pos1[i].x * pos2[i].x; - C.xy() += pos1[i].x * pos2[i].y; - C.xz() += pos1[i].x * pos2[i].z; - C.yx() += pos1[i].y * pos2[i].x; - C.yy() += pos1[i].y * pos2[i].y; - C.yz() += pos1[i].y * pos2[i].z; - C.zx() += pos1[i].z * pos2[i].x; - C.zy() += pos1[i].z * pos2[i].y; - C.zz() += pos1[i].z * pos2[i].z; + C.xx += pos1[i].x * pos2[i].x; + C.xy += pos1[i].x * pos2[i].y; + C.xz += pos1[i].x * pos2[i].z; + C.yx += pos1[i].y * pos2[i].x; + C.yy += pos1[i].y * pos2[i].y; + C.yz += pos1[i].y * pos2[i].z; + C.zx += pos1[i].z * pos2[i].x; + C.zy += pos1[i].z * pos2[i].y; + C.zz += pos1[i].z * pos2[i].z; } } @@ -335,22 +305,22 @@ void colvarmodule::rotation::compute_overlap_matrix() { // build the "overlap" matrix, whose eigenvectors are stationary // points of the RMSD in the space of rotations - S[0][0] = C.xx() + C.yy() + C.zz(); - S[1][0] = C.yz() - C.zy(); + S[0][0] = C.xx + C.yy + C.zz; + S[1][0] = C.yz - C.zy; S[0][1] = S[1][0]; - S[2][0] = - C.xz() + C.zx() ; + S[2][0] = - C.xz + C.zx ; S[0][2] = S[2][0]; - S[3][0] = C.xy() - C.yx(); + S[3][0] = C.xy - C.yx; S[0][3] = S[3][0]; - S[1][1] = C.xx() - C.yy() - C.zz(); - S[2][1] = C.xy() + C.yx(); + S[1][1] = C.xx - C.yy - C.zz; + S[2][1] = C.xy + C.yx; S[1][2] = S[2][1]; - S[3][1] = C.xz() + C.zx(); + S[3][1] = C.xz + C.zx; S[1][3] = S[3][1]; - S[2][2] = - C.xx() + C.yy() - C.zz(); - S[3][2] = C.yz() + C.zy(); + S[2][2] = - C.xx + C.yy - C.zz; + S[3][2] = C.yz + C.zy; S[2][3] = S[3][2]; - S[3][3] = - C.xx() - C.yy() + C.zz(); + S[3][3] = - C.xx - C.yy + C.zz; } @@ -402,7 +372,6 @@ void colvarmodule::rotation::calc_optimal_rotation( std::vector const &pos1, std::vector const &pos2) { - C.resize(3, 3); C.reset(); build_correlation_matrix(pos1, pos2); diff --git a/lib/colvars/colvartypes.h b/lib/colvars/colvartypes.h index 354c216838..13b6a5bdb3 100644 --- a/lib/colvars/colvartypes.h +++ b/lib/colvars/colvartypes.h @@ -868,107 +868,69 @@ public: /// \brief 2-dimensional array of real numbers with three components /// along each dimension (works with colvarmodule::rvector) -class colvarmodule::rmatrix - : public colvarmodule::matrix2d { -private: +class colvarmodule::rmatrix { public: - /// Return the xx element - inline cvm::real & xx() { return (*this)[0][0]; } - /// Return the xy element - inline cvm::real & xy() { return (*this)[0][1]; } - /// Return the xz element - inline cvm::real & xz() { return (*this)[0][2]; } - /// Return the yx element - inline cvm::real & yx() { return (*this)[1][0]; } - /// Return the yy element - inline cvm::real & yy() { return (*this)[1][1]; } - /// Return the yz element - inline cvm::real & yz() { return (*this)[1][2]; } - /// Return the zx element - inline cvm::real & zx() { return (*this)[2][0]; } - /// Return the zy element - inline cvm::real & zy() { return (*this)[2][1]; } - /// Return the zz element - inline cvm::real & zz() { return (*this)[2][2]; } - - /// Return the xx element - inline cvm::real xx() const { return (*this)[0][0]; } - /// Return the xy element - inline cvm::real xy() const { return (*this)[0][1]; } - /// Return the xz element - inline cvm::real xz() const { return (*this)[0][2]; } - /// Return the yx element - inline cvm::real yx() const { return (*this)[1][0]; } - /// Return the yy element - inline cvm::real yy() const { return (*this)[1][1]; } - /// Return the yz element - inline cvm::real yz() const { return (*this)[1][2]; } - /// Return the zx element - inline cvm::real zx() const { return (*this)[2][0]; } - /// Return the zy element - inline cvm::real zy() const { return (*this)[2][1]; } - /// Return the zz element - inline cvm::real zz() const { return (*this)[2][2]; } + cvm::real xx, xy, xz, yx, yy, yz, zx, zy, zz; /// Default constructor inline rmatrix() - : cvm::matrix2d(3, 3) - {} + { + reset(); + } /// Constructor component by component inline rmatrix(cvm::real xxi, cvm::real xyi, cvm::real xzi, cvm::real yxi, cvm::real yyi, cvm::real yzi, cvm::real zxi, cvm::real zyi, cvm::real zzi) - : cvm::matrix2d(3, 3) { - this->xx() = xxi; - this->xy() = xyi; - this->xz() = xzi; - this->yx() = yxi; - this->yy() = yyi; - this->yz() = yzi; - this->zx() = zxi; - this->zy() = zyi; - this->zz() = zzi; + xx = xxi; + xy = xyi; + xz = xzi; + yx = yxi; + yy = yyi; + yz = yzi; + zx = zxi; + zy = zyi; + zz = zzi; } /// Destructor inline ~rmatrix() {} + inline void reset() + { + xx = xy = xz = yx = yy = yz = zx = zy = zz = 0.0; + } + /// Return the determinant inline cvm::real determinant() const { return - ( xx() * (yy()*zz() - zy()*yz())) - - (yx() * (xy()*zz() - zy()*xz())) - + (zx() * (xy()*yz() - yy()*xz())); + ( xx * (yy*zz - zy*yz)) + - (yx * (xy*zz - zy*xz)) + + (zx * (xy*yz - yy*xz)); } inline cvm::rmatrix transpose() const { - return cvm::rmatrix(this->xx(), this->yx(), this->zx(), - this->xy(), this->yy(), this->zy(), - this->xz(), this->yz(), this->zz()); + return cvm::rmatrix(xx, yx, zx, + xy, yy, zy, + xz, yz, zz); } - friend cvm::rvector operator * (cvm::rmatrix const &m, cvm::rvector const &r); - + inline friend cvm::rvector operator * (cvm::rmatrix const &m, + cvm::rvector const &r) + { + return cvm::rvector(m.xx*r.x + m.xy*r.y + m.xz*r.z, + m.yx*r.x + m.yy*r.y + m.yz*r.z, + m.zx*r.x + m.zy*r.y + m.zz*r.z); + } }; -inline cvm::rvector operator * (cvm::rmatrix const &m, - cvm::rvector const &r) -{ - return cvm::rvector(m.xx()*r.x + m.xy()*r.y + m.xz()*r.z, - m.yx()*r.x + m.yy()*r.y + m.yz()*r.z, - m.zx()*r.x + m.zy()*r.y + m.zz()*r.z); -} - - - /// \brief 1-dimensional vector of real numbers with four components and /// a quaternion algebra @@ -1151,11 +1113,6 @@ public: q0-=h.q0; q1-=h.q1; q2-=h.q2; q3-=h.q3; } - /// Promote a 3-vector to a quaternion - static inline cvm::quaternion promote(cvm::rvector const &v) - { - return cvm::quaternion(0.0, v.x, v.y, v.z); - } /// Return the vector component inline cvm::rvector get_vector() const { @@ -1207,7 +1164,8 @@ public: /// reference frame) inline cvm::rvector rotate(cvm::rvector const &v) const { - return ((*this) * promote(v) * ((*this).conjugate())).get_vector(); + return ( (*this) * cvm::quaternion(0.0, v.x, v.y, v.z) * + this->conjugate() ).get_vector(); } /// \brief Rotate Q2 through this quaternion (put it in the rotated @@ -1223,18 +1181,18 @@ public: { cvm::rmatrix R; - R.xx() = q0*q0 + q1*q1 - q2*q2 - q3*q3; - R.yy() = q0*q0 - q1*q1 + q2*q2 - q3*q3; - R.zz() = q0*q0 - q1*q1 - q2*q2 + q3*q3; + R.xx = q0*q0 + q1*q1 - q2*q2 - q3*q3; + R.yy = q0*q0 - q1*q1 + q2*q2 - q3*q3; + R.zz = q0*q0 - q1*q1 - q2*q2 + q3*q3; - R.xy() = 2.0 * (q1*q2 - q0*q3); - R.xz() = 2.0 * (q0*q2 + q1*q3); + R.xy = 2.0 * (q1*q2 - q0*q3); + R.xz = 2.0 * (q0*q2 + q1*q3); - R.yx() = 2.0 * (q0*q3 + q1*q2); - R.yz() = 2.0 * (q2*q3 - q0*q1); + R.yx = 2.0 * (q0*q3 + q1*q2); + R.yz = 2.0 * (q2*q3 - q0*q1); - R.zx() = 2.0 * (q1*q3 - q0*q2); - R.zy() = 2.0 * (q0*q1 + q2*q3); + R.zx = 2.0 * (q1*q3 - q0*q2); + R.zy = 2.0 * (q0*q1 + q2*q3); return R; } diff --git a/src/COLVARS/colvarproxy_lammps.cpp b/src/COLVARS/colvarproxy_lammps.cpp index eb03c14de7..06a2a23ec0 100644 --- a/src/COLVARS/colvarproxy_lammps.cpp +++ b/src/COLVARS/colvarproxy_lammps.cpp @@ -43,9 +43,10 @@ colvarproxy_lammps::colvarproxy_lammps(LAMMPS_NS::LAMMPS *lmp, first_timestep=true; previous_step=-1; - t_target=temp; do_exit=false; + engine_ready_ = false; + // set input restart name and strip the extension, if present input_prefix_str = std::string(inp_name ? inp_name : ""); if (input_prefix_str.rfind(".colvars.state") != std::string::npos) @@ -87,7 +88,7 @@ colvarproxy_lammps::colvarproxy_lammps(LAMMPS_NS::LAMMPS *lmp, } -void colvarproxy_lammps::init(const char *conf_file) +void colvarproxy_lammps::init() { version_int = get_version_from_string(COLVARPROXY_VERSION); @@ -102,18 +103,13 @@ void colvarproxy_lammps::init(const char *conf_file) my_angstrom = _lmp->force->angstrom; // Front-end unit is the same as back-end - angstrom_value = my_angstrom; + angstrom_value_ = my_angstrom; // my_kcal_mol = _lmp->force->qe2f / 23.060549; // force->qe2f is 1eV expressed in LAMMPS' energy unit (1 if unit is eV, 23 if kcal/mol) - my_boltzmann = _lmp->force->boltz; + boltzmann_ = _lmp->force->boltz; my_timestep = _lmp->update->dt * _lmp->force->femtosecond; - // TODO move one or more of these to setup() if needed - colvars->read_config_file(conf_file); - colvars->setup_input(); - colvars->setup_output(); - if (_lmp->update->ntimestep != 0) { cvm::log("Setting initial step number from LAMMPS: "+ cvm::to_str(_lmp->update->ntimestep)+"\n"); @@ -123,7 +119,7 @@ void colvarproxy_lammps::init(const char *conf_file) if (cvm::debug()) { cvm::log("atoms_ids = "+cvm::to_str(atoms_ids)+"\n"); - cvm::log("atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n"); + cvm::log("atoms_refcount = "+cvm::to_str(atoms_refcount)+"\n"); cvm::log("atoms_positions = "+cvm::to_str(atoms_positions)+"\n"); cvm::log(cvm::line_marker); cvm::log("Info: done initializing the colvars proxy object.\n"); @@ -154,8 +150,12 @@ colvarproxy_lammps::~colvarproxy_lammps() // re-initialize data where needed int colvarproxy_lammps::setup() { + int error_code = colvarproxy::setup(); my_timestep = _lmp->update->dt * _lmp->force->femtosecond; - return colvars->setup(); + error_code |= colvars->update_engine_parameters(); + error_code |= colvars->setup_input(); + error_code |= colvars->setup_output(); + return error_code; } // trigger colvars computation @@ -222,17 +222,19 @@ double colvarproxy_lammps::compute() if (cvm::debug()) { cvm::log("atoms_ids = "+cvm::to_str(atoms_ids)+"\n"); - cvm::log("atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n"); + cvm::log("atoms_refcount = "+cvm::to_str(atoms_refcount)+"\n"); cvm::log("atoms_positions = "+cvm::to_str(atoms_positions)+"\n"); cvm::log("atoms_new_colvar_forces = "+cvm::to_str(atoms_new_colvar_forces)+"\n"); } - // call the collective variable module - colvars->calc(); + // Call the collective variable module + if (colvars->calc() != COLVARS_OK) { + cvm::error("Error in the collective variables module.\n", COLVARS_ERROR); + } if (cvm::debug()) { cvm::log("atoms_ids = "+cvm::to_str(atoms_ids)+"\n"); - cvm::log("atoms_ncopies = "+cvm::to_str(atoms_ncopies)+"\n"); + cvm::log("atoms_refcount = "+cvm::to_str(atoms_refcount)+"\n"); cvm::log("atoms_positions = "+cvm::to_str(atoms_positions)+"\n"); cvm::log("atoms_new_colvar_forces = "+cvm::to_str(atoms_new_colvar_forces)+"\n"); } @@ -384,7 +386,7 @@ int colvarproxy_lammps::init_atom(int atom_number) for (size_t i = 0; i < atoms_ids.size(); i++) { if (atoms_ids[i] == aid) { // this atom id was already recorded - atoms_ncopies[i] += 1; + atoms_refcount[i] += 1; return i; } } diff --git a/src/COLVARS/colvarproxy_lammps.h b/src/COLVARS/colvarproxy_lammps.h index 338f64fa86..0fc9f1ba12 100644 --- a/src/COLVARS/colvarproxy_lammps.h +++ b/src/COLVARS/colvarproxy_lammps.h @@ -33,7 +33,7 @@ class colvarproxy_lammps : public colvarproxy { LAMMPS_NS::RanPark *_random; // state of LAMMPS properties - double t_target, my_timestep, my_boltzmann, my_angstrom; + double my_timestep, my_angstrom; double bias_energy; int previous_step; @@ -50,7 +50,7 @@ class colvarproxy_lammps : public colvarproxy { colvarproxy_lammps(LAMMPS_NS::LAMMPS *lmp, const char *, const char *, const int, const double, MPI_Comm); ~colvarproxy_lammps() override; - void init(const char *); + void init(); int setup() override; // disable default and copy constructor @@ -60,7 +60,7 @@ class colvarproxy_lammps : public colvarproxy { // methods for lammps to move data or trigger actions in the proxy public: - void set_temperature(double t) { t_target = t; }; + bool total_forces_enabled() const override { return total_force_requested; }; bool total_forces_same_step() const override { return true; }; bool want_exit() const { return do_exit; }; @@ -86,10 +86,6 @@ class colvarproxy_lammps : public colvarproxy { // Request to set the units used internally by Colvars int set_unit_system(std::string const &units_in, bool check_only) override; - inline cvm::real backend_angstrom_value() override { return my_angstrom; }; - - inline cvm::real boltzmann() override { return my_boltzmann; }; - inline cvm::real temperature() override { return t_target; }; inline cvm::real dt() override { return my_timestep; @@ -101,8 +97,7 @@ class colvarproxy_lammps : public colvarproxy { void log(std::string const &message) override; void error(std::string const &message) override; - cvm::rvector position_distance(cvm::atom_pos const &pos1, - cvm::atom_pos const &pos2) const override; + cvm::rvector position_distance(cvm::atom_pos const &pos1, cvm::atom_pos const &pos2) const override; cvm::real rand_gaussian(void) override { return _random->gaussian(); }; diff --git a/src/COLVARS/colvarproxy_lammps_version.h b/src/COLVARS/colvarproxy_lammps_version.h index b0f8965fb0..4228740554 100644 --- a/src/COLVARS/colvarproxy_lammps_version.h +++ b/src/COLVARS/colvarproxy_lammps_version.h @@ -1,3 +1,3 @@ #ifndef COLVARPROXY_VERSION -#define COLVARPROXY_VERSION "2022-05-09" +#define COLVARPROXY_VERSION "2023-04-12" #endif diff --git a/src/COLVARS/fix_colvars.cpp b/src/COLVARS/fix_colvars.cpp index 0fd7bc9857..baf0209c61 100644 --- a/src/COLVARS/fix_colvars.cpp +++ b/src/COLVARS/fix_colvars.cpp @@ -443,7 +443,9 @@ void FixColvars::one_time_init() } proxy = new colvarproxy_lammps(lmp,inp_name,out_name,rng_seed,t_target,root2root); - proxy->init(conf_file); + proxy->init(); + proxy->add_config("configfile", conf_file); + proxy->parse_module_config(); num_coords = (proxy->modify_atom_positions()->size()); } @@ -677,16 +679,16 @@ void FixColvars::post_force(int /*vflag*/) error->one(FLERR,"Run aborted on request from colvars module.\n"); if (!tstat_fix) { - proxy->set_temperature(0.0); + proxy->set_target_temperature(0.0); } else { int tmp; // get thermostat target temperature from corresponding fix, // if the fix supports extraction. double *tt = (double *) tstat_fix->extract("t_target", tmp); if (tt) - proxy->set_temperature(*tt); + proxy->set_target_temperature(*tt); else - proxy->set_temperature(0.0); + proxy->set_target_temperature(0.0); } } From 8736f97792ad951e3430bd678d56de2aa3d8e303 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 May 2023 17:35:14 -0400 Subject: [PATCH 211/448] remove dead code --- src/REPLICA/fix_pimd_langevin.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 4d1ca2eb62..3760c453ab 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -462,7 +462,6 @@ void FixPIMDLangevin::setup(int vflag) { int nlocal = atom->nlocal; double **x = atom->x; - double **v = atom->v; imageint *image = atom->image; if (mapflag) { for (int i = 0; i < nlocal; i++) domain->unmap(x[i], image[i]); From 79f3eb6a4d2fc2fa3ad596ede196efecda24ee16 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 May 2023 17:35:22 -0400 Subject: [PATCH 212/448] remove debug code --- src/REPLICA/fix_pimd_langevin.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 3760c453ab..733d38e038 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -644,10 +644,6 @@ void FixPIMDLangevin::end_of_step() compute_p_cv(); compute_tote(); if (pstat_flag) compute_totenthalpy(); - - if (update->ntimestep % 10000 == 0) { - if (universe->me == 0) printf("This is the end of step %lld.\n", update->ntimestep); - } } void FixPIMDLangevin::collect_xc() From 5d66dc6659718d2e16644a7b1c43ae50af134b6d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 May 2023 17:38:16 -0400 Subject: [PATCH 213/448] apply clang-format --- src/REPLICA/fix_pimd_langevin.cpp | 123 ++++++++++++++---------------- 1 file changed, 58 insertions(+), 65 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 733d38e038..67d7cabe02 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -47,7 +47,8 @@ using namespace LAMMPS_NS; using namespace FixConst; -using namespace MathConst; +using MathConst::MY_PI; +using MathConst::THIRD; enum { NMPIMD }; enum { PHYSICAL, NORMAL }; @@ -63,7 +64,7 @@ enum { SINGLE_PROC, MULTI_PROC }; /* ---------------------------------------------------------------------- */ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) + Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) { restart_global = 1; time_integrate = 1; @@ -114,18 +115,18 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : int seed = -1; - for (int i = 0; i < 6; i++) - { + for (int i = 0; i < 6; i++) { p_flag[i] = 0; p_target[i] = 0.0; } for (int i = 3; i < narg - 1; i += 2) { if (strcmp(arg[i], "method") == 0) { - if (strcmp(arg[i + 1], "nmpimd") == 0)method = NMPIMD; - else error->universe_all(FLERR, "Unknown method parameter for fix pimd/langevin"); - } - else if (strcmp(arg[i], "integrator") == 0) { + if (strcmp(arg[i + 1], "nmpimd") == 0) + method = NMPIMD; + else + error->universe_all(FLERR, "Unknown method parameter for fix pimd/langevin"); + } else if (strcmp(arg[i], "integrator") == 0) { if (strcmp(arg[i + 1], "obabo") == 0) integrator = OBABO; else if (strcmp(arg[i + 1], "baoab") == 0) @@ -157,11 +158,11 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : "Unknown ensemble parameter for fix pimd/langevin. Only nve and nvt " "ensembles are supported!"); } else if (strcmp(arg[i], "fmass") == 0) { - fmass = utils::numeric(FLERR, arg[i+1], false, lmp); + fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); if (fmass < 0.0 || fmass > np) error->universe_all(FLERR, "Invalid fmass value for fix pimd/langevin"); } else if (strcmp(arg[i], "sp") == 0) { - sp = utils::numeric(FLERR, arg[i+1], false, lmp); + sp = utils::numeric(FLERR, arg[i + 1], false, lmp); if (sp < 0.0) error->universe_all(FLERR, "Invalid sp value for fix pimd/nvt"); } else if (strcmp(arg[i], "fmmode") == 0) { if (strcmp(arg[i + 1], "physical") == 0) @@ -204,29 +205,29 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : error->universe_all(FLERR, "Unknown barostat parameter for fix pimd/langevin"); } else if (strcmp(arg[i], "iso") == 0) { pstyle = ISO; - Pext = utils::numeric(FLERR, arg[i+1], false, lmp); + Pext = utils::numeric(FLERR, arg[i + 1], false, lmp); p_target[0] = p_target[1] = p_target[2] = Pext; pdim = 3; } else if (strcmp(arg[i], "aniso") == 0) { pstyle = ANISO; p_flag[0] = p_flag[1] = p_flag[2] = 1; - Pext = utils::numeric(FLERR, arg[i+1], false, lmp); + Pext = utils::numeric(FLERR, arg[i + 1], false, lmp); p_target[0] = p_target[1] = p_target[2] = Pext; pdim = 3; } else if (strcmp(arg[i], "x") == 0) { pstyle = ANISO; p_flag[0] = 1; - p_target[0] = utils::numeric(FLERR, arg[i+1], false, lmp); + p_target[0] = utils::numeric(FLERR, arg[i + 1], false, lmp); pdim++; } else if (strcmp(arg[i], "y") == 0) { pstyle = ANISO; p_flag[1] = 1; - p_target[1] = utils::numeric(FLERR, arg[i+1], false, lmp); + p_target[1] = utils::numeric(FLERR, arg[i + 1], false, lmp); pdim++; } else if (strcmp(arg[i], "z") == 0) { pstyle = ANISO; p_flag[2] = 1; - p_target[2] = utils::numeric(FLERR, arg[i+1], false, lmp); + p_target[2] = utils::numeric(FLERR, arg[i + 1], false, lmp); pdim++; } else if (strcmp(arg[i], "taup") == 0) { tau_p = utils::numeric(FLERR, arg[i + 1], false, lmp); @@ -245,12 +246,12 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : global_freq = 1; vector_flag = 1; - if (!pstat_flag) size_vector = 10; + if (!pstat_flag) + size_vector = 10; else if (pstat_flag) { - if (pstyle == ISO){ - size_vector = 15; - } - else if (pstyle == ANISO){ + if (pstyle == ISO) { + size_vector = 15; + } else if (pstyle == ANISO) { size_vector = 17; } } @@ -271,7 +272,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : fixedpoint[0] = 0.5 * (domain->boxlo[0] + domain->boxhi[0]); fixedpoint[1] = 0.5 * (domain->boxlo[1] + domain->boxhi[1]); fixedpoint[2] = 0.5 * (domain->boxlo[2] + domain->boxhi[2]); - if (pstat_flag) { p_hydro = (p_target[0]+p_target[1]+p_target[2])/pdim; } + if (pstat_flag) { p_hydro = (p_target[0] + p_target[1] + p_target[2]) / pdim; } // initialize Marsaglia RNG with processor-unique seed @@ -293,8 +294,10 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : nreplica = universe->nworlds; ireplica = universe->iworld; - if (nreplica == 1) mapflag = 0; - else mapflag = 1; + if (nreplica == 1) + mapflag = 0; + else + mapflag = 1; int *iroots = new int[nreplica]; MPI_Group uworldgroup, rootgroup; @@ -426,7 +429,8 @@ void FixPIMDLangevin::init() fbond = _fbond * force->mvv2e; if ((universe->me == 0) && (universe->uscreen)) - fprintf(universe->uscreen, "fix pimd/langevin -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); + fprintf(universe->uscreen, + "fix pimd/langevin -P/(beta^2 * hbar^2) = %20.7lE (kcal/mol/A^2)\n\n", fbond); if (integrator == OBABO) { dtf = 0.5 * update->dt * force->ftm2v; @@ -724,13 +728,10 @@ void FixPIMDLangevin::qc_step() if (barostat == BZP) { for (int i = 0; i < nlocal; i++) { for (int j = 0; j < 3; j++) { - if (p_flag[j]) - { + if (p_flag[j]) { x[i][j] = expq[j] * x[i][j] + (expq[j] - expp[j]) / 2. / vw[j] * v[i][j]; v[i][j] = expp[j] * v[i][j]; - } - else - { + } else { x[i][j] += dtv * v[i][j]; } } @@ -844,10 +845,9 @@ void FixPIMDLangevin::press_v_step() } else if (pstyle == ANISO) { compute_stress_tensor(); for (int ii = 0; ii < 3; ii++) { - if (p_flag[ii]) - { - vw[ii] += - dtv * (volume * np * (stress_tensor[ii] - p_hydro) / force->nktv2p + Vcoeff / beta_np) / W; + if (p_flag[ii]) { + vw[ii] += dtv * + (volume * np * (stress_tensor[ii] - p_hydro) / force->nktv2p + Vcoeff / beta_np) / W; if (universe->iworld == 0) { double dvw_proc = 0.0, dvw = 0.0; for (int i = 0; i < nlocal; i++) { @@ -875,10 +875,8 @@ void FixPIMDLangevin::press_o_step() MPI_Bcast(&vw[0], 1, MPI_DOUBLE, 0, universe->uworld); } else if (pstyle == ANISO) { if (universe->me == 0) { - for (int ii=0; ii<3; ii++) - { - if (p_flag[ii]) - { + for (int ii = 0; ii < 3; ii++) { + if (p_flag[ii]) { r1 = random->gaussian(); vw[ii] = c1 * vw[ii] + c2 * sqrt(1.0 / W / beta_np) * r1; } @@ -1155,9 +1153,9 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) m++; } MPI_Allgather(&m, 1, MPI_INT, counts, 1, MPI_INT, universe->uworld); - for (i = 0; i < nreplica; i++) { counts[i] *= 3; } + for (i = 0; i < nreplica; i++) counts[i] *= 3; displacements[0] = 0; - for (i = 0; i < nreplica - 1; i++) { displacements[i + 1] = displacements[i] + counts[i]; } + for (i = 0; i < nreplica - 1; i++) displacements[i + 1] = displacements[i] + counts[i]; MPI_Allgatherv(bufsorted[0], 3 * m, MPI_DOUBLE, bufsortedall[0], counts, displacements, MPI_DOUBLE, universe->uworld); } else if (cmode == MULTI_PROC) { @@ -1171,11 +1169,11 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) } MPI_Gather(&m, 1, MPI_INT, counts, 1, MPI_INT, 0, world); displacements[0] = 0; - for (i = 0; i < nprocs - 1; i++) { displacements[i + 1] = displacements[i] + counts[i]; } + for (i = 0; i < nprocs - 1; i++) displacements[i + 1] = displacements[i] + counts[i]; MPI_Gatherv(tagsend, m, MPI_LMP_TAGINT, tagsendall, counts, displacements, MPI_LMP_TAGINT, 0, world); - for (i = 0; i < nprocs; i++) { counts[i] *= 3; } - for (i = 0; i < nprocs - 1; i++) { displacements[i + 1] = displacements[i] + counts[i]; } + for (i = 0; i < nprocs; i++) counts[i] *= 3; + for (i = 0; i < nprocs - 1; i++) displacements[i + 1] = displacements[i] + counts[i]; MPI_Gatherv(bufsend[0], 3 * m, MPI_DOUBLE, bufsendall[0], counts, displacements, MPI_DOUBLE, 0, world); for (int iplan = 0; iplan < sizeplan; iplan++) { @@ -1203,15 +1201,15 @@ void FixPIMDLangevin::inter_replica_comm(double **ptr) /* ---------------------------------------------------------------------- */ -void FixPIMDLangevin::remove_com_motion(){ - if(universe->iworld == 0) - { - double **v = atom->v; - int *mask = atom->mask; +void FixPIMDLangevin::remove_com_motion() +{ + if (universe->iworld == 0) { + double **v = atom->v; + int *mask = atom->mask; int nlocal = atom->nlocal; - if (dynamic) masstotal = group->mass(igroup); + if (dynamic) masstotal = group->mass(igroup); double vcm[3]; - group->vcm(igroup,masstotal,vcm); + group->vcm(igroup, masstotal, vcm); for (int i = 0; i < nlocal; i++) { if (mask[i] & groupbit) { v[i][0] -= vcm[0]; @@ -1372,7 +1370,8 @@ void FixPIMDLangevin::compute_t_vir() void FixPIMDLangevin::compute_p_prim() { double inv_volume = 1.0 / (domain->xprd * domain->yprd * domain->zprd); - p_prim = atom->natoms * np * force->boltz * temp * inv_volume - 1.0 / 1.5 * inv_volume * total_spring_energy; + p_prim = atom->natoms * np * force->boltz * temp * inv_volume - + 1.0 / 1.5 * inv_volume * total_spring_energy; p_prim *= force->nktv2p; } @@ -1415,14 +1414,14 @@ void FixPIMDLangevin::write_restart(FILE *fp) int nsize = size_restart_global(); double *list; - memory->create(list,nsize,"FixPIMDLangevin:list"); + memory->create(list, nsize, "FixPIMDLangevin:list"); pack_restart_data(list); if (comm->me == 0) { int size = nsize * sizeof(double); - fwrite(&size,sizeof(int),1,fp); - fwrite(list,sizeof(double),nsize,fp); + fwrite(&size, sizeof(int), 1, fp); + fwrite(list, sizeof(double), nsize, fp); } memory->destroy(list); @@ -1441,7 +1440,7 @@ int FixPIMDLangevin::size_restart_global() int FixPIMDLangevin::pack_restart_data(double *list) { int n = 0; - for (int i=0; i<6; i++) { list[n++] = vw[i]; } + for (int i = 0; i < 6; i++) list[n++] = vw[i]; return n; } @@ -1451,7 +1450,7 @@ void FixPIMDLangevin::restart(char *buf) { int n = 0; auto list = (double *) buf; - for (int i=0; i<6; i++) { vw[i] = list[n++]; } + for (int i = 0; i < 6; i++) vw[i] = list[n++]; } /* ---------------------------------------------------------------------- */ @@ -1470,7 +1469,7 @@ double FixPIMDLangevin::compute_vector(int n) if (n == 9) return p_cv; if (pstat_flag) { - volume = domain->xprd * domain->yprd * domain->zprd; + volume = domain->xprd * domain->yprd * domain->zprd; if (pstyle == ISO) { if (n == 10) return vw[0]; if (barostat == BZP) { @@ -1478,21 +1477,15 @@ double FixPIMDLangevin::compute_vector(int n) } else if (barostat == MTTK) { if (n == 11) return 1.5 * W * vw[0] * vw[0]; } - if (n == 12) { - return np * Pext * volume / force->nktv2p; - } - if (n == 13) { - return -Vcoeff * np * kBT * log(volume); - } + if (n == 12) { return np * Pext * volume / force->nktv2p; } + if (n == 13) { return -Vcoeff * np * kBT * log(volume); } if (n == 14) return totenthalpy; } else if (pstyle == ANISO) { if (n == 10) return vw[0]; if (n == 11) return vw[1]; if (n == 12) return vw[2]; if (n == 13) return 0.5 * W * (vw[0] * vw[0] + vw[1] * vw[1] + vw[2] * vw[2]); - if (n == 14) { - return np * Pext * volume / force->nktv2p; - } + if (n == 14) { return np * Pext * volume / force->nktv2p; } if (n == 15) { volume = domain->xprd * domain->yprd * domain->zprd; return -Vcoeff * np * kBT * log(volume); From f1aca8b71a44cb4693bbf4f77665f5556322c7b0 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 17 May 2023 16:39:14 -0600 Subject: [PATCH 214/448] formatting tweaks --- src/EXTRA-FIX/fix_ttm_mod.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index 902c0044c9..ca9b3bd2c5 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -659,6 +659,9 @@ el_heat_capacity_thermal_conductivity FixTTMMod::el_properties(double T_e) properties.el_thermal_conductivity = el_th_diff*properties.el_heat_capacity; // thermal conductivity return properties; } + +/* ---------------------------------------------------------------------- */ + double FixTTMMod::el_sp_heat_integral(double T_e) { double T_temp = T_e/1000.0, T_reduced = T_damp*T_temp; @@ -751,6 +754,7 @@ void FixTTMMod::end_of_step() for (int iy = 0; iy < nygrid; iy++) for (int ix = 0; ix < nxgrid; ix++) T_electron_first[iz][iy][ix] = T_electron[iz][iy][ix]; + do { for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) From d206f583c4cd269202611cbd411187ec69e91b09 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 May 2023 21:57:14 -0400 Subject: [PATCH 215/448] whitespace --- src/EXTRA-FIX/fix_ttm_mod.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index ca9b3bd2c5..79af414f0a 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -754,7 +754,7 @@ void FixTTMMod::end_of_step() for (int iy = 0; iy < nygrid; iy++) for (int ix = 0; ix < nxgrid; ix++) T_electron_first[iz][iy][ix] = T_electron[iz][iy][ix]; - + do { for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) From 6585151ce1f7681338df0279c3f63cf6ef32045b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 17 May 2023 22:04:32 -0400 Subject: [PATCH 216/448] reorder loops to compute properties vector --- src/EXTRA-FIX/fix_ttm_mod.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index 79af414f0a..a5dea815ea 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -894,9 +894,9 @@ double FixTTMMod::compute_vector(int n) double dz = domain->zprd/nzgrid; double del_vol = dx*dy*dz; - for (int iz = 0; iz < nzgrid; iz++) + for (int ix = 0; ix < nxgrid; ix++) for (int iy = 0; iy < nygrid; iy++) - for (int ix = 0; ix < nxgrid; ix++) { + for (int iz = 0; iz < nzgrid; iz++) { e_energy += el_sp_heat_integral(T_electron[iz][iy][ix])*del_vol; transfer_energy += net_energy_transfer_all[iz][iy][ix]*update->dt; } From 81a497adcd6d1fa52ac3bf0931bec76a7c8caaf4 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 18 May 2023 21:51:53 +0800 Subject: [PATCH 217/448] add standard version of ilp_water_2dm --- src/INTERLAYER/pair_ilp_graphene_hbn.cpp | 25 +-- src/INTERLAYER/pair_ilp_graphene_hbn.h | 38 +++- src/INTERLAYER/pair_ilp_tmd.cpp | 213 +++++++++++++++++++---- src/INTERLAYER/pair_ilp_tmd.h | 2 +- src/INTERLAYER/pair_ilp_water_2dm.cpp | 80 +++++++++ src/INTERLAYER/pair_ilp_water_2dm.h | 67 +++++++ 6 files changed, 373 insertions(+), 52 deletions(-) create mode 100644 src/INTERLAYER/pair_ilp_water_2dm.cpp create mode 100644 src/INTERLAYER/pair_ilp_water_2dm.h diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index 0ff2811339..956d7ba2be 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org + Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains @@ -47,11 +47,11 @@ using namespace InterLayer; static const char cite_ilp[] = "ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848\n" "@Article{Ouyang2018\n" - " author = {W. Ouyang and D. Mandelli and M. Urbakh and O. Hod},\n" + " author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod},\n" " title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials},\n" " journal = {Nano Letters},\n" " volume = 18,\n" - " pages = 6009,\n" + " pages = {6009}\n" " year = 2018,\n" "}\n\n"; @@ -59,7 +59,10 @@ static const char cite_ilp[] = static std::map variant_map = { {PairILPGrapheneHBN::ILP_GrhBN, "ilp/graphene/hbn"}, {PairILPGrapheneHBN::ILP_TMD, "ilp/tmd"}, - {PairILPGrapheneHBN::SAIP_METAL, "saip/metal"}}; + {PairILPGrapheneHBN::ILP_PHOSPHORUS, "ilp/phosphorus"}, + {PairILPGrapheneHBN::ILP_WATER_2DM, "ilp/water/2dm"}, + {PairILPGrapheneHBN::SAIP_METAL, "saip/metal"}, + {PairILPGrapheneHBN::SAIP_METAL_TMD, "saip/metal/tmd"}}; /* ---------------------------------------------------------------------- */ @@ -313,14 +316,14 @@ void PairILPGrapheneHBN::read_file(char *filename) for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { if (n >= 0) - error->all(FLERR, "{} potential file {} has a duplicate entry for: {} {}", - variant_map[variant], filename, elements[i], elements[j]); + error->all(FLERR, "{} potential file {} has a duplicate entry", variant_map[variant], + filename); n = m; } } if (n < 0) - error->all(FLERR, "{} potential file {} is missing an entry for: {} {}", - variant_map[variant], filename, elements[i], elements[j]); + error->all(FLERR, "{} potential file {} is missing an entry", variant_map[variant], + filename); elem2param[i][j] = n; cutILPsq[i][j] = params[n].rcut * params[n].rcut; } @@ -632,7 +635,7 @@ void PairILPGrapheneHBN::calc_FRep(int eflag, int /* vflag */) void PairILPGrapheneHBN::ILP_neigh() { - int i, j, ii, jj, n, allnum, jnum, itype, jtype; + int i, j, ii, jj, n, inum, jnum, itype, jtype; double xtmp, ytmp, ztmp, delx, dely, delz, rsq; int *ilist, *jlist, *numneigh, **firstneigh; int *neighptr; @@ -649,7 +652,7 @@ void PairILPGrapheneHBN::ILP_neigh() (int **) memory->smalloc(maxlocal * sizeof(int *), "ILPGrapheneHBN:firstneigh"); } - allnum = list->inum + list->gnum; + inum = list->inum; // + list->gnum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; @@ -659,7 +662,7 @@ void PairILPGrapheneHBN::ILP_neigh() ipage->reset(); - for (ii = 0; ii < allnum; ii++) { + for (ii = 0; ii < inum; ii++) { i = ilist[ii]; n = 0; diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.h b/src/INTERLAYER/pair_ilp_graphene_hbn.h index 9987830b1d..6381fb8f35 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.h +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org + Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains @@ -35,11 +35,19 @@ class PairILPGrapheneHBN : public Pair { double init_one(int, int) override; void init_style() override; void calc_FvdW(int, int); + virtual void calc_FRep(int, int); + virtual void ILP_neigh(); + virtual void calc_normal(); + void read_file(char *); + void allocate(); + double single(int, int, int, int, double, double, double, double &) override; static constexpr int NPARAMS_PER_LINE = 13; - enum { ILP_GrhBN, ILP_TMD, SAIP_METAL }; // for telling class variants apart in shared code + // for telling class variants apart in shared code + enum { ILP_GrhBN, ILP_TMD, SAIP_METAL, + ILP_WATER_2DM, SAIP_METAL_TMD, ILP_PHOSPHORUS }; protected: int me; @@ -51,6 +59,7 @@ class PairILPGrapheneHBN : public Pair { int *ILP_numneigh; // # of pair neighbors for each atom int **ILP_firstneigh; // ptr to 1st neighbor of each atom int tap_flag; // flag to turn on/off taper function + double ncf; // for ilp/phosphorus, coefficients for calcualting the normals struct Param { double z0, alpha, epsilon, C, delta, d, sR, reff, C6, S; @@ -76,15 +85,28 @@ class PairILPGrapheneHBN : public Pair { double ***dpvet1; double ***dpvet2; double ***dNave; - - virtual void ILP_neigh(); - virtual void calc_normal(); - virtual void calc_FRep(int, int); - void read_file(char *); - void allocate(); }; } // namespace LAMMPS_NS #endif #endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: All pair coeffs are not set + +All pair coefficients must be set in the data file or by the +pair_coeff command before running a simulation. + +*/ diff --git a/src/INTERLAYER/pair_ilp_tmd.cpp b/src/INTERLAYER/pair_ilp_tmd.cpp index c024e23079..d855b9423d 100644 --- a/src/INTERLAYER/pair_ilp_tmd.cpp +++ b/src/INTERLAYER/pair_ilp_tmd.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org + Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains @@ -22,12 +22,14 @@ #include "atom.h" #include "citeme.h" +#include "comm.h" #include "error.h" #include "force.h" #include "interlayer_taper.h" #include "memory.h" #include "my_page.h" #include "neigh_list.h" +#include "neighbor.h" #include #include @@ -35,22 +37,20 @@ using namespace LAMMPS_NS; using namespace InterLayer; -#define MAXLINE 1024 #define DELTA 4 #define PGDELTA 1 -static const char cite_ilp_tmd[] = - "ilp/tmd potential doi:10.1021/acs.jctc.1c00782\n" - "@Article{Ouyang2021\n" - " author = {W. Ouyang and R. Sofer and X. Gao and J. Hermann and\n" - " A. Tkatchenko and L. Kronik and M. Urbakh and O. Hod},\n" - " title = {Anisotropic Interlayer Force Field for Transition\n" - " Metal Dichalcogenides: The Case of Molybdenum Disulfide},\n" - " journal = {J.~Chem.\\ Theory Comput.},\n" - " volume = 17,\n" - " pages = {7237--7245}\n" - " year = 2021,\n" - "}\n\n"; +static const char cite_ilp_tmd[] = "ilp/tmd potential doi/10.1021/acs.jctc.1c00782\n" + "@Article{Ouyang2021\n" + " author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. " + "Tkatchenko, L. Kronik, M. Urbakh, and O. Hod},\n" + " title = {Anisotropic Interlayer Force Field for Transition " + "Metal Dichalcogenides: The Case of Molybdenum Disulfide},\n" + " journal = {J. Chem. Theory Comput.},\n" + " volume = 17,\n" + " pages = {7237–7245}\n" + " year = 2021,\n" + "}\n\n"; /* ---------------------------------------------------------------------- */ @@ -232,7 +232,7 @@ void PairILPTMD::calc_FRep(int eflag, int /* vflag */) void PairILPTMD::ILP_neigh() { - int i, j, l, ii, jj, ll, n, allnum, jnum, itype, jtype, ltype, imol, jmol, count; + int i, j, l, ii, jj, ll, n, inum, jnum, itype, jtype, ltype, imol, jmol, count; double xtmp, ytmp, ztmp, delx, dely, delz, deljx, deljy, deljz, rsq, rsqlj; int *ilist, *jlist, *numneigh, **firstneigh; int *neighsort; @@ -249,7 +249,7 @@ void PairILPTMD::ILP_neigh() ILP_firstneigh = (int **) memory->smalloc(maxlocal * sizeof(int *), "ILPTMD:firstneigh"); } - allnum = list->inum + list->gnum; + inum = list->inum; //+ list->gnum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; @@ -259,7 +259,7 @@ void PairILPTMD::ILP_neigh() ipage->reset(); - for (ii = 0; ii < allnum; ii++) { + for (ii = 0; ii < inum; ii++) { i = ilist[ii]; //initialize varibles @@ -288,21 +288,21 @@ void PairILPTMD::ILP_neigh() delz = ztmp - x[j][2]; rsq = delx * delx + dely * dely + delz * delz; - // check if the atom i is TMD, i.e., Mo/S/W/Se - if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 || - strcmp(elements[itype], "S") == 0 || strcmp(elements[itype], "Se") == 0 || + // check if the atom i is a TMD atom, i.e., Mo/S/W/Se + if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 || + strcmp(elements[itype], "S") == 0 || strcmp(elements[itype], "Se") == 0 || strcmp(elements[itype], "Te") == 0) { if (rsq != 0 && rsq < cutILPsq[itype][jtype] && imol == jmol && type[i] == type[j]) { neighptr[n++] = j; } - } else { // atom i is C, B, N or H. + } else { // atom i can be P, C, B, N or H. if (rsq != 0 && rsq < cutILPsq[itype][jtype] && imol == jmol) { neighptr[n++] = j; } } } // loop over jj // if atom i is Mo/W/S/Se/Te, then sorting the orders of neighbors - if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 || - strcmp(elements[itype], "S") == 0 || strcmp(elements[itype], "Se") == 0 || + if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 || + strcmp(elements[itype], "S") == 0 || strcmp(elements[itype], "Se") == 0 || strcmp(elements[itype], "Te") == 0) { // initialize neighsort for (ll = 0; ll < n; ll++) { @@ -367,11 +367,11 @@ void PairILPTMD::ILP_neigh() ll++; } } // end of sorting the order of neighbors - } else { // for B/N/C/H atoms + } else { // for P/B/N/C/H atoms if (n > 3) error->one( FLERR, - "There are too many neighbors for B/N/C/H atoms, please check your configuration"); + "There are too many neighbors for P/B/N/C/H atoms, please check your configuration"); for (ll = 0; ll < n; ll++) { neighsort[ll] = neighptr[ll]; } } @@ -390,12 +390,14 @@ void PairILPTMD::calc_normal() { int i, j, ii, jj, inum, jnum; int cont, id, ip, m, k, itype; - double nn, xtp, ytp, ztp, delx, dely, delz, nn2; int *ilist, *jlist; + int iH1,iH2,jH1,jH2; double Nave[3], dni[3], dpvdri[3][3]; + double nn, xtp, ytp, ztp, delx, dely, delz, nn2; double **x = atom->x; int *type = atom->type; + tagint *tag = atom->tag; memory->destroy(dnn); memory->destroy(vect); @@ -479,9 +481,63 @@ void PairILPTMD::calc_normal() for (m = 0; m < Nnei; m++) { dnormal[i][id][m][ip] = 0.0; } } } + // for hydrogen in water molecule + if (strcmp(elements[itype], "Hw") == 0) { + if(cont == 0) { + jH1 = atom->map(tag[i] - 1); + jH2 = atom->map(tag[i] - 2); + iH1 = map[type[jH1]]; + iH2 = map[type[jH2]]; + if (strcmp(elements[iH1], "Ow") == 0 ) { + vect[0][0] = x[jH1][0] - xtp; + vect[0][1] = x[jH1][1] - ytp; + vect[0][2] = x[jH1][2] - ztp; + } else if (strcmp(elements[iH2], "Ow") == 0 ) { + vect[0][0] = x[jH2][0] - xtp; + vect[0][1] = x[jH2][1] - ytp; + vect[0][2] = x[jH2][2] - ztp; + } else { + fprintf(screen, "jH1 jH2 = %d %d\n", jH1,jH2); + fprintf(screen, "Atom Type = %d %d\n", type[jH1],type[jH2]); + fprintf(screen, "For atom i = %d %d\n", tag[i],type[i]); + error->one(FLERR, "The order of atoms in water molecule should be O H H !"); + } + } + Nave[0] = vect[0][0]; + Nave[1] = vect[0][1]; + Nave[2] = vect[0][2]; + // the magnitude of the normal vector + nn2 = Nave[0] * Nave[0] + Nave[1] * Nave[1] + Nave[2] * Nave[2]; + nn = sqrt(nn2); + if (nn == 0) error->one(FLERR, "The magnitude of the normal vector is zero"); + // the unit normal vector + normal[i][0] = Nave[0] / nn; + normal[i][1] = Nave[1] / nn; + normal[i][2] = Nave[2] / nn; + + // Calculte dNave/dri, defined as dpvdri + for (id = 0; id < 3; id++) { + for (ip = 0; ip < 3; ip++) { + if (ip == id) { dpvdri[id][ip] = -1.0;} + else {dpvdri[id][ip] = 0.0;} + } + } + + // derivatives of nn, dnn:3x1 vector + dni[0] = (Nave[0] * dpvdri[0][0] + Nave[1] * dpvdri[1][0] + Nave[2] * dpvdri[2][0]) / nn; + dni[1] = (Nave[0] * dpvdri[0][1] + Nave[1] * dpvdri[1][1] + Nave[2] * dpvdri[2][1]) / nn; + dni[2] = (Nave[0] * dpvdri[0][2] + Nave[1] * dpvdri[1][2] + Nave[2] * dpvdri[2][2]) / nn; + // derivatives of unit vector ni respect to ri, the result is 3x3 matrix + for (id = 0; id < 3; id++) { + for (ip = 0; ip < 3; ip++) { + dnormdri[i][id][ip] = dpvdri[id][ip] / nn - Nave[id] * dni[ip] / nn2; + dnormal[i][id][0][ip] = -dnormdri[i][id][ip]; + } + } + } } //############################ For the edge atoms of TMD ################################ - else if (cont < Nnei) { + else if (cont > 1 && cont < Nnei) { if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 || strcmp(elements[itype], "S") == 0 || strcmp(elements[itype], "Se") == 0) { // derivatives of Ni[l] respect to the cont neighbors @@ -557,8 +613,7 @@ void PairILPTMD::calc_normal() for (m = 0; m < cont; m++) { for (id = 0; id < 3; id++) { dnn[m][id] = (Nave[0] * dNave[0][m][id] + Nave[1] * dNave[1][m][id] + - Nave[2] * dNave[2][m][id]) / - nn; + Nave[2] * dNave[2][m][id]) / nn; } } // dnormal[i][id][m][ip]: the derivative of normal[i][id] respect to r[m][ip], id,ip=0,1,2. @@ -589,12 +644,107 @@ void PairILPTMD::calc_normal() } } } // for TMD + //############################ For Oxygen in the water molecule ####################### + else if (strcmp(elements[itype], "Ow") == 0) { + if(cont == 0) { + jH1 = atom->map(tag[i] + 1); + jH2 = atom->map(tag[i] + 2); + iH1 = map[type[jH1]]; + iH2 = map[type[jH2]]; + if (strcmp(elements[iH1], "Hw") == 0 && strcmp(elements[iH2], "Hw") == 0) { + vect[0][0] = x[jH1][0] - xtp; + vect[0][1] = x[jH1][1] - ytp; + vect[0][2] = x[jH1][2] - ztp; + + vect[1][0] = x[jH2][0] - xtp; + vect[1][1] = x[jH2][1] - ytp; + vect[1][2] = x[jH2][2] - ztp; + + cont = 2; + } else { + fprintf(screen, "jH1 jH2 = %d %d\n", jH1,jH2); + fprintf(screen, "Atom Type = %d %d\n", type[jH1],type[jH2]); + fprintf(screen, "ID and type of atom i = %d %d\n", tag[i],type[i]); + error->one(FLERR, "The order of atoms in water molecule should be O H H !"); + } + } + if (cont == 2) { + Nave[0] = (vect[0][0] + vect[1][0])/cont; + Nave[1] = (vect[0][1] + vect[1][1])/cont; + Nave[2] = (vect[0][2] + vect[1][2])/cont; + // the magnitude of the normal vector + nn2 = Nave[0] * Nave[0] + Nave[1] * Nave[1] + Nave[2] * Nave[2]; + nn = sqrt(nn2); + if (nn == 0) error->one(FLERR, "The magnitude of the normal vector is zero"); + // the unit normal vector + normal[i][0] = Nave[0] / nn; + normal[i][1] = Nave[1] / nn; + normal[i][2] = Nave[2] / nn; + + // derivatives of non-normalized normal vector, dNave:3xcontx3 array + // dNave[id][m][ip]: the derivatve of the id component of Nave + // respect to the ip component of atom m + for (id = 0; id < 3; id++) { + for (ip = 0; ip < 3; ip++) { + for (m = 0; m < cont; m++) { + if (ip == id) { dNave[id][m][ip] = 0.5;} + else {dNave[id][m][ip] = 0.0;} + } + } + } + // derivatives of nn, dnn:contx3 vector + // dnn[m][id]: the derivative of nn respect to r[m][id], m=0,...Nnei-1; id=0,1,2 + // r[m][id]: the id's component of atom m + for (m = 0; m < cont; m++) { + for (id = 0; id < 3; id++) { + dnn[m][id] = (Nave[0] * dNave[0][m][id] + Nave[1] * dNave[1][m][id] + + Nave[2] * dNave[2][m][id]) / nn; + } + } + // dnormal[i][id][m][ip]: the derivative of normal[i][id] respect to r[m][ip], id,ip=0,1,2. + // for atom m, which is a neighbor atom of atom i, m = 0,...,Nnei-1 + for (m = 0; m < cont; m++) { + for (id = 0; id < 3; id++) { + for (ip = 0; ip < 3; ip++) { + dnormal[i][id][m][ip] = dNave[id][m][ip] / nn - Nave[id] * dnn[m][ip] / nn2; + } + } + } + // Calculte dNave/dri, defined as dpvdri + for (id = 0; id < 3; id++) { + for (ip = 0; ip < 3; ip++) { + dpvdri[id][ip] = 0.0; + for (k = 0; k < cont; k++) { dpvdri[id][ip] -= dNave[id][k][ip]; } + } + } + + // derivatives of nn, dnn:3x1 vector + dni[0] = (Nave[0] * dpvdri[0][0] + Nave[1] * dpvdri[1][0] + Nave[2] * dpvdri[2][0]) / nn; + dni[1] = (Nave[0] * dpvdri[0][1] + Nave[1] * dpvdri[1][1] + Nave[2] * dpvdri[2][1]) / nn; + dni[2] = (Nave[0] * dpvdri[0][2] + Nave[1] * dpvdri[1][2] + Nave[2] * dpvdri[2][2]) / nn; + // derivatives of unit vector ni respect to ri, the result is 3x3 matrix + for (id = 0; id < 3; id++) { + for (ip = 0; ip < 3; ip++) { + dnormdri[i][id][ip] = dpvdri[id][ip] / nn - Nave[id] * dni[ip] / nn2; + } + } + // printf("%4d:\t%e %e %e\n\t%e %e %e\n\t%e %e %e\n", + // i, dnormdri[i][0][0], dnormdri[i][0][1], dnormdri[i][0][2], + // dnormdri[i][1][0],dnormdri[i][1][1],dnormdri[i][1][2], + // dnormdri[i][2][0],dnormdri[i][2][1],dnormdri[i][2][2]); + // exit(0); + } + else if (cont >= 3) { + error->one(FLERR, + "There are too many neighbors for calculating normals of water molecules"); + } + } //############################ For the edge & bulk atoms of GrhBN ################################ else { if (cont == 2) { for (ip = 0; ip < 3; ip++) { pvet[0][ip] = vect[0][modulo(ip + 1, 3)] * vect[1][modulo(ip + 2, 3)] - - vect[0][modulo(ip + 2, 3)] * vect[1][modulo(ip + 1, 3)]; + vect[0][modulo(ip + 2, 3)] * vect[1][modulo(ip + 1, 3)]; } // dpvet1[k][l][ip]: the derivatve of the k (=0,...cont-1)th Nik respect to the ip component of atom l // derivatives respect to atom l @@ -657,8 +807,7 @@ void PairILPTMD::calc_normal() for (m = 0; m < cont; m++) { for (id = 0; id < 3; id++) { dnn[m][id] = (Nave[0] * dNave[0][m][id] + Nave[1] * dNave[1][m][id] + - Nave[2] * dNave[2][m][id]) / - nn; + Nave[2] * dNave[2][m][id]) / nn; } } // dnormal[i][id][m][ip]: the derivative of normal[i][id] respect to r[m][ip], id,ip=0,1,2. diff --git a/src/INTERLAYER/pair_ilp_tmd.h b/src/INTERLAYER/pair_ilp_tmd.h index 8381c2e830..8d5446d49c 100644 --- a/src/INTERLAYER/pair_ilp_tmd.h +++ b/src/INTERLAYER/pair_ilp_tmd.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org + Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains diff --git a/src/INTERLAYER/pair_ilp_water_2dm.cpp b/src/INTERLAYER/pair_ilp_water_2dm.cpp new file mode 100644 index 0000000000..58e56894f5 --- /dev/null +++ b/src/INTERLAYER/pair_ilp_water_2dm.cpp @@ -0,0 +1,80 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Wengen Ouyang (Wuhan University) + e-mail: w.g.ouyang at gmail dot com + + This is a full version of the potential described in + [Feng and Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023).] +------------------------------------------------------------------------- */ + +#include "pair_ilp_water_2dm.h" + +#include "atom.h" +#include "citeme.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "interlayer_taper.h" +#include "memory.h" +#include "my_page.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace InterLayer; + +#define MAXLINE 1024 +#define DELTA 4 +#define PGDELTA 1 + +static const char cite_ilp_water[] = "ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464\n" + "@Article{Feng2023\n" + " author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang},\n" + " title = {Registry-Dependent Potential for Interfaces of Water with Graphene},\n" + " journal = {J. Phys. Chem. C},\n" + " volume = 127,\n" + " pages = {8704-8713}\n" + " year = 2023,\n" + "}\n\n"; + +/* ---------------------------------------------------------------------- */ + +PairILPWATER2DM::PairILPWATER2DM(LAMMPS *lmp) : PairILPGrapheneHBN(lmp), PairILPTMD(lmp) +{ + variant = ILP_WATER_2DM; + single_enable = 0; + + // for TMD, each atom have six neighbors + Nnei = 6; + + if (lmp->citeme) lmp->citeme->add(cite_ilp_water); +} + +/* ---------------------------------------------------------------------- + global settings +------------------------------------------------------------------------- */ + +void PairILPWATER2DM::settings(int narg, char **arg) +{ + if (narg < 1 || narg > 2) error->all(FLERR, "Illegal pair_style command"); + if (!utils::strmatch(force->pair_style, "^hybrid/overlay")) + error->all(FLERR, "Pair style ilp/water/2dm must be used as sub-style with hybrid/overlay"); + + cut_global = utils::numeric(FLERR, arg[0], false, lmp); + if (narg == 2) tap_flag = utils::numeric(FLERR, arg[1], false, lmp); +} diff --git a/src/INTERLAYER/pair_ilp_water_2dm.h b/src/INTERLAYER/pair_ilp_water_2dm.h new file mode 100644 index 0000000000..c35d757ea0 --- /dev/null +++ b/src/INTERLAYER/pair_ilp_water_2dm.h @@ -0,0 +1,67 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(ilp/water/2dm,PairILPWATER2DM); +// clang-format on +#else + +#ifndef LMP_PAIR_ILP_WATER_2DM_H +#define LMP_PAIR_ILP_WATER_2DM_H + +#include "pair_ilp_tmd.h" + +namespace LAMMPS_NS { + +class PairILPWATER2DM : virtual public PairILPTMD { + public: + PairILPWATER2DM(class LAMMPS *); + + protected: + void settings(int, char **) override; + + /**************************************************************/ + /* modulo operation with cycling around range */ + + inline int modulo(int k, int range) + { + if (k < 0) k += range; + return k % range; + } + /**************************************************************/ +}; + +} // namespace LAMMPS_NS + +#endif +#endif + +/* ERROR/WARNING messages: + +E: Illegal ... command + +Self-explanatory. Check the input script syntax and compare to the +documentation for the command. You can use -echo screen as a +command-line option when running LAMMPS to see the offending line. + +E: Incorrect args for pair coefficients + +Self-explanatory. Check the input script or data file. + +E: All pair coeffs are not set + +All pair coefficients must be set in the data file or by the +pair_coeff command before running a simulation. + +*/ From cc30c4478dcfe6c73d908398437cc58909d1be5c Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 18 May 2023 21:58:40 +0800 Subject: [PATCH 218/448] add optmized verion of ilp_water_2dm --- src/OPT/pair_ilp_graphene_hbn_opt.cpp | 99 +++++++++++++++++++++++---- src/OPT/pair_ilp_graphene_hbn_opt.h | 12 +++- src/OPT/pair_ilp_water_2dm_opt.cpp | 73 ++++++++++++++++++++ src/OPT/pair_ilp_water_2dm_opt.h | 39 +++++++++++ 4 files changed, 207 insertions(+), 16 deletions(-) create mode 100644 src/OPT/pair_ilp_water_2dm_opt.cpp create mode 100644 src/OPT/pair_ilp_water_2dm_opt.h diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.cpp b/src/OPT/pair_ilp_graphene_hbn_opt.cpp index 586c44be08..63822ad4c6 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.cpp +++ b/src/OPT/pair_ilp_graphene_hbn_opt.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org + Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains @@ -23,24 +23,27 @@ #include "atom.h" #include "citeme.h" +#include "comm.h" #include "error.h" #include "force.h" #include "interlayer_taper.h" #include "memory.h" #include "neigh_list.h" +#include "neigh_request.h" #include "neighbor.h" +#include "pointers.h" #include -#include +#include using namespace LAMMPS_NS; using namespace InterLayer; static const char cite_ilp_cur[] = - "ilp/graphene/hbn/opt potential: doi:10.1145/3458817.3476137\n" + "ilp/graphene/hbn/opt potential doi:10.1145/3458817.3476137\n" "@inproceedings{gao2021lmff\n" - " author = {Gao, Ping and Duan, Xiaohui and others},\n" - " title = {{LMFF}: Efficient and Scalable Layered Materials Force Field on Heterogeneous " + " author = {Gao, Ping and Duan, Xiaohui and Others},\n" + " title = {LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous " "Many-Core Processors},\n" " year = {2021},\n" " isbn = {9781450384421},\n" @@ -50,14 +53,12 @@ static const char cite_ilp_cur[] = " doi = {10.1145/3458817.3476137},\n" " booktitle = {Proceedings of the International Conference for High Performance Computing, " "Networking, Storage and Analysis},\n" - " pages = {42},\n" + " articleno = {42},\n" " numpages = {14},\n" - " location = {St.~Louis, Missouri},\n" + " location = {St. Louis, Missouri},\n" " series = {SC'21},\n" "}\n\n"; -static bool check_vdw(tagint itag, tagint jtag, double *xi, double *xj); - /* ---------------------------------------------------------------------- */ PairILPGrapheneHBNOpt::PairILPGrapheneHBNOpt(LAMMPS *lmp) : @@ -168,6 +169,36 @@ void PairILPGrapheneHBNOpt::compute(int eflag, int vflag) } } } + } else if (variant == ILP_WATER_2DM) { + if (eflag_global || eflag_atom) { + if (vflag_either) { + if (tap_flag) { + eval<6, 1, 1, 1, ILP_WATER_2DM>(); + } else { + eval<6, 1, 1, 0, ILP_WATER_2DM>(); + } + } else { + if (tap_flag) { + eval<6, 1, 0, 1, ILP_WATER_2DM>(); + } else { + eval<6, 1, 0, 0, ILP_WATER_2DM>(); + } + } + } else { + if (vflag_either) { + if (tap_flag) { + eval<6, 0, 1, 1, ILP_WATER_2DM>(); + } else { + eval<6, 0, 1, 0, ILP_WATER_2DM>(); + } + } else { + if (tap_flag) { + eval<6, 0, 0, 1, ILP_WATER_2DM>(); + } else { + eval<6, 0, 0, 0, ILP_WATER_2DM>(); + } + } + } } else if (variant == SAIP_METAL) { if (eflag_global || eflag_atom) { if (vflag_either) { @@ -255,7 +286,7 @@ void PairILPGrapheneHBNOpt::eval() rsq = delx * delx + dely * dely + delz * delz; if (rsq != 0 && rsq < cutILPsq[itype_map][jtype]) { - if (VARIANT == ILP_TMD && special_type[itype] && itype != type[j]) continue; + if ((VARIANT == ILP_TMD || VARIANT == ILP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue; if (ILP_nneigh >= MAX_NNEIGH) { error->one(FLERR, "There are too many neighbors for calculating normals"); } @@ -269,7 +300,8 @@ void PairILPGrapheneHBNOpt::eval() dproddni[2] = 0.0; double norm[3], dnormdxi[3][3], dnormdxk[MAX_NNEIGH][3][3]; - calc_normal(i, ILP_neigh, ILP_nneigh, norm, dnormdxi, dnormdxk); + + calc_normal(i, itype, ILP_neigh, ILP_nneigh, norm, dnormdxi, dnormdxk); for (jj = 0; jj < jnum_inter; jj++) { j = jlist_inter[jj]; @@ -298,7 +330,7 @@ void PairILPGrapheneHBNOpt::eval() Tap = 1.0; dTap = 0.0; } - if (VARIANT != SAIP_METAL || !special_type[itype]) { + if (VARIANT != SAIP_METAL || special_type[itype] != SAIP_BNCH) { // Calculate the transverse distance prodnorm1 = norm[0] * delx + norm[1] * dely + norm[2] * delz; rhosq1 = rsq - prodnorm1 * prodnorm1; // rho_ij @@ -310,7 +342,7 @@ void PairILPGrapheneHBNOpt::eval() frho1 = exp1 * p.C; Erep = 0.5 * p.epsilon + frho1; - if (VARIANT == SAIP_METAL && special_type[jtype]) { Erep += 0.5 * p.epsilon + p.C; } + if (VARIANT == SAIP_METAL && special_type[jtype] == SAIP_BNCH) { Erep += 0.5 * p.epsilon + p.C; } Vilp = exp0 * Erep; // derivatives @@ -428,6 +460,19 @@ inline void deriv_normal(double dndr[3][3], double *del, double *n, double rnnor dndr[1][2] = (del[1] * n[0] * n[1] + del[0] * (n[0] * n[0] + n[2] * n[2])) * rnnorm; dndr[2][2] = (del[1] * n[0] * n[2] - del[0] * n[1] * n[2]) * rnnorm; } +inline void deriv_hat(double dnhatdn[3][3], double *n, double rnnorm, double factor){ + double cfactor = rnnorm * factor; + dnhatdn[0][0] = (n[1]*n[1]+n[2]*n[2])*cfactor; + dnhatdn[1][0] = -n[1]*n[0]*cfactor; + dnhatdn[2][0] = -n[2]*n[0]*cfactor; + dnhatdn[0][1] = -n[0]*n[1]*cfactor; + dnhatdn[1][1] = (n[0]*n[0]+n[2]*n[2])*cfactor; + dnhatdn[2][1] = -n[2]*n[1]*cfactor; + dnhatdn[0][2] = -n[0]*n[2]*cfactor; + dnhatdn[1][2] = -n[1]*n[2]*cfactor; + dnhatdn[2][2] = (n[0]*n[0]+n[1]*n[1])*cfactor; + +} inline double normalize_factor(double *n) { double nnorm = sqrt(n[0] * n[0] + n[1] * n[1] + n[2] * n[2]); @@ -441,7 +486,7 @@ inline double normalize_factor(double *n) Yet another normal calculation method for simpiler code. */ template -void PairILPGrapheneHBNOpt::calc_normal(int i, int *ILP_neigh, int nneigh, double *n, +void PairILPGrapheneHBNOpt::calc_normal(int i, int itype, int *ILP_neigh, int nneigh, double *n, double (*dnormdri)[3], double (*dnormdrk)[3][3]) { double **x = atom->x; @@ -475,6 +520,32 @@ void PairILPGrapheneHBNOpt::calc_normal(int i, int *ILP_neigh, int nneigh, doubl vet[jj][2] = x[j][2] - x[i][2]; } + //specialize for ILP_WATER_2DM for hydrogen has special normal vector rule + if (variant == ILP_WATER_2DM && special_type[itype] == WATER) { + if (nneigh == 1){ + n[0] = vet[0][0]; + n[1] = vet[0][1]; + n[2] = vet[0][2]; + + double rnnorm = normalize_factor(n); + + deriv_hat(dnormdri, n, rnnorm, -1.0); + deriv_hat(dnormdrk[0], n, rnnorm, 1.0); + + } else if (nneigh == 2){ + n[0] = (vet[0][0] + vet[1][0])*0.5; + n[1] = (vet[0][1] + vet[1][1])*0.5; + n[2] = (vet[0][2] + vet[1][2])*0.5; + double rnnorm = normalize_factor(n); + + deriv_hat(dnormdri, n, rnnorm, -1.0); + deriv_hat(dnormdrk[0], n, rnnorm, 0.5); + deriv_hat(dnormdrk[1], n, rnnorm, 0.5); + } else { + error->one(FLERR, "malformed water"); + } + return; + } if (nneigh <= 1) { n[0] = 0.0; n[1] = 0.0; diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.h b/src/OPT/pair_ilp_graphene_hbn_opt.h index 0721014e00..bc22ab22b0 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.h +++ b/src/OPT/pair_ilp_graphene_hbn_opt.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - LAMMPS development team: developers@lammps.org + Steve Plimpton, sjplimp@sandia.gov Copyright (2003) Sandia Corporation. Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains @@ -35,7 +35,7 @@ class PairILPGrapheneHBNOpt : virtual public PairILPGrapheneHBN { protected: void update_internal_list(); template - void calc_normal(int i, int *ILP_neigh, int nneigh, double *normal, double (*dnormdri)[3], + void calc_normal(int i, int itype, int *ILP_neigh, int nneigh, double *normal, double (*dnormdri)[3], double (*dnormdrk)[3][3]); template void eval(); @@ -44,6 +44,14 @@ class PairILPGrapheneHBNOpt : virtual public PairILPGrapheneHBN { int *special_type; int *num_intra, *num_inter, *num_vdw; int inum_max, jnum_max; + + enum special_type_const { + NOT_SPECIAL = 0, + TMD_METAL, + SAIP_BNCH, + WATER, + }; + }; } // namespace LAMMPS_NS diff --git a/src/OPT/pair_ilp_water_2dm_opt.cpp b/src/OPT/pair_ilp_water_2dm_opt.cpp new file mode 100644 index 0000000000..6cdac00ed9 --- /dev/null +++ b/src/OPT/pair_ilp_water_2dm_opt.cpp @@ -0,0 +1,73 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + This is an optimized version of ilp/water/2dm based on the contribution of: + author: Wengen Ouyang (Wuhan University) + e-mail: w.g.ouyang at gmail dot com + + Optimizations are done by: + author1: Xiaohui Duan (National Supercomputing Center in Wuxi, China) + e-mail: sunrise_duan at 126 dot com + + author2: Ping Gao (National Supercomputing Center in Wuxi, China) + e-mail: qdgaoping at gmail dot com + + Optimizations are described in: + Gao, Ping and Duan, Xiaohui, et al: + LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors + DOI: 10.1145/3458817.3476137 + + Potential is described by: + [Feng and Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023).] +*/ +#include "pair_ilp_water_2dm_opt.h" + +#include "atom.h" +#include "citeme.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "interlayer_taper.h" +#include "memory.h" +#include "neigh_list.h" +#include "neigh_request.h" +#include "neighbor.h" + +#include +#include + +using namespace LAMMPS_NS; +using namespace InterLayer; + +PairILPWATER2DMOpt::PairILPWATER2DMOpt(LAMMPS *lmp) : + PairILPGrapheneHBN(lmp), PairILPTMD(lmp), PairILPWATER2DM(lmp), PairILPGrapheneHBNOpt(lmp) +{ +} + +void PairILPWATER2DMOpt::coeff(int narg, char **args) +{ + PairILPTMD::coeff(narg, args); + memory->create(special_type, atom->ntypes + 1, "PairILPWATER2DMOpt:check_sublayer"); + for (int i = 1; i <= atom->ntypes; i++) { + int itype = map[i]; + if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 || + strcmp(elements[itype], "S") == 0 || strcmp(elements[itype], "Se") == 0 || + strcmp(elements[itype], "Te") == 0) { + special_type[i] = TMD_METAL; + } else if (strcmp(elements[itype], "Hw") == 0 || strcmp(elements[itype], "Ow") == 0) { + special_type[i] = WATER; + } else { + special_type[i] = NOT_SPECIAL; + } + } +} diff --git a/src/OPT/pair_ilp_water_2dm_opt.h b/src/OPT/pair_ilp_water_2dm_opt.h new file mode 100644 index 0000000000..25905643af --- /dev/null +++ b/src/OPT/pair_ilp_water_2dm_opt.h @@ -0,0 +1,39 @@ + /* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(ilp/water/2dm/opt,PairILPWATER2DMOpt); +// clang-format on +#else + +#ifndef LMP_PAIR_ILP_WATER_2DM_OPT_H +#define LMP_PAIR_ILP_WATER_2DM_OPT_H + +#include "pair_ilp_graphene_hbn_opt.h" +#include "pair_ilp_water_2dm.h" + +namespace LAMMPS_NS { + +class PairILPWATER2DMOpt : public PairILPWATER2DM, public PairILPGrapheneHBNOpt { + public: + PairILPWATER2DMOpt(class LAMMPS *); + void coeff(int narg, char **args) override; + + protected: +}; + +} // namespace LAMMPS_NS +#endif +#endif + From af04ecc53217f52e32bc51f626cfdabc067792ec Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 18 May 2023 21:59:07 +0800 Subject: [PATCH 219/448] add potential file --- potentials/COH.ILP | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100755 potentials/COH.ILP diff --git a/potentials/COH.ILP b/potentials/COH.ILP new file mode 100755 index 0000000000..bd815b5c00 --- /dev/null +++ b/potentials/COH.ILP @@ -0,0 +1,28 @@ +# DATE: 2023-05-18 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127, 8704 (2023). +# Interlayer Potential (ILP) for water/graphene heterojunctions +# The parameters below are fitted against the PBE + MBD-NL DFT reference data from 2.5 A to 15 A. +# +# ----------------- Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ +# beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut +# For graphene and hydrocarbons +C C 3.205843 7.511126 1.235334 1.528338E-5 37.530428 15.499947 0.7954443 3.681440 25.714535E3 1.0 2.0 +H H 3.974540 6.53799 1.080633 0.6700556 0.8333833 15.022371 0.7490632 2.767223 1.6159581E3 1.0 1.2 +C H 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 +H C 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 + +# For water-graphene +C Ow 5.45369612 6.18172364 1.25025450 3.34909245 0.68780636 9.05706482 1.23249498 2.77577173 100226.55503127 1.0 2.0 +C Hw 2.55380862 9.68664390 1.96489198 41.77617053 -16.30012807 9.01568534 0.74415463 2.41545571 7409.12856378 1.0 2.0 +Ow C 5.45369612 6.18172364 1.25025450 3.34909245 0.68780636 9.05706482 1.23249498 2.77577173 100226.55503127 1.0 1.2 +Hw C 2.55380862 9.68664390 1.96489198 41.77617053 -16.30012807 9.01568534 0.74415463 2.41545571 7409.12856378 1.0 1.2 + +# # The ILPs for other systems are set to zero +H Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +H Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Ow H 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Hw H 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 + +Ow Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Hw Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Ow Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Hw Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 From 3d35d68a4bd9fc432e40239c5d0ad6c8169e75d1 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 18 May 2023 22:00:03 +0800 Subject: [PATCH 220/448] add doc file --- doc/src/pair_ilp_graphene_hbn.rst | 20 +-- doc/src/pair_ilp_tmd.rst | 4 +- doc/src/pair_ilp_water_2dm.rst | 166 ++++++++++++++++++++++++ doc/src/pair_kolmogorov_crespi_full.rst | 2 +- doc/src/pair_saip_metal.rst | 4 +- 5 files changed, 181 insertions(+), 15 deletions(-) create mode 100644 doc/src/pair_ilp_water_2dm.rst diff --git a/doc/src/pair_ilp_graphene_hbn.rst b/doc/src/pair_ilp_graphene_hbn.rst index de088f2926..36e971ef62 100644 --- a/doc/src/pair_ilp_graphene_hbn.rst +++ b/doc/src/pair_ilp_graphene_hbn.rst @@ -155,8 +155,8 @@ interactions. The BNCH.ILP potential file provided with LAMMPS (see the potentials directory) are parameterized for *metal* units. You can use this -potential with any LAMMPS units, but you would need to create your -BNCH.ILP potential file with coefficients listed in the appropriate +potential with any LAMMPS units, but you would need to create your own +custom BNCH.ILP potential file with coefficients listed in the appropriate units, if your simulation does not use *metal* units. Related commands @@ -181,6 +181,14 @@ tap_flag = 1 ---------- +.. _Ouyang1: + +**(Ouyang1)** W. Ouyang, D. Mandelli, M. Urbakh and O. Hod, Nano Lett. 18, 6009-6016 (2018). + +.. _Ouyang2: + +**(Ouyang2)** W. Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020). + .. _Leven1: **(Leven1)** I. Leven, I. Azuri, L. Kronik and O. Hod, J. Chem. Phys. 140, 104106 (2014). @@ -196,11 +204,3 @@ tap_flag = 1 .. _Kolmogorov2: **(Kolmogorov)** A. N. Kolmogorov, V. H. Crespi, Phys. Rev. B 71, 235415 (2005). - -.. _Ouyang1: - -**(Ouyang1)** W. Ouyang, D. Mandelli, M. Urbakh and O. Hod, Nano Lett. 18, 6009-6016 (2018). - -.. _Ouyang2: - -**(Ouyang2)** W. Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020). diff --git a/doc/src/pair_ilp_tmd.rst b/doc/src/pair_ilp_tmd.rst index 77fa8bbfd5..482d75a100 100644 --- a/doc/src/pair_ilp_tmd.rst +++ b/doc/src/pair_ilp_tmd.rst @@ -135,8 +135,8 @@ interactions. The TMD.ILP potential file provided with LAMMPS (see the potentials directory) are parameterized for *metal* units. You can use this -potential with any LAMMPS units, but you would need to create your -BNCH.ILP potential file with coefficients listed in the appropriate +potential with any LAMMPS units, but you would need to create your own +custom TMD.ILP potential file with coefficients listed in the appropriate units, if your simulation does not use *metal* units. Related commands diff --git a/doc/src/pair_ilp_water_2dm.rst b/doc/src/pair_ilp_water_2dm.rst new file mode 100644 index 0000000000..5dc287493b --- /dev/null +++ b/doc/src/pair_ilp_water_2dm.rst @@ -0,0 +1,166 @@ +.. index:: pair_style ilp/water/2dm +.. index:: pair_style ilp/water/2dm/opt + +pair_style ilp/tmd command +=================================== + +Accelerator Variant: *ilp/water/2dm/opt* + +Syntax +"""""" + +.. code-block:: LAMMPS + + pair_style [hybrid/overlay ...] ilp/tmd cutoff tap_flag + +* cutoff = global cutoff (distance units) +* tap_flag = 0/1 to turn off/on the taper function + +Examples +"""""""" + +.. code-block:: LAMMPS + + pair_style hybrid/overlay ilp/water/2dm 16.0 1 + pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw + + pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 + pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O + pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H + pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H + pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw + +Description +""""""""""" + +.. versionadded:: xxxx2023 + +The *ilp/water/2dm* style computes the registry-dependent interlayer +potential (ILP) potential for interfaces of water with two-dimensinal (2D) +materials as described in :ref:`(Feng) `. + +.. math:: + + E = & \frac{1}{2} \sum_i \sum_{j \neq i} V_{ij} \\ + V_{ij} = & {\rm Tap}(r_{ij})\left \{ e^{-\alpha (r_{ij}/\beta -1)} + \left [ \epsilon + f(\rho_{ij}) + f(\rho_{ji})\right ] - + \frac{1}{1+e^{-d\left [ \left ( r_{ij}/\left (s_R \cdot r^{eff} \right ) \right )-1 \right ]}} + \cdot \frac{C_6}{r^6_{ij}} \right \}\\ + \rho_{ij}^2 = & r_{ij}^2 - ({\bf r}_{ij} \cdot {\bf n}_i)^2 \\ + \rho_{ji}^2 = & r_{ij}^2 - ({\bf r}_{ij} \cdot {\bf n}_j)^2 \\ + f(\rho) = & C e^{ -( \rho / \delta )^2 } \\ + {\rm Tap}(r_{ij}) = & 20\left ( \frac{r_{ij}}{R_{cut}} \right )^7 - + 70\left ( \frac{r_{ij}}{R_{cut}} \right )^6 + + 84\left ( \frac{r_{ij}}{R_{cut}} \right )^5 - + 35\left ( \frac{r_{ij}}{R_{cut}} \right )^4 + 1 + +Where :math:`\mathrm{Tap}(r_{ij})` is the taper function which provides +a continuous cutoff (up to third derivative) for interatomic separations +larger than :math:`r_c` :doc:`pair_style ilp_graphene_hbn `. + +It is important to include all the pairs to build the neighbor list for +calculating the normals. + +.. note:: + + Since each water molecule contains one oxygen atom and two hydrogen atoms, + a new definition is proposed (see In :ref:`(Feng) `),the atomic + normal vectors of hydrogen atoms are assumed to lie along the corresponding + oxygen-hydrogen bonds and the normal vector of the central oxygen atom + is defined as their average. + +The parameter file (e.g. COH.ILP), is intended for use with *metal* +:doc:`units `, with energies in meV. Two additional parameters, +*S*, and *rcut* are included in the parameter file. *S* is designed to +facilitate scaling of energies. *rcut* is designed to build the neighbor +list for calculating the normals for each atom pair. + +.. note:: + + The parameters presented in the parameter file (e.g. COH.ILP), + are fitted with taper function by setting the cutoff equal to 16.0 + Angstrom. Using different cutoff or taper function should be careful. + These parameters provide a good description in both short- and long-range + interaction regimes. This feature is essential for simulations in high pressure + regime (i.e., the interlayer distance is smaller than the equilibrium + distance). + +This potential must be used in combination with hybrid/overlay. +Other interactions can be set to zero using pair_style *none*\ . + +This pair style tallies a breakdown of the total interlayer potential +energy into sub-categories, which can be accessed via the :doc:`compute pair ` command as a vector of values of length 2. +The 2 values correspond to the following sub-categories: + +1. *E_vdW* = vdW (attractive) energy +2. *E_Rep* = Repulsive energy + +To print these quantities to the log file (with descriptive column +headings) the following commands could be included in an input script: + +.. code-block:: LAMMPS + + compute 0 all pair ilp/water/2dm + variable Evdw equal c_0[1] + variable Erep equal c_0[2] + thermo_style custom step temp epair v_Erep v_Evdw + +---------- + +.. include:: accel_styles.rst + +---------- + +Mixing, shift, table, tail correction, restart, rRESPA info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This pair style does not support the pair_modify mix, shift, table, and +tail options. + +This pair style does not write their information to binary restart +files, since it is stored in potential files. Thus, you need to +re-specify the pair_style and pair_coeff commands in an input script +that reads a restart file. + +Restrictions +"""""""""""" + +This pair style is part of the INTERLAYER package. It is only enabled +if LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +This pair style requires the newton setting to be *on* for pair +interactions. + +The COH.ILP potential file provided with LAMMPS (see the potentials +directory) are parameterized for *metal* units. You can use this +potential with any LAMMPS units, but you would need to create your +COH.ILP potential file with coefficients listed in the appropriate +units, if your simulation does not use *metal* units. + +Related commands +"""""""""""""""" + +:doc:`pair_coeff `, +:doc:`pair_none `, +:doc:`pair_style hybrid/overlay `, +:doc:`pair_style drip `, +:doc:`pair_style ilp_tmd `, +:doc:`pair_style saip_metal `, +:doc:`pair_style ilp_graphene_hbn `, +:doc:`pair_style pair_kolmogorov_crespi_z `, +:doc:`pair_style pair_kolmogorov_crespi_full `, +:doc:`pair_style pair_lebedeva_z `, +:doc:`pair_style pair_coul_shield `. + +Default +""""""" + +tap_flag = 1 + + +---------- + +.. _Feng: + +**(Feng)** Z. Feng, W. Ouyang, J. Phys. Chem. C. accepted (2023). diff --git a/doc/src/pair_kolmogorov_crespi_full.rst b/doc/src/pair_kolmogorov_crespi_full.rst index 1a33a3f4bb..1a4706dd6f 100644 --- a/doc/src/pair_kolmogorov_crespi_full.rst +++ b/doc/src/pair_kolmogorov_crespi_full.rst @@ -129,7 +129,7 @@ interactions. The CH.KC potential file provided with LAMMPS (see the potentials folder) is parameterized for metal units. You can use this pair style with any LAMMPS units, but you would need to create your own custom -CC.KC potential file with all coefficients converted to the appropriate +CH.KC potential file with all coefficients converted to the appropriate units. Related commands diff --git a/doc/src/pair_saip_metal.rst b/doc/src/pair_saip_metal.rst index 21bfeb0aa9..ed011894c9 100644 --- a/doc/src/pair_saip_metal.rst +++ b/doc/src/pair_saip_metal.rst @@ -134,8 +134,8 @@ interactions. The CHAu.ILP potential file provided with LAMMPS (see the potentials directory) are parameterized for *metal* units. You can use this -potential with any LAMMPS units, but you would need to create your -BNCH.ILP potential file with coefficients listed in the appropriate +potential with any LAMMPS units, but you would need to create your own +custom CHAu.ILP potential file with coefficients listed in the appropriate units, if your simulation does not use *metal* units. Related commands From bbff6c25b33625a1b34ff95e581c78d59eb74e56 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 18 May 2023 22:01:19 +0800 Subject: [PATCH 221/448] add examples --- .../PACKAGES/interlayer/ilp_water_2dm/COH.ILP | 1 + .../interlayer/ilp_water_2dm/gra_water.data | 2040 +++++++++++++++++ .../interlayer/ilp_water_2dm/in.gr_water | 51 + .../interlayer/ilp_water_2dm/in.gr_water.opt | 51 + .../ilp_water_2dm/log.18May23.water.g++.1 | 234 ++ .../ilp_water_2dm/log.18May23.water.g++.4 | 234 ++ .../ilp_water_2dm/log.18May23.water.opt.g++.1 | 251 ++ .../ilp_water_2dm/log.18May23.water.opt.g++.4 | 251 ++ 8 files changed, 3113 insertions(+) create mode 120000 examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP create mode 100644 examples/PACKAGES/interlayer/ilp_water_2dm/gra_water.data create mode 100644 examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water create mode 100644 examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water.opt create mode 100644 examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.1 create mode 100644 examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.4 create mode 100644 examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.1 create mode 100644 examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.4 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP b/examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP new file mode 120000 index 0000000000..526995dae4 --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP @@ -0,0 +1 @@ +../../../../potentials/COH.ILP \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/gra_water.data b/examples/PACKAGES/interlayer/ilp_water_2dm/gra_water.data new file mode 100644 index 0000000000..7e6d3925f0 --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/gra_water.data @@ -0,0 +1,2040 @@ +LAMMPS data file via write_data, version 23 Jun 2022, timestep = 100000 + +936 atoms +3 atom types +96 bonds +1 bond types +48 angles +1 angle types + +0 46.92336 xlo xhi +0 44.331078317370086 ylo yhi +0 200 zlo zhi + +Atoms # full + +1 1 1 0 0 0 0 0 0 0 +2 1 1 0 0.71096 1.231418842149169 0 0 0 0 +3 1 1 0 2.13288 1.231418842149169 0 0 0 0 +4 1 1 0 2.84384 0 0 0 0 0 +5 1 1 0 0 2.462837684298338 0 0 0 0 +6 1 1 0 0.71096 3.694256526447507 0 0 0 0 +7 1 1 0 2.13288 3.694256526447507 0 0 0 0 +8 1 1 0 2.84384 2.462837684298338 0 0 0 0 +9 1 1 0 0 4.925675368596676 0 0 0 0 +10 1 1 0 0.71096 6.157094210745845 0 0 0 0 +11 1 1 0 2.13288 6.157094210745845 0 0 0 0 +12 1 1 0 2.84384 4.925675368596676 0 0 0 0 +13 1 1 0 0 7.388513052895014 0 0 0 0 +14 1 1 0 0.71096 8.619931895044184 0 0 0 0 +15 1 1 0 2.13288 8.619931895044184 0 0 0 0 +16 1 1 0 2.84384 7.388513052895014 0 0 0 0 +17 1 1 0 0 9.851350737193352 0 0 0 0 +20 1 1 0 2.84384 9.851350737193352 0 0 0 0 +73 1 1 0 4.26576 0 0 0 0 0 +74 1 1 0 4.97672 1.231418842149169 0 0 0 0 +77 1 1 0 4.26576 2.462837684298338 0 0 0 0 +78 1 1 0 4.97672 3.694256526447507 0 0 0 0 +81 1 1 0 4.26576 4.925675368596676 0 0 0 0 +82 1 1 0 4.97672 6.157094210745845 0 0 0 0 +85 1 1 0 4.26576 7.388513052895014 0 0 0 0 +86 1 1 0 4.97672 8.619931895044184 0 0 0 0 +89 1 1 0 4.26576 9.851350737193352 0 0 0 0 +18 1 1 0 0.71096 11.082769579342521 0 0 0 0 +19 1 1 0 2.13288 11.082769579342521 0 0 0 0 +21 1 1 0 0 12.31418842149169 0 0 0 0 +22 1 1 0 0.71096 13.545607263640859 0 0 0 0 +23 1 1 0 2.13288 13.545607263640859 0 0 0 0 +24 1 1 0 2.84384 12.31418842149169 0 0 0 0 +25 1 1 0 0 14.777026105790029 0 0 0 0 +26 1 1 0 0.71096 16.008444947939196 0 0 0 0 +27 1 1 0 2.13288 16.008444947939196 0 0 0 0 +28 1 1 0 2.84384 14.777026105790029 0 0 0 0 +29 1 1 0 0 17.239863790088364 0 0 0 0 +30 1 1 0 0.71096 18.471282632237532 0 0 0 0 +31 1 1 0 2.13288 18.471282632237532 0 0 0 0 +32 1 1 0 2.84384 17.239863790088364 0 0 0 0 +33 1 1 0 0 19.702701474386703 0 0 0 0 +34 1 1 0 0.71096 20.93412031653587 0 0 0 0 +35 1 1 0 2.13288 20.93412031653587 0 0 0 0 +36 1 1 0 2.84384 19.702701474386703 0 0 0 0 +90 1 1 0 4.97672 11.082769579342521 0 0 0 0 +93 1 1 0 4.26576 12.31418842149169 0 0 0 0 +94 1 1 0 4.97672 13.545607263640859 0 0 0 0 +97 1 1 0 4.26576 14.777026105790029 0 0 0 0 +98 1 1 0 4.97672 16.008444947939196 0 0 0 0 +101 1 1 0 4.26576 17.239863790088364 0 0 0 0 +102 1 1 0 4.97672 18.471282632237532 0 0 0 0 +105 1 1 0 4.26576 19.702701474386703 0 0 0 0 +106 1 1 0 4.97672 20.93412031653587 0 0 0 0 +37 1 1 0 0 22.165539158685043 0 0 0 0 +38 1 1 0 0.71096 23.39695800083421 0 0 0 0 +39 1 1 0 2.13288 23.39695800083421 0 0 0 0 +40 1 1 0 2.84384 22.165539158685043 0 0 0 0 +41 1 1 0 0 24.62837684298338 0 0 0 0 +42 1 1 0 0.71096 25.859795685132546 0 0 0 0 +43 1 1 0 2.13288 25.859795685132546 0 0 0 0 +44 1 1 0 2.84384 24.62837684298338 0 0 0 0 +45 1 1 0 0 27.091214527281718 0 0 0 0 +46 1 1 0 0.71096 28.322633369430886 0 0 0 0 +47 1 1 0 2.13288 28.322633369430886 0 0 0 0 +48 1 1 0 2.84384 27.091214527281718 0 0 0 0 +49 1 1 0 0 29.554052211580057 0 0 0 0 +50 1 1 0 0.71096 30.785471053729225 0 0 0 0 +51 1 1 0 2.13288 30.785471053729225 0 0 0 0 +52 1 1 0 2.84384 29.554052211580057 0 0 0 0 +53 1 1 0 0 32.01688989587839 0 0 0 0 +56 1 1 0 2.84384 32.01688989587839 0 0 0 0 +109 1 1 0 4.26576 22.165539158685043 0 0 0 0 +110 1 1 0 4.97672 23.39695800083421 0 0 0 0 +113 1 1 0 4.26576 24.62837684298338 0 0 0 0 +114 1 1 0 4.97672 25.859795685132546 0 0 0 0 +117 1 1 0 4.26576 27.091214527281718 0 0 0 0 +118 1 1 0 4.97672 28.322633369430886 0 0 0 0 +121 1 1 0 4.26576 29.554052211580057 0 0 0 0 +122 1 1 0 4.97672 30.785471053729225 0 0 0 0 +125 1 1 0 4.26576 32.01688989587839 0 0 0 0 +54 1 1 0 0.71096 33.24830873802756 0 0 0 0 +55 1 1 0 2.13288 33.24830873802756 0 0 0 0 +57 1 1 0 0 34.47972758017673 0 0 0 0 +58 1 1 0 0.71096 35.711146422325896 0 0 0 0 +59 1 1 0 2.13288 35.711146422325896 0 0 0 0 +60 1 1 0 2.84384 34.47972758017673 0 0 0 0 +61 1 1 0 0 36.94256526447507 0 0 0 0 +62 1 1 0 0.71096 38.17398410662424 0 0 0 0 +63 1 1 0 2.13288 38.17398410662424 0 0 0 0 +64 1 1 0 2.84384 36.94256526447507 0 0 0 0 +65 1 1 0 0 39.40540294877341 0 0 0 0 +66 1 1 0 0.71096 40.636821790922575 0 0 0 0 +67 1 1 0 2.13288 40.636821790922575 0 0 0 0 +68 1 1 0 2.84384 39.40540294877341 0 0 0 0 +69 1 1 0 0 41.86824063307174 0 0 0 0 +70 1 1 0 0.71096 43.09965947522091 0 0 0 0 +71 1 1 0 2.13288 43.09965947522091 0 0 0 0 +72 1 1 0 2.84384 41.86824063307174 0 0 0 0 +126 1 1 0 4.97672 33.24830873802756 0 0 0 0 +129 1 1 0 4.26576 34.47972758017673 0 0 0 0 +130 1 1 0 4.97672 35.711146422325896 0 0 0 0 +133 1 1 0 4.26576 36.94256526447507 0 0 0 0 +134 1 1 0 4.97672 38.17398410662424 0 0 0 0 +137 1 1 0 4.26576 39.40540294877341 0 0 0 0 +138 1 1 0 4.97672 40.636821790922575 0 0 0 0 +141 1 1 0 4.26576 41.86824063307174 0 0 0 0 +142 1 1 0 4.97672 43.09965947522091 0 0 0 0 +75 1 1 0 6.39864 1.231418842149169 0 0 0 0 +76 1 1 0 7.1096 0 0 0 0 0 +79 1 1 0 6.39864 3.694256526447507 0 0 0 0 +80 1 1 0 7.1096 2.462837684298338 0 0 0 0 +83 1 1 0 6.39864 6.157094210745845 0 0 0 0 +84 1 1 0 7.1096 4.925675368596676 0 0 0 0 +87 1 1 0 6.39864 8.619931895044184 0 0 0 0 +88 1 1 0 7.1096 7.388513052895014 0 0 0 0 +92 1 1 0 7.1096 9.851350737193352 0 0 0 0 +145 1 1 0 8.53152 0 0 0 0 0 +146 1 1 0 9.24248 1.231418842149169 0 0 0 0 +147 1 1 0 10.6644 1.231418842149169 0 0 0 0 +148 1 1 0 11.37536 0 0 0 0 0 +149 1 1 0 8.53152 2.462837684298338 0 0 0 0 +150 1 1 0 9.24248 3.694256526447507 0 0 0 0 +151 1 1 0 10.6644 3.694256526447507 0 0 0 0 +152 1 1 0 11.37536 2.462837684298338 0 0 0 0 +153 1 1 0 8.53152 4.925675368596676 0 0 0 0 +154 1 1 0 9.24248 6.157094210745845 0 0 0 0 +155 1 1 0 10.6644 6.157094210745845 0 0 0 0 +156 1 1 0 11.37536 4.925675368596676 0 0 0 0 +157 1 1 0 8.53152 7.388513052895014 0 0 0 0 +158 1 1 0 9.24248 8.619931895044184 0 0 0 0 +159 1 1 0 10.6644 8.619931895044184 0 0 0 0 +160 1 1 0 11.37536 7.388513052895014 0 0 0 0 +161 1 1 0 8.53152 9.851350737193352 0 0 0 0 +164 1 1 0 11.37536 9.851350737193352 0 0 0 0 +91 1 1 0 6.39864 11.082769579342521 0 0 0 0 +95 1 1 0 6.39864 13.545607263640859 0 0 0 0 +96 1 1 0 7.1096 12.31418842149169 0 0 0 0 +99 1 1 0 6.39864 16.008444947939196 0 0 0 0 +100 1 1 0 7.1096 14.777026105790029 0 0 0 0 +103 1 1 0 6.39864 18.471282632237532 0 0 0 0 +104 1 1 0 7.1096 17.239863790088364 0 0 0 0 +107 1 1 0 6.39864 20.93412031653587 0 0 0 0 +108 1 1 0 7.1096 19.702701474386703 0 0 0 0 +162 1 1 0 9.24248 11.082769579342521 0 0 0 0 +163 1 1 0 10.6644 11.082769579342521 0 0 0 0 +165 1 1 0 8.53152 12.31418842149169 0 0 0 0 +166 1 1 0 9.24248 13.545607263640859 0 0 0 0 +167 1 1 0 10.6644 13.545607263640859 0 0 0 0 +168 1 1 0 11.37536 12.31418842149169 0 0 0 0 +169 1 1 0 8.53152 14.777026105790029 0 0 0 0 +170 1 1 0 9.24248 16.008444947939196 0 0 0 0 +171 1 1 0 10.6644 16.008444947939196 0 0 0 0 +172 1 1 0 11.37536 14.777026105790029 0 0 0 0 +173 1 1 0 8.53152 17.239863790088364 0 0 0 0 +174 1 1 0 9.24248 18.471282632237532 0 0 0 0 +175 1 1 0 10.6644 18.471282632237532 0 0 0 0 +176 1 1 0 11.37536 17.239863790088364 0 0 0 0 +177 1 1 0 8.53152 19.702701474386703 0 0 0 0 +178 1 1 0 9.24248 20.93412031653587 0 0 0 0 +179 1 1 0 10.6644 20.93412031653587 0 0 0 0 +180 1 1 0 11.37536 19.702701474386703 0 0 0 0 +111 1 1 0 6.39864 23.39695800083421 0 0 0 0 +112 1 1 0 7.1096 22.165539158685043 0 0 0 0 +115 1 1 0 6.39864 25.859795685132546 0 0 0 0 +116 1 1 0 7.1096 24.62837684298338 0 0 0 0 +119 1 1 0 6.39864 28.322633369430886 0 0 0 0 +120 1 1 0 7.1096 27.091214527281718 0 0 0 0 +123 1 1 0 6.39864 30.785471053729225 0 0 0 0 +124 1 1 0 7.1096 29.554052211580057 0 0 0 0 +128 1 1 0 7.1096 32.01688989587839 0 0 0 0 +181 1 1 0 8.53152 22.165539158685043 0 0 0 0 +182 1 1 0 9.24248 23.39695800083421 0 0 0 0 +183 1 1 0 10.6644 23.39695800083421 0 0 0 0 +184 1 1 0 11.37536 22.165539158685043 0 0 0 0 +185 1 1 0 8.53152 24.62837684298338 0 0 0 0 +186 1 1 0 9.24248 25.859795685132546 0 0 0 0 +187 1 1 0 10.6644 25.859795685132546 0 0 0 0 +188 1 1 0 11.37536 24.62837684298338 0 0 0 0 +189 1 1 0 8.53152 27.091214527281718 0 0 0 0 +190 1 1 0 9.24248 28.322633369430886 0 0 0 0 +191 1 1 0 10.6644 28.322633369430886 0 0 0 0 +192 1 1 0 11.37536 27.091214527281718 0 0 0 0 +193 1 1 0 8.53152 29.554052211580057 0 0 0 0 +194 1 1 0 9.24248 30.785471053729225 0 0 0 0 +195 1 1 0 10.6644 30.785471053729225 0 0 0 0 +196 1 1 0 11.37536 29.554052211580057 0 0 0 0 +197 1 1 0 8.53152 32.01688989587839 0 0 0 0 +200 1 1 0 11.37536 32.01688989587839 0 0 0 0 +127 1 1 0 6.39864 33.24830873802756 0 0 0 0 +131 1 1 0 6.39864 35.711146422325896 0 0 0 0 +132 1 1 0 7.1096 34.47972758017673 0 0 0 0 +135 1 1 0 6.39864 38.17398410662424 0 0 0 0 +136 1 1 0 7.1096 36.94256526447507 0 0 0 0 +139 1 1 0 6.39864 40.636821790922575 0 0 0 0 +140 1 1 0 7.1096 39.40540294877341 0 0 0 0 +143 1 1 0 6.39864 43.09965947522091 0 0 0 0 +144 1 1 0 7.1096 41.86824063307174 0 0 0 0 +198 1 1 0 9.24248 33.24830873802756 0 0 0 0 +199 1 1 0 10.6644 33.24830873802756 0 0 0 0 +201 1 1 0 8.53152 34.47972758017673 0 0 0 0 +202 1 1 0 9.24248 35.711146422325896 0 0 0 0 +203 1 1 0 10.6644 35.711146422325896 0 0 0 0 +204 1 1 0 11.37536 34.47972758017673 0 0 0 0 +205 1 1 0 8.53152 36.94256526447507 0 0 0 0 +206 1 1 0 9.24248 38.17398410662424 0 0 0 0 +207 1 1 0 10.6644 38.17398410662424 0 0 0 0 +208 1 1 0 11.37536 36.94256526447507 0 0 0 0 +209 1 1 0 8.53152 39.40540294877341 0 0 0 0 +210 1 1 0 9.24248 40.636821790922575 0 0 0 0 +211 1 1 0 10.6644 40.636821790922575 0 0 0 0 +212 1 1 0 11.37536 39.40540294877341 0 0 0 0 +213 1 1 0 8.53152 41.86824063307174 0 0 0 0 +214 1 1 0 9.24248 43.09965947522091 0 0 0 0 +215 1 1 0 10.6644 43.09965947522091 0 0 0 0 +216 1 1 0 11.37536 41.86824063307174 0 0 0 0 +217 1 1 0 12.79728 0 0 0 0 0 +218 1 1 0 13.50824 1.231418842149169 0 0 0 0 +219 1 1 0 14.93016 1.231418842149169 0 0 0 0 +220 1 1 0 15.64112 0 0 0 0 0 +221 1 1 0 12.79728 2.462837684298338 0 0 0 0 +222 1 1 0 13.50824 3.694256526447507 0 0 0 0 +223 1 1 0 14.93016 3.694256526447507 0 0 0 0 +224 1 1 0 15.64112 2.462837684298338 0 0 0 0 +225 1 1 0 12.79728 4.925675368596676 0 0 0 0 +226 1 1 0 13.50824 6.157094210745845 0 0 0 0 +227 1 1 0 14.93016 6.157094210745845 0 0 0 0 +228 1 1 0 15.64112 4.925675368596676 0 0 0 0 +229 1 1 0 12.79728 7.388513052895014 0 0 0 0 +230 1 1 0 13.50824 8.619931895044184 0 0 0 0 +231 1 1 0 14.93016 8.619931895044184 0 0 0 0 +232 1 1 0 15.64112 7.388513052895014 0 0 0 0 +233 1 1 0 12.79728 9.851350737193352 0 0 0 0 +236 1 1 0 15.64112 9.851350737193352 0 0 0 0 +289 1 1 0 17.06304 0 0 0 0 0 +293 1 1 0 17.06304 2.462837684298338 0 0 0 0 +297 1 1 0 17.06304 4.925675368596676 0 0 0 0 +301 1 1 0 17.06304 7.388513052895014 0 0 0 0 +305 1 1 0 17.06304 9.851350737193352 0 0 0 0 +234 1 1 0 13.50824 11.082769579342521 0 0 0 0 +235 1 1 0 14.93016 11.082769579342521 0 0 0 0 +237 1 1 0 12.79728 12.31418842149169 0 0 0 0 +238 1 1 0 13.50824 13.545607263640859 0 0 0 0 +239 1 1 0 14.93016 13.545607263640859 0 0 0 0 +240 1 1 0 15.64112 12.31418842149169 0 0 0 0 +241 1 1 0 12.79728 14.777026105790029 0 0 0 0 +242 1 1 0 13.50824 16.008444947939196 0 0 0 0 +243 1 1 0 14.93016 16.008444947939196 0 0 0 0 +244 1 1 0 15.64112 14.777026105790029 0 0 0 0 +245 1 1 0 12.79728 17.239863790088364 0 0 0 0 +246 1 1 0 13.50824 18.471282632237532 0 0 0 0 +247 1 1 0 14.93016 18.471282632237532 0 0 0 0 +248 1 1 0 15.64112 17.239863790088364 0 0 0 0 +249 1 1 0 12.79728 19.702701474386703 0 0 0 0 +250 1 1 0 13.50824 20.93412031653587 0 0 0 0 +251 1 1 0 14.93016 20.93412031653587 0 0 0 0 +252 1 1 0 15.64112 19.702701474386703 0 0 0 0 +309 1 1 0 17.06304 12.31418842149169 0 0 0 0 +313 1 1 0 17.06304 14.777026105790029 0 0 0 0 +317 1 1 0 17.06304 17.239863790088364 0 0 0 0 +321 1 1 0 17.06304 19.702701474386703 0 0 0 0 +253 1 1 0 12.79728 22.165539158685043 0 0 0 0 +254 1 1 0 13.50824 23.39695800083421 0 0 0 0 +255 1 1 0 14.93016 23.39695800083421 0 0 0 0 +256 1 1 0 15.64112 22.165539158685043 0 0 0 0 +257 1 1 0 12.79728 24.62837684298338 0 0 0 0 +258 1 1 0 13.50824 25.859795685132546 0 0 0 0 +259 1 1 0 14.93016 25.859795685132546 0 0 0 0 +260 1 1 0 15.64112 24.62837684298338 0 0 0 0 +261 1 1 0 12.79728 27.091214527281718 0 0 0 0 +262 1 1 0 13.50824 28.322633369430886 0 0 0 0 +263 1 1 0 14.93016 28.322633369430886 0 0 0 0 +264 1 1 0 15.64112 27.091214527281718 0 0 0 0 +265 1 1 0 12.79728 29.554052211580057 0 0 0 0 +266 1 1 0 13.50824 30.785471053729225 0 0 0 0 +267 1 1 0 14.93016 30.785471053729225 0 0 0 0 +268 1 1 0 15.64112 29.554052211580057 0 0 0 0 +269 1 1 0 12.79728 32.01688989587839 0 0 0 0 +272 1 1 0 15.64112 32.01688989587839 0 0 0 0 +325 1 1 0 17.06304 22.165539158685043 0 0 0 0 +329 1 1 0 17.06304 24.62837684298338 0 0 0 0 +333 1 1 0 17.06304 27.091214527281718 0 0 0 0 +337 1 1 0 17.06304 29.554052211580057 0 0 0 0 +341 1 1 0 17.06304 32.01688989587839 0 0 0 0 +270 1 1 0 13.50824 33.24830873802756 0 0 0 0 +271 1 1 0 14.93016 33.24830873802756 0 0 0 0 +273 1 1 0 12.79728 34.47972758017673 0 0 0 0 +274 1 1 0 13.50824 35.711146422325896 0 0 0 0 +275 1 1 0 14.93016 35.711146422325896 0 0 0 0 +276 1 1 0 15.64112 34.47972758017673 0 0 0 0 +277 1 1 0 12.79728 36.94256526447507 0 0 0 0 +278 1 1 0 13.50824 38.17398410662424 0 0 0 0 +279 1 1 0 14.93016 38.17398410662424 0 0 0 0 +280 1 1 0 15.64112 36.94256526447507 0 0 0 0 +281 1 1 0 12.79728 39.40540294877341 0 0 0 0 +282 1 1 0 13.50824 40.636821790922575 0 0 0 0 +283 1 1 0 14.93016 40.636821790922575 0 0 0 0 +284 1 1 0 15.64112 39.40540294877341 0 0 0 0 +285 1 1 0 12.79728 41.86824063307174 0 0 0 0 +286 1 1 0 13.50824 43.09965947522091 0 0 0 0 +287 1 1 0 14.93016 43.09965947522091 0 0 0 0 +288 1 1 0 15.64112 41.86824063307174 0 0 0 0 +345 1 1 0 17.06304 34.47972758017673 0 0 0 0 +349 1 1 0 17.06304 36.94256526447507 0 0 0 0 +353 1 1 0 17.06304 39.40540294877341 0 0 0 0 +357 1 1 0 17.06304 41.86824063307174 0 0 0 0 +290 1 1 0 17.774 1.231418842149169 0 0 0 0 +291 1 1 0 19.19592 1.231418842149169 0 0 0 0 +292 1 1 0 19.90688 0 0 0 0 0 +294 1 1 0 17.774 3.694256526447507 0 0 0 0 +295 1 1 0 19.19592 3.694256526447507 0 0 0 0 +296 1 1 0 19.90688 2.462837684298338 0 0 0 0 +298 1 1 0 17.774 6.157094210745845 0 0 0 0 +299 1 1 0 19.19592 6.157094210745845 0 0 0 0 +300 1 1 0 19.90688 4.925675368596676 0 0 0 0 +302 1 1 0 17.774 8.619931895044184 0 0 0 0 +303 1 1 0 19.19592 8.619931895044184 0 0 0 0 +304 1 1 0 19.90688 7.388513052895014 0 0 0 0 +308 1 1 0 19.90688 9.851350737193352 0 0 0 0 +361 1 1 0 21.3288 0 0 0 0 0 +362 1 1 0 22.03976 1.231418842149169 0 0 0 0 +365 1 1 0 21.3288 2.462837684298338 0 0 0 0 +366 1 1 0 22.03976 3.694256526447507 0 0 0 0 +369 1 1 0 21.3288 4.925675368596676 0 0 0 0 +370 1 1 0 22.03976 6.157094210745845 0 0 0 0 +373 1 1 0 21.3288 7.388513052895014 0 0 0 0 +374 1 1 0 22.03976 8.619931895044184 0 0 0 0 +377 1 1 0 21.3288 9.851350737193352 0 0 0 0 +306 1 1 0 17.774 11.082769579342521 0 0 0 0 +307 1 1 0 19.19592 11.082769579342521 0 0 0 0 +310 1 1 0 17.774 13.545607263640859 0 0 0 0 +311 1 1 0 19.19592 13.545607263640859 0 0 0 0 +312 1 1 0 19.90688 12.31418842149169 0 0 0 0 +314 1 1 0 17.774 16.008444947939196 0 0 0 0 +315 1 1 0 19.19592 16.008444947939196 0 0 0 0 +316 1 1 0 19.90688 14.777026105790029 0 0 0 0 +318 1 1 0 17.774 18.471282632237532 0 0 0 0 +319 1 1 0 19.19592 18.471282632237532 0 0 0 0 +320 1 1 0 19.90688 17.239863790088364 0 0 0 0 +322 1 1 0 17.774 20.93412031653587 0 0 0 0 +323 1 1 0 19.19592 20.93412031653587 0 0 0 0 +324 1 1 0 19.90688 19.702701474386703 0 0 0 0 +378 1 1 0 22.03976 11.082769579342521 0 0 0 0 +381 1 1 0 21.3288 12.31418842149169 0 0 0 0 +382 1 1 0 22.03976 13.545607263640859 0 0 0 0 +385 1 1 0 21.3288 14.777026105790029 0 0 0 0 +386 1 1 0 22.03976 16.008444947939196 0 0 0 0 +389 1 1 0 21.3288 17.239863790088364 0 0 0 0 +390 1 1 0 22.03976 18.471282632237532 0 0 0 0 +393 1 1 0 21.3288 19.702701474386703 0 0 0 0 +394 1 1 0 22.03976 20.93412031653587 0 0 0 0 +326 1 1 0 17.774 23.39695800083421 0 0 0 0 +327 1 1 0 19.19592 23.39695800083421 0 0 0 0 +328 1 1 0 19.90688 22.165539158685043 0 0 0 0 +330 1 1 0 17.774 25.859795685132546 0 0 0 0 +331 1 1 0 19.19592 25.859795685132546 0 0 0 0 +332 1 1 0 19.90688 24.62837684298338 0 0 0 0 +334 1 1 0 17.774 28.322633369430886 0 0 0 0 +335 1 1 0 19.19592 28.322633369430886 0 0 0 0 +336 1 1 0 19.90688 27.091214527281718 0 0 0 0 +338 1 1 0 17.774 30.785471053729225 0 0 0 0 +339 1 1 0 19.19592 30.785471053729225 0 0 0 0 +340 1 1 0 19.90688 29.554052211580057 0 0 0 0 +344 1 1 0 19.90688 32.01688989587839 0 0 0 0 +397 1 1 0 21.3288 22.165539158685043 0 0 0 0 +398 1 1 0 22.03976 23.39695800083421 0 0 0 0 +401 1 1 0 21.3288 24.62837684298338 0 0 0 0 +402 1 1 0 22.03976 25.859795685132546 0 0 0 0 +405 1 1 0 21.3288 27.091214527281718 0 0 0 0 +406 1 1 0 22.03976 28.322633369430886 0 0 0 0 +409 1 1 0 21.3288 29.554052211580057 0 0 0 0 +410 1 1 0 22.03976 30.785471053729225 0 0 0 0 +413 1 1 0 21.3288 32.01688989587839 0 0 0 0 +342 1 1 0 17.774 33.24830873802756 0 0 0 0 +343 1 1 0 19.19592 33.24830873802756 0 0 0 0 +346 1 1 0 17.774 35.711146422325896 0 0 0 0 +347 1 1 0 19.19592 35.711146422325896 0 0 0 0 +348 1 1 0 19.90688 34.47972758017673 0 0 0 0 +350 1 1 0 17.774 38.17398410662424 0 0 0 0 +351 1 1 0 19.19592 38.17398410662424 0 0 0 0 +352 1 1 0 19.90688 36.94256526447507 0 0 0 0 +354 1 1 0 17.774 40.636821790922575 0 0 0 0 +355 1 1 0 19.19592 40.636821790922575 0 0 0 0 +356 1 1 0 19.90688 39.40540294877341 0 0 0 0 +358 1 1 0 17.774 43.09965947522091 0 0 0 0 +359 1 1 0 19.19592 43.09965947522091 0 0 0 0 +360 1 1 0 19.90688 41.86824063307174 0 0 0 0 +414 1 1 0 22.03976 33.24830873802756 0 0 0 0 +417 1 1 0 21.3288 34.47972758017673 0 0 0 0 +418 1 1 0 22.03976 35.711146422325896 0 0 0 0 +421 1 1 0 21.3288 36.94256526447507 0 0 0 0 +422 1 1 0 22.03976 38.17398410662424 0 0 0 0 +425 1 1 0 21.3288 39.40540294877341 0 0 0 0 +426 1 1 0 22.03976 40.636821790922575 0 0 0 0 +429 1 1 0 21.3288 41.86824063307174 0 0 0 0 +430 1 1 0 22.03976 43.09965947522091 0 0 0 0 +363 1 1 0 23.46168 1.231418842149169 0 0 0 0 +364 1 1 0 24.17264 0 0 0 0 0 +367 1 1 0 23.46168 3.694256526447507 0 0 0 0 +368 1 1 0 24.17264 2.462837684298338 0 0 0 0 +371 1 1 0 23.46168 6.157094210745845 0 0 0 0 +372 1 1 0 24.17264 4.925675368596676 0 0 0 0 +375 1 1 0 23.46168 8.619931895044184 0 0 0 0 +376 1 1 0 24.17264 7.388513052895014 0 0 0 0 +380 1 1 0 24.17264 9.851350737193352 0 0 0 0 +433 1 1 0 25.59456 0 0 0 0 0 +434 1 1 0 26.30552 1.231418842149169 0 0 0 0 +435 1 1 0 27.72744 1.231418842149169 0 0 0 0 +436 1 1 0 28.4384 0 0 0 0 0 +437 1 1 0 25.59456 2.462837684298338 0 0 0 0 +438 1 1 0 26.30552 3.694256526447507 0 0 0 0 +439 1 1 0 27.72744 3.694256526447507 0 0 0 0 +440 1 1 0 28.4384 2.462837684298338 0 0 0 0 +441 1 1 0 25.59456 4.925675368596676 0 0 0 0 +442 1 1 0 26.30552 6.157094210745845 0 0 0 0 +443 1 1 0 27.72744 6.157094210745845 0 0 0 0 +444 1 1 0 28.4384 4.925675368596676 0 0 0 0 +445 1 1 0 25.59456 7.388513052895014 0 0 0 0 +446 1 1 0 26.30552 8.619931895044184 0 0 0 0 +447 1 1 0 27.72744 8.619931895044184 0 0 0 0 +448 1 1 0 28.4384 7.388513052895014 0 0 0 0 +449 1 1 0 25.59456 9.851350737193352 0 0 0 0 +452 1 1 0 28.4384 9.851350737193352 0 0 0 0 +824 2 3 0.5564 27.869304504728962 5.441231954072771 7.1662725516060455 0 1 0 +882 2 3 0.5564 28.591049353698207 2.8104183869168513 5.199459350263634 0 1 0 +915 2 3 0.5564 28.292441133424674 2.1988836940092424 7.463258849755662 0 1 0 +839 2 3 0.5564 26.910290112042958 6.063448035194025 5.063585745298239 0 1 0 +880 2 2 -1.1128 28.406942326033935 2.7991510311135688 4.260199050138843 0 1 0 +897 2 3 0.5564 27.747536325556545 1.2206385238286348 3.5735630764050397 0 1 0 +881 2 3 0.5564 29.245437925664305 3.008615335710485 3.848759968343325 0 1 0 +840 2 3 0.5564 27.732306784723644 4.9179177154124885 4.512269230492448 0 1 0 +823 2 2 -1.1128 27.744982568298607 4.921082089542739 7.960138430480629 0 1 0 +825 2 3 0.5564 28.164684169862443 5.433634827582471 8.651059816127074 0 1 0 +838 2 2 -1.1128 27.618723311223718 5.461577610249769 5.291862125144689 0 1 0 +918 2 3 0.5564 29.02685745449238 0.37211643590853727 5.955025086554165 0 1 0 +895 2 2 -1.1128 27.54700508575224 0.3218588761159764 3.312383533998835 0 1 0 +913 2 2 -1.1128 28.964145363419156 1.767681453892013 6.93494944041131 0 1 0 +896 2 3 0.5564 26.73803217297322 0.39396829884754553 2.8058305738430946 0 1 0 +379 1 1 0 23.46168 11.082769579342521 0 0 0 0 +383 1 1 0 23.46168 13.545607263640859 0 0 0 0 +384 1 1 0 24.17264 12.31418842149169 0 0 0 0 +387 1 1 0 23.46168 16.008444947939196 0 0 0 0 +388 1 1 0 24.17264 14.777026105790029 0 0 0 0 +391 1 1 0 23.46168 18.471282632237532 0 0 0 0 +392 1 1 0 24.17264 17.239863790088364 0 0 0 0 +395 1 1 0 23.46168 20.93412031653587 0 0 0 0 +396 1 1 0 24.17264 19.702701474386703 0 0 0 0 +450 1 1 0 26.30552 11.082769579342521 0 0 0 0 +451 1 1 0 27.72744 11.082769579342521 0 0 0 0 +453 1 1 0 25.59456 12.31418842149169 0 0 0 0 +454 1 1 0 26.30552 13.545607263640859 0 0 0 0 +455 1 1 0 27.72744 13.545607263640859 0 0 0 0 +456 1 1 0 28.4384 12.31418842149169 0 0 0 0 +457 1 1 0 25.59456 14.777026105790029 0 0 0 0 +458 1 1 0 26.30552 16.008444947939196 0 0 0 0 +459 1 1 0 27.72744 16.008444947939196 0 0 0 0 +460 1 1 0 28.4384 14.777026105790029 0 0 0 0 +461 1 1 0 25.59456 17.239863790088364 0 0 0 0 +462 1 1 0 26.30552 18.471282632237532 0 0 0 0 +463 1 1 0 27.72744 18.471282632237532 0 0 0 0 +464 1 1 0 28.4384 17.239863790088364 0 0 0 0 +465 1 1 0 25.59456 19.702701474386703 0 0 0 0 +466 1 1 0 26.30552 20.93412031653587 0 0 0 0 +467 1 1 0 27.72744 20.93412031653587 0 0 0 0 +468 1 1 0 28.4384 19.702701474386703 0 0 0 0 +399 1 1 0 23.46168 23.39695800083421 0 0 0 0 +400 1 1 0 24.17264 22.165539158685043 0 0 0 0 +403 1 1 0 23.46168 25.859795685132546 0 0 0 0 +404 1 1 0 24.17264 24.62837684298338 0 0 0 0 +407 1 1 0 23.46168 28.322633369430886 0 0 0 0 +408 1 1 0 24.17264 27.091214527281718 0 0 0 0 +411 1 1 0 23.46168 30.785471053729225 0 0 0 0 +412 1 1 0 24.17264 29.554052211580057 0 0 0 0 +416 1 1 0 24.17264 32.01688989587839 0 0 0 0 +469 1 1 0 25.59456 22.165539158685043 0 0 0 0 +470 1 1 0 26.30552 23.39695800083421 0 0 0 0 +471 1 1 0 27.72744 23.39695800083421 0 0 0 0 +472 1 1 0 28.4384 22.165539158685043 0 0 0 0 +473 1 1 0 25.59456 24.62837684298338 0 0 0 0 +474 1 1 0 26.30552 25.859795685132546 0 0 0 0 +475 1 1 0 27.72744 25.859795685132546 0 0 0 0 +476 1 1 0 28.4384 24.62837684298338 0 0 0 0 +477 1 1 0 25.59456 27.091214527281718 0 0 0 0 +478 1 1 0 26.30552 28.322633369430886 0 0 0 0 +479 1 1 0 27.72744 28.322633369430886 0 0 0 0 +480 1 1 0 28.4384 27.091214527281718 0 0 0 0 +481 1 1 0 25.59456 29.554052211580057 0 0 0 0 +482 1 1 0 26.30552 30.785471053729225 0 0 0 0 +483 1 1 0 27.72744 30.785471053729225 0 0 0 0 +484 1 1 0 28.4384 29.554052211580057 0 0 0 0 +485 1 1 0 25.59456 32.01688989587839 0 0 0 0 +488 1 1 0 28.4384 32.01688989587839 0 0 0 0 +415 1 1 0 23.46168 33.24830873802756 0 0 0 0 +419 1 1 0 23.46168 35.711146422325896 0 0 0 0 +420 1 1 0 24.17264 34.47972758017673 0 0 0 0 +423 1 1 0 23.46168 38.17398410662424 0 0 0 0 +424 1 1 0 24.17264 36.94256526447507 0 0 0 0 +427 1 1 0 23.46168 40.636821790922575 0 0 0 0 +428 1 1 0 24.17264 39.40540294877341 0 0 0 0 +431 1 1 0 23.46168 43.09965947522091 0 0 0 0 +432 1 1 0 24.17264 41.86824063307174 0 0 0 0 +486 1 1 0 26.30552 33.24830873802756 0 0 0 0 +487 1 1 0 27.72744 33.24830873802756 0 0 0 0 +489 1 1 0 25.59456 34.47972758017673 0 0 0 0 +490 1 1 0 26.30552 35.711146422325896 0 0 0 0 +491 1 1 0 27.72744 35.711146422325896 0 0 0 0 +492 1 1 0 28.4384 34.47972758017673 0 0 0 0 +493 1 1 0 25.59456 36.94256526447507 0 0 0 0 +494 1 1 0 26.30552 38.17398410662424 0 0 0 0 +495 1 1 0 27.72744 38.17398410662424 0 0 0 0 +496 1 1 0 28.4384 36.94256526447507 0 0 0 0 +497 1 1 0 25.59456 39.40540294877341 0 0 0 0 +498 1 1 0 26.30552 40.636821790922575 0 0 0 0 +499 1 1 0 27.72744 40.636821790922575 0 0 0 0 +500 1 1 0 28.4384 39.40540294877341 0 0 0 0 +501 1 1 0 25.59456 41.86824063307174 0 0 0 0 +502 1 1 0 26.30552 43.09965947522091 0 0 0 0 +503 1 1 0 27.72744 43.09965947522091 0 0 0 0 +504 1 1 0 28.4384 41.86824063307174 0 0 0 0 +916 2 2 -1.1128 29.08618298573557 43.94947838758336 5.367978087245454 0 0 0 +917 2 3 0.5564 28.386514599822995 44.08700021343198 4.729397955617813 0 0 0 +505 1 1 0 29.86032 0 0 0 0 0 +506 1 1 0 30.57128 1.231418842149169 0 0 0 0 +507 1 1 0 31.9932 1.231418842149169 0 0 0 0 +508 1 1 0 32.70416 0 0 0 0 0 +509 1 1 0 29.86032 2.462837684298338 0 0 0 0 +510 1 1 0 30.57128 3.694256526447507 0 0 0 0 +511 1 1 0 31.9932 3.694256526447507 0 0 0 0 +512 1 1 0 32.70416 2.462837684298338 0 0 0 0 +513 1 1 0 29.86032 4.925675368596676 0 0 0 0 +514 1 1 0 30.57128 6.157094210745845 0 0 0 0 +515 1 1 0 31.9932 6.157094210745845 0 0 0 0 +516 1 1 0 32.70416 4.925675368596676 0 0 0 0 +517 1 1 0 29.86032 7.388513052895014 0 0 0 0 +518 1 1 0 30.57128 8.619931895044184 0 0 0 0 +519 1 1 0 31.9932 8.619931895044184 0 0 0 0 +520 1 1 0 32.70416 7.388513052895014 0 0 0 0 +521 1 1 0 29.86032 9.851350737193352 0 0 0 0 +524 1 1 0 32.70416 9.851350737193352 0 0 0 0 +577 1 1 0 34.12608 0 0 0 0 0 +578 1 1 0 34.83704 1.231418842149169 0 0 0 0 +581 1 1 0 34.12608 2.462837684298338 0 0 0 0 +582 1 1 0 34.83704 3.694256526447507 0 0 0 0 +585 1 1 0 34.12608 4.925675368596676 0 0 0 0 +586 1 1 0 34.83704 6.157094210745845 0 0 0 0 +589 1 1 0 34.12608 7.388513052895014 0 0 0 0 +590 1 1 0 34.83704 8.619931895044184 0 0 0 0 +593 1 1 0 34.12608 9.851350737193352 0 0 0 0 +817 2 2 -1.1128 32.95909328018726 1.6637108808053531 5.668801991409098 0 1 0 +934 2 2 -1.1128 33.03662922860542 5.539750355496759 3.4106598806856026 0 1 0 +844 2 2 -1.1128 32.621956673723574 8.462510491174692 3.097685137766835 0 1 0 +865 2 2 -1.1128 33.39821533005053 4.27658110246568 8.57211051291085 0 1 0 +926 2 3 0.5564 34.92704311330822 0.3845425638438278 3.265292528280904 0 1 0 +936 2 3 0.5564 33.75132011550044 5.390752767402144 2.7915877722683704 0 1 0 +845 2 3 0.5564 32.95333393700144 7.6062659773288255 3.3683635070864155 0 1 0 +819 2 3 0.5564 32.7762889404034 1.1154582070700432 4.905758051766679 0 1 0 +884 2 3 0.5564 34.37559715270682 2.4504450164493186 4.161687719751862 0 1 0 +928 2 2 -1.1128 31.427550994207557 2.4943780016602988 7.958560374626963 0 1 0 +832 2 2 -1.1128 30.792128585762608 3.236529264630232 3.148554951507026 0 1 0 +866 2 3 0.5564 33.498279431301086 5.15245480897742 8.94502756132422 0 1 0 +879 2 3 0.5564 31.732225644992504 0.6458474538482556 8.445047264076692 0 1 0 +929 2 3 0.5564 31.77966866913706 2.4458814443480152 7.069800530214144 0 1 0 +935 2 3 0.5564 33.378544384335676 5.232733920405251 4.250343211939568 0 1 0 +909 2 3 0.5564 34.652364031673926 9.711776039203794 3.0913066271420564 0 1 0 +846 2 3 0.5564 31.81206671515871 8.574696009442315 3.595405469907686 0 1 0 +867 2 3 0.5564 34.29090448110653 3.9354082288573955 8.517893415156758 0 1 0 +914 2 3 0.5564 29.77283350609241 1.883495478021958 7.433793196056744 0 1 0 +818 2 3 0.5564 33.45847517590033 1.097384085601532 6.25712553579729 0 1 0 +793 2 2 -1.1128 31.42830690864691 0.30749748676379024 3.451602894838017 0 1 0 +833 2 3 0.5564 31.524189385665945 3.8525231665567263 3.17806031753671 0 1 0 +834 2 3 0.5564 31.198864521440843 2.3888322887806708 2.969088763806106 0 1 0 +930 2 3 0.5564 31.832512681924495 3.2758254964154077 8.334829251422462 0 1 0 +883 2 2 -1.1128 35.06386221461597 2.1652239249670107 3.56071142612891 0 1 0 +794 2 3 0.5564 31.07805011932854 0.1628051877054162 2.572616093573198 0 1 0 +795 2 3 0.5564 30.711778331953756 0.06543858818245951 4.038311517945166 0 1 0 +522 1 1 0 30.57128 11.082769579342521 0 0 0 0 +523 1 1 0 31.9932 11.082769579342521 0 0 0 0 +525 1 1 0 29.86032 12.31418842149169 0 0 0 0 +526 1 1 0 30.57128 13.545607263640859 0 0 0 0 +527 1 1 0 31.9932 13.545607263640859 0 0 0 0 +528 1 1 0 32.70416 12.31418842149169 0 0 0 0 +529 1 1 0 29.86032 14.777026105790029 0 0 0 0 +530 1 1 0 30.57128 16.008444947939196 0 0 0 0 +531 1 1 0 31.9932 16.008444947939196 0 0 0 0 +532 1 1 0 32.70416 14.777026105790029 0 0 0 0 +533 1 1 0 29.86032 17.239863790088364 0 0 0 0 +534 1 1 0 30.57128 18.471282632237532 0 0 0 0 +535 1 1 0 31.9932 18.471282632237532 0 0 0 0 +536 1 1 0 32.70416 17.239863790088364 0 0 0 0 +537 1 1 0 29.86032 19.702701474386703 0 0 0 0 +538 1 1 0 30.57128 20.93412031653587 0 0 0 0 +539 1 1 0 31.9932 20.93412031653587 0 0 0 0 +540 1 1 0 32.70416 19.702701474386703 0 0 0 0 +594 1 1 0 34.83704 11.082769579342521 0 0 0 0 +597 1 1 0 34.12608 12.31418842149169 0 0 0 0 +598 1 1 0 34.83704 13.545607263640859 0 0 0 0 +601 1 1 0 34.12608 14.777026105790029 0 0 0 0 +602 1 1 0 34.83704 16.008444947939196 0 0 0 0 +605 1 1 0 34.12608 17.239863790088364 0 0 0 0 +606 1 1 0 34.83704 18.471282632237532 0 0 0 0 +609 1 1 0 34.12608 19.702701474386703 0 0 0 0 +610 1 1 0 34.83704 20.93412031653587 0 0 0 0 +541 1 1 0 29.86032 22.165539158685043 0 0 0 0 +542 1 1 0 30.57128 23.39695800083421 0 0 0 0 +543 1 1 0 31.9932 23.39695800083421 0 0 0 0 +544 1 1 0 32.70416 22.165539158685043 0 0 0 0 +545 1 1 0 29.86032 24.62837684298338 0 0 0 0 +546 1 1 0 30.57128 25.859795685132546 0 0 0 0 +547 1 1 0 31.9932 25.859795685132546 0 0 0 0 +548 1 1 0 32.70416 24.62837684298338 0 0 0 0 +549 1 1 0 29.86032 27.091214527281718 0 0 0 0 +550 1 1 0 30.57128 28.322633369430886 0 0 0 0 +551 1 1 0 31.9932 28.322633369430886 0 0 0 0 +552 1 1 0 32.70416 27.091214527281718 0 0 0 0 +553 1 1 0 29.86032 29.554052211580057 0 0 0 0 +554 1 1 0 30.57128 30.785471053729225 0 0 0 0 +555 1 1 0 31.9932 30.785471053729225 0 0 0 0 +556 1 1 0 32.70416 29.554052211580057 0 0 0 0 +557 1 1 0 29.86032 32.01688989587839 0 0 0 0 +560 1 1 0 32.70416 32.01688989587839 0 0 0 0 +613 1 1 0 34.12608 22.165539158685043 0 0 0 0 +614 1 1 0 34.83704 23.39695800083421 0 0 0 0 +617 1 1 0 34.12608 24.62837684298338 0 0 0 0 +618 1 1 0 34.83704 25.859795685132546 0 0 0 0 +621 1 1 0 34.12608 27.091214527281718 0 0 0 0 +622 1 1 0 34.83704 28.322633369430886 0 0 0 0 +625 1 1 0 34.12608 29.554052211580057 0 0 0 0 +626 1 1 0 34.83704 30.785471053729225 0 0 0 0 +629 1 1 0 34.12608 32.01688989587839 0 0 0 0 +558 1 1 0 30.57128 33.24830873802756 0 0 0 0 +559 1 1 0 31.9932 33.24830873802756 0 0 0 0 +561 1 1 0 29.86032 34.47972758017673 0 0 0 0 +562 1 1 0 30.57128 35.711146422325896 0 0 0 0 +563 1 1 0 31.9932 35.711146422325896 0 0 0 0 +564 1 1 0 32.70416 34.47972758017673 0 0 0 0 +565 1 1 0 29.86032 36.94256526447507 0 0 0 0 +566 1 1 0 30.57128 38.17398410662424 0 0 0 0 +567 1 1 0 31.9932 38.17398410662424 0 0 0 0 +568 1 1 0 32.70416 36.94256526447507 0 0 0 0 +569 1 1 0 29.86032 39.40540294877341 0 0 0 0 +570 1 1 0 30.57128 40.636821790922575 0 0 0 0 +571 1 1 0 31.9932 40.636821790922575 0 0 0 0 +572 1 1 0 32.70416 39.40540294877341 0 0 0 0 +573 1 1 0 29.86032 41.86824063307174 0 0 0 0 +574 1 1 0 30.57128 43.09965947522091 0 0 0 0 +575 1 1 0 31.9932 43.09965947522091 0 0 0 0 +576 1 1 0 32.70416 41.86824063307174 0 0 0 0 +630 1 1 0 34.83704 33.24830873802756 0 0 0 0 +633 1 1 0 34.12608 34.47972758017673 0 0 0 0 +634 1 1 0 34.83704 35.711146422325896 0 0 0 0 +637 1 1 0 34.12608 36.94256526447507 0 0 0 0 +638 1 1 0 34.83704 38.17398410662424 0 0 0 0 +641 1 1 0 34.12608 39.40540294877341 0 0 0 0 +642 1 1 0 34.83704 40.636821790922575 0 0 0 0 +645 1 1 0 34.12608 41.86824063307174 0 0 0 0 +646 1 1 0 34.83704 43.09965947522091 0 0 0 0 +857 2 3 0.5564 31.280093348563454 40.92413736707893 6.6129915041108855 0 0 0 +856 2 2 -1.1128 31.40625202155322 40.21708321945418 7.245756851263454 0 0 0 +892 2 2 -1.1128 31.44124789790012 42.595258440016934 5.939207128004798 0 0 0 +893 2 3 0.5564 31.51332483392942 42.86716514991827 6.854141078427132 0 0 0 +886 2 2 -1.1128 34.01903467331608 42.21640858508662 5.249166944042416 0 0 0 +828 2 3 0.5564 32.936087243922984 39.01715292261755 6.258330984602254 0 0 0 +887 2 3 0.5564 33.06416149038681 42.23692223473913 5.31266208454256 0 0 0 +826 2 2 -1.1128 33.39528676861921 38.50985593645892 5.588989616608882 0 0 0 +827 2 3 0.5564 32.73225698170465 37.911697838992474 5.244270601582248 0 0 0 +894 2 3 0.5564 30.602363734473947 42.95262718865609 5.648014222802151 0 0 0 +925 2 2 -1.1128 34.84802945499661 43.76986891444704 3.140612646843307 0 0 0 +858 2 3 0.5564 30.675738345874993 40.309216087673825 7.857389270234698 0 0 0 +878 2 3 0.5564 32.99974881977633 44.200178456643876 8.15878411943684 0 0 0 +812 2 3 0.5564 34.62910581051034 43.605123868773425 6.411277828859756 0 0 0 +927 2 3 0.5564 34.27329532640793 43.48151669199635 3.849673061844464 0 0 0 +888 2 3 0.5564 34.21818732626533 41.3445338672516 4.907982839354571 0 0 0 +877 2 2 -1.1128 32.10811143071273 44.09784681673461 8.491565398531655 0 0 0 +835 2 2 -1.1128 35.185759286779124 40.039097016824876 3.8999166884707246 0 0 0 +811 2 2 -1.1128 34.72988962100261 44.30600404203223 7.05535990375944 0 0 0 +837 2 3 0.5564 34.873780058275806 39.29804634363621 4.419289163091052 0 0 0 +579 1 1 0 36.25896 1.231418842149169 0 0 0 0 +580 1 1 0 36.96992 0 0 0 0 0 +583 1 1 0 36.25896 3.694256526447507 0 0 0 0 +584 1 1 0 36.96992 2.462837684298338 0 0 0 0 +587 1 1 0 36.25896 6.157094210745845 0 0 0 0 +588 1 1 0 36.96992 4.925675368596676 0 0 0 0 +591 1 1 0 36.25896 8.619931895044184 0 0 0 0 +592 1 1 0 36.96992 7.388513052895014 0 0 0 0 +596 1 1 0 36.96992 9.851350737193352 0 0 0 0 +649 1 1 0 38.39184 0 0 0 0 0 +650 1 1 0 39.1028 1.231418842149169 0 0 0 0 +651 1 1 0 40.52472 1.231418842149169 0 0 0 0 +653 1 1 0 38.39184 2.462837684298338 0 0 0 0 +654 1 1 0 39.1028 3.694256526447507 0 0 0 0 +655 1 1 0 40.52472 3.694256526447507 0 0 0 0 +657 1 1 0 38.39184 4.925675368596676 0 0 0 0 +658 1 1 0 39.1028 6.157094210745845 0 0 0 0 +659 1 1 0 40.52472 6.157094210745845 0 0 0 0 +661 1 1 0 38.39184 7.388513052895014 0 0 0 0 +662 1 1 0 39.1028 8.619931895044184 0 0 0 0 +663 1 1 0 40.52472 8.619931895044184 0 0 0 0 +665 1 1 0 38.39184 9.851350737193352 0 0 0 0 +864 2 3 0.5564 38.72559977454883 6.453140217896254 3.9654022350817373 0 1 0 +885 2 3 0.5564 35.86457499683829 2.187926621046695 4.084712133041518 0 1 0 +891 2 3 0.5564 36.49290196320123 4.5825554857830815 2.340280303271688 0 1 0 +905 2 3 0.5564 35.6539726734068 6.533533581961909 4.2226103514317215 0 1 0 +847 2 2 -1.1128 38.31073636731568 9.297637163461909 3.018631746447206 0 1 0 +807 2 3 0.5564 39.93839438218238 3.380787594401584 8.070189977397536 0 1 0 +842 2 3 0.5564 40.4439801215969 3.4539357982168974 5.874913654515922 0 1 0 +806 2 3 0.5564 39.53388614087088 1.9224662216249124 8.030602383511098 0 1 0 +841 2 2 -1.1128 40.346631074078815 3.161275558289171 4.968764399811248 0 1 0 +848 2 3 0.5564 37.378243475312125 9.509492777618444 2.9761304825701878 0 1 0 +805 2 2 -1.1128 39.1879363509718 2.799773990143194 8.194559951043354 0 1 0 +862 2 2 -1.1128 39.527254402566676 6.871055409294266 3.6508699018474053 0 1 0 +808 2 2 -1.1128 40.9813125028353 6.491622655244695 6.1252186603712815 0 1 0 +863 2 3 0.5564 39.2982209112595 7.796620838566813 3.566577577839523 0 1 0 +906 2 3 0.5564 35.63016556188961 6.980217848903836 5.668916912294608 0 1 0 +803 2 3 0.5564 37.21046144155504 3.3547056748419672 8.44685444624274 0 1 0 +820 2 2 -1.1128 40.238058884519425 8.892908109209923 7.228256282347458 0 1 0 +813 2 3 0.5564 35.66411242895095 0.1828007460118728 7.039625445693748 0 1 0 +830 2 3 0.5564 37.461900361164744 5.761054225296827 7.339683551589981 0 1 0 +809 2 3 0.5564 40.143388183992 6.666539751684856 5.6968272273146985 0 1 0 +849 2 3 0.5564 38.545146461582334 9.064870760768706 2.1202418370825424 0 1 0 +814 2 2 -1.1128 40.748134171936435 0.7389880780512781 3.3949349561238815 0 1 0 +816 2 3 0.5564 40.34138668782936 1.5417691543993164 3.7210197692903493 0 1 0 +933 2 3 0.5564 38.42845468599284 3.199245505203782 4.980786350179616 0 1 0 +932 2 3 0.5564 37.36968971559904 3.309266240641299 6.057265875709786 0 1 0 +802 2 2 -1.1128 36.25679030038503 3.29601481677218 8.38941777770298 0 1 0 +931 2 2 -1.1128 37.542384613917065 2.9133905650069245 5.203046413341369 0 1 0 +907 2 2 -1.1128 35.578884551020806 9.573590646940167 3.2880229990945917 0 1 0 +831 2 3 0.5564 36.268287811817636 4.832138094401851 7.27407174097549 0 1 0 +804 2 3 0.5564 36.035479013673445 2.501960846901915 8.875969191698895 0 1 0 +904 2 2 -1.1128 35.40021179318659 7.265609687237741 4.784662067802107 0 1 0 +829 2 2 -1.1128 36.67463142628169 5.575159558617119 6.8279361567305 0 1 0 +890 2 3 0.5564 35.51445085753465 3.6096863189422184 2.96322151266684 0 1 0 +919 2 2 -1.1128 40.013239321978745 0.15668706717705305 7.440776242049551 0 1 0 +908 2 3 0.5564 35.58368296090604 8.875183376627756 3.9425735956748125 0 1 0 +800 2 3 0.5564 37.74677816296982 0.734680968209546 5.402507033516551 0 1 0 +859 2 2 -1.1128 40.622879392981964 10.272720036648469 4.720042613666213 0 1 0 +861 2 3 0.5564 39.78296055209543 10.382230179324548 4.274198380882334 0 1 0 +889 2 2 -1.1128 35.68276124895589 4.5449882413929235 2.8487022953494807 0 1 0 +860 2 3 0.5564 40.42792864795578 9.700111278266009 5.461896012943214 0 1 0 +822 2 3 0.5564 40.522133068490525 8.019471778966093 6.958729128356608 0 1 0 +821 2 3 0.5564 40.47731496825091 8.948235047845442 8.153419981025246 0 1 0 +595 1 1 0 36.25896 11.082769579342521 0 0 0 0 +599 1 1 0 36.25896 13.545607263640859 0 0 0 0 +600 1 1 0 36.96992 12.31418842149169 0 0 0 0 +603 1 1 0 36.25896 16.008444947939196 0 0 0 0 +604 1 1 0 36.96992 14.777026105790029 0 0 0 0 +607 1 1 0 36.25896 18.471282632237532 0 0 0 0 +608 1 1 0 36.96992 17.239863790088364 0 0 0 0 +611 1 1 0 36.25896 20.93412031653587 0 0 0 0 +612 1 1 0 36.96992 19.702701474386703 0 0 0 0 +666 1 1 0 39.1028 11.082769579342521 0 0 0 0 +667 1 1 0 40.52472 11.082769579342521 0 0 0 0 +669 1 1 0 38.39184 12.31418842149169 0 0 0 0 +670 1 1 0 39.1028 13.545607263640859 0 0 0 0 +671 1 1 0 40.52472 13.545607263640859 0 0 0 0 +673 1 1 0 38.39184 14.777026105790029 0 0 0 0 +674 1 1 0 39.1028 16.008444947939196 0 0 0 0 +675 1 1 0 40.52472 16.008444947939196 0 0 0 0 +677 1 1 0 38.39184 17.239863790088364 0 0 0 0 +678 1 1 0 39.1028 18.471282632237532 0 0 0 0 +679 1 1 0 40.52472 18.471282632237532 0 0 0 0 +681 1 1 0 38.39184 19.702701474386703 0 0 0 0 +682 1 1 0 39.1028 20.93412031653587 0 0 0 0 +683 1 1 0 40.52472 20.93412031653587 0 0 0 0 +615 1 1 0 36.25896 23.39695800083421 0 0 0 0 +616 1 1 0 36.96992 22.165539158685043 0 0 0 0 +619 1 1 0 36.25896 25.859795685132546 0 0 0 0 +620 1 1 0 36.96992 24.62837684298338 0 0 0 0 +623 1 1 0 36.25896 28.322633369430886 0 0 0 0 +624 1 1 0 36.96992 27.091214527281718 0 0 0 0 +627 1 1 0 36.25896 30.785471053729225 0 0 0 0 +628 1 1 0 36.96992 29.554052211580057 0 0 0 0 +632 1 1 0 36.96992 32.01688989587839 0 0 0 0 +685 1 1 0 38.39184 22.165539158685043 0 0 0 0 +686 1 1 0 39.1028 23.39695800083421 0 0 0 0 +687 1 1 0 40.52472 23.39695800083421 0 0 0 0 +689 1 1 0 38.39184 24.62837684298338 0 0 0 0 +690 1 1 0 39.1028 25.859795685132546 0 0 0 0 +691 1 1 0 40.52472 25.859795685132546 0 0 0 0 +693 1 1 0 38.39184 27.091214527281718 0 0 0 0 +694 1 1 0 39.1028 28.322633369430886 0 0 0 0 +695 1 1 0 40.52472 28.322633369430886 0 0 0 0 +697 1 1 0 38.39184 29.554052211580057 0 0 0 0 +698 1 1 0 39.1028 30.785471053729225 0 0 0 0 +699 1 1 0 40.52472 30.785471053729225 0 0 0 0 +701 1 1 0 38.39184 32.01688989587839 0 0 0 0 +631 1 1 0 36.25896 33.24830873802756 0 0 0 0 +635 1 1 0 36.25896 35.711146422325896 0 0 0 0 +636 1 1 0 36.96992 34.47972758017673 0 0 0 0 +639 1 1 0 36.25896 38.17398410662424 0 0 0 0 +640 1 1 0 36.96992 36.94256526447507 0 0 0 0 +643 1 1 0 36.25896 40.636821790922575 0 0 0 0 +644 1 1 0 36.96992 39.40540294877341 0 0 0 0 +647 1 1 0 36.25896 43.09965947522091 0 0 0 0 +648 1 1 0 36.96992 41.86824063307174 0 0 0 0 +702 1 1 0 39.1028 33.24830873802756 0 0 0 0 +703 1 1 0 40.52472 33.24830873802756 0 0 0 0 +705 1 1 0 38.39184 34.47972758017673 0 0 0 0 +706 1 1 0 39.1028 35.711146422325896 0 0 0 0 +707 1 1 0 40.52472 35.711146422325896 0 0 0 0 +709 1 1 0 38.39184 36.94256526447507 0 0 0 0 +710 1 1 0 39.1028 38.17398410662424 0 0 0 0 +711 1 1 0 40.52472 38.17398410662424 0 0 0 0 +713 1 1 0 38.39184 39.40540294877341 0 0 0 0 +714 1 1 0 39.1028 40.636821790922575 0 0 0 0 +715 1 1 0 40.52472 40.636821790922575 0 0 0 0 +717 1 1 0 38.39184 41.86824063307174 0 0 0 0 +718 1 1 0 39.1028 43.09965947522091 0 0 0 0 +719 1 1 0 40.52472 43.09965947522091 0 0 0 0 +801 2 3 0.5564 37.548308436970686 43.56537533039196 5.365704432988823 0 0 0 +852 2 3 0.5564 38.88919502047367 42.042424135970684 3.6087789454249384 0 0 0 +876 2 3 0.5564 36.695468476045846 41.81307318973102 4.654847654027673 0 0 0 +851 2 3 0.5564 39.88056712847529 43.079060421379005 3.124565190962247 0 0 0 +836 2 3 0.5564 35.55710562397264 39.6409654643291 3.11262603757073 0 0 0 +874 2 2 -1.1128 37.156592548770114 42.42602324299549 4.082231251420106 0 0 0 +875 2 3 0.5564 36.4628015962606 42.8541504174728 3.580640511788261 0 0 0 +850 2 2 -1.1128 39.74740412124872 42.13377480969944 3.1948153248505924 0 0 0 +920 2 3 0.5564 40.541519697736526 43.81546496276574 7.010468244614621 0 0 0 +921 2 3 0.5564 39.11034070400223 44.265151888276336 7.21395020009192 0 0 0 +799 2 2 -1.1128 37.54782393045426 44.314597322511524 5.9614390867350435 0 0 0 +652 1 1 0 41.23568 0 0 0 0 0 +656 1 1 0 41.23568 2.462837684298338 0 0 0 0 +660 1 1 0 41.23568 4.925675368596676 0 0 0 0 +664 1 1 0 41.23568 7.388513052895014 0 0 0 0 +668 1 1 0 41.23568 9.851350737193352 0 0 0 0 +721 1 1 0 42.6576 0 0 0 0 0 +722 1 1 0 43.36856 1.231418842149169 0 0 0 0 +723 1 1 0 44.79048 1.231418842149169 0 0 0 0 +724 1 1 0 45.50144 0 0 0 0 0 +725 1 1 0 42.6576 2.462837684298338 0 0 0 0 +726 1 1 0 43.36856 3.694256526447507 0 0 0 0 +727 1 1 0 44.79048 3.694256526447507 0 0 0 0 +728 1 1 0 45.50144 2.462837684298338 0 0 0 0 +729 1 1 0 42.6576 4.925675368596676 0 0 0 0 +730 1 1 0 43.36856 6.157094210745845 0 0 0 0 +731 1 1 0 44.79048 6.157094210745845 0 0 0 0 +732 1 1 0 45.50144 4.925675368596676 0 0 0 0 +733 1 1 0 42.6576 7.388513052895014 0 0 0 0 +734 1 1 0 43.36856 8.619931895044184 0 0 0 0 +735 1 1 0 44.79048 8.619931895044184 0 0 0 0 +736 1 1 0 45.50144 7.388513052895014 0 0 0 0 +737 1 1 0 42.6576 9.851350737193352 0 0 0 0 +740 1 1 0 45.50144 9.851350737193352 0 0 0 0 +855 2 3 0.5564 42.60570890502672 6.754108104519662 3.2778996089299444 0 1 0 +853 2 2 -1.1128 42.099480757637274 5.9504482420758835 3.3966273472818673 0 1 0 +924 2 3 0.5564 42.55717296882286 9.17260477834803 2.5938337966266043 0 1 0 +796 2 2 -1.1128 42.77023484300884 3.2473201847921502 3.212925112248156 0 1 0 +902 2 3 0.5564 42.12839423169956 3.7289140838154062 7.1537282390574495 0 1 0 +903 2 3 0.5564 41.53585251071065 5.1118011663682905 7.322300070785221 0 1 0 +898 2 2 -1.1128 45.445001196506084 2.452551396966245 3.028403472579563 0 1 0 +797 2 3 0.5564 42.58443206962962 4.186306057729107 3.2089115332453373 0 1 0 +798 2 3 0.5564 43.71048122279908 3.189455512069421 3.38269391940839 0 1 0 +810 2 3 0.5564 41.63040595115056 6.5777864583716426 5.427015401612798 0 1 0 +854 2 3 0.5564 41.20236665318539 6.25112336337136 3.5415926908824034 0 1 0 +923 2 3 0.5564 42.32247135813611 9.521352146245636 4.048203548805301 0 1 0 +922 2 2 -1.1128 42.80519254575484 8.918478791891543 3.4827315727519106 0 1 0 +900 2 3 0.5564 45.15285956979833 1.5485234956341212 3.145105564354613 0 1 0 +899 2 3 0.5564 46.07339231136837 2.4105339689072443 2.3075759749099993 0 1 0 +901 2 2 -1.1128 41.44718299707816 4.208196261290198 7.625398774411962 0 1 0 +815 2 3 0.5564 41.32793113560261 1.0321378043039096 2.6919903566852 0 1 0 +843 2 3 0.5564 41.07940607864339 3.567038821973523 4.505483562010162 0 1 0 +672 1 1 0 41.23568 12.31418842149169 0 0 0 0 +676 1 1 0 41.23568 14.777026105790029 0 0 0 0 +680 1 1 0 41.23568 17.239863790088364 0 0 0 0 +684 1 1 0 41.23568 19.702701474386703 0 0 0 0 +738 1 1 0 43.36856 11.082769579342521 0 0 0 0 +739 1 1 0 44.79048 11.082769579342521 0 0 0 0 +741 1 1 0 42.6576 12.31418842149169 0 0 0 0 +742 1 1 0 43.36856 13.545607263640859 0 0 0 0 +743 1 1 0 44.79048 13.545607263640859 0 0 0 0 +744 1 1 0 45.50144 12.31418842149169 0 0 0 0 +745 1 1 0 42.6576 14.777026105790029 0 0 0 0 +746 1 1 0 43.36856 16.008444947939196 0 0 0 0 +747 1 1 0 44.79048 16.008444947939196 0 0 0 0 +748 1 1 0 45.50144 14.777026105790029 0 0 0 0 +749 1 1 0 42.6576 17.239863790088364 0 0 0 0 +750 1 1 0 43.36856 18.471282632237532 0 0 0 0 +751 1 1 0 44.79048 18.471282632237532 0 0 0 0 +752 1 1 0 45.50144 17.239863790088364 0 0 0 0 +753 1 1 0 42.6576 19.702701474386703 0 0 0 0 +754 1 1 0 43.36856 20.93412031653587 0 0 0 0 +755 1 1 0 44.79048 20.93412031653587 0 0 0 0 +756 1 1 0 45.50144 19.702701474386703 0 0 0 0 +688 1 1 0 41.23568 22.165539158685043 0 0 0 0 +692 1 1 0 41.23568 24.62837684298338 0 0 0 0 +696 1 1 0 41.23568 27.091214527281718 0 0 0 0 +700 1 1 0 41.23568 29.554052211580057 0 0 0 0 +704 1 1 0 41.23568 32.01688989587839 0 0 0 0 +757 1 1 0 42.6576 22.165539158685043 0 0 0 0 +758 1 1 0 43.36856 23.39695800083421 0 0 0 0 +759 1 1 0 44.79048 23.39695800083421 0 0 0 0 +760 1 1 0 45.50144 22.165539158685043 0 0 0 0 +761 1 1 0 42.6576 24.62837684298338 0 0 0 0 +762 1 1 0 43.36856 25.859795685132546 0 0 0 0 +763 1 1 0 44.79048 25.859795685132546 0 0 0 0 +764 1 1 0 45.50144 24.62837684298338 0 0 0 0 +765 1 1 0 42.6576 27.091214527281718 0 0 0 0 +766 1 1 0 43.36856 28.322633369430886 0 0 0 0 +767 1 1 0 44.79048 28.322633369430886 0 0 0 0 +768 1 1 0 45.50144 27.091214527281718 0 0 0 0 +769 1 1 0 42.6576 29.554052211580057 0 0 0 0 +770 1 1 0 43.36856 30.785471053729225 0 0 0 0 +771 1 1 0 44.79048 30.785471053729225 0 0 0 0 +772 1 1 0 45.50144 29.554052211580057 0 0 0 0 +773 1 1 0 42.6576 32.01688989587839 0 0 0 0 +776 1 1 0 45.50144 32.01688989587839 0 0 0 0 +708 1 1 0 41.23568 34.47972758017673 0 0 0 0 +712 1 1 0 41.23568 36.94256526447507 0 0 0 0 +716 1 1 0 41.23568 39.40540294877341 0 0 0 0 +720 1 1 0 41.23568 41.86824063307174 0 0 0 0 +774 1 1 0 43.36856 33.24830873802756 0 0 0 0 +775 1 1 0 44.79048 33.24830873802756 0 0 0 0 +777 1 1 0 42.6576 34.47972758017673 0 0 0 0 +778 1 1 0 43.36856 35.711146422325896 0 0 0 0 +779 1 1 0 44.79048 35.711146422325896 0 0 0 0 +780 1 1 0 45.50144 34.47972758017673 0 0 0 0 +781 1 1 0 42.6576 36.94256526447507 0 0 0 0 +782 1 1 0 43.36856 38.17398410662424 0 0 0 0 +783 1 1 0 44.79048 38.17398410662424 0 0 0 0 +784 1 1 0 45.50144 36.94256526447507 0 0 0 0 +785 1 1 0 42.6576 39.40540294877341 0 0 0 0 +786 1 1 0 43.36856 40.636821790922575 0 0 0 0 +787 1 1 0 44.79048 40.636821790922575 0 0 0 0 +788 1 1 0 45.50144 39.40540294877341 0 0 0 0 +789 1 1 0 42.6576 41.86824063307174 0 0 0 0 +790 1 1 0 43.36856 43.09965947522091 0 0 0 0 +791 1 1 0 44.79048 43.09965947522091 0 0 0 0 +792 1 1 0 45.50144 41.86824063307174 0 0 0 0 +871 2 2 -1.1128 42.43621342090696 41.361777660606826 3.5286311215230155 0 0 0 +910 2 2 -1.1128 44.00261269418429 44.009231456650014 3.7548439135777425 0 0 0 +873 2 3 0.5564 42.81116163142683 40.8806399438352 2.7909638607684895 0 0 0 +912 2 3 0.5564 44.01512081357764 43.199784996149646 3.244083663427368 0 0 0 +872 2 3 0.5564 41.50534987825062 41.436128256982094 3.318397554899502 0 0 0 +869 2 3 0.5564 41.92696097428322 42.44540495044042 4.918533220471727 0 0 0 +868 2 2 -1.1128 41.602312218152235 43.15319449082845 5.475195560073079 0 0 0 +870 2 3 0.5564 41.17840173459901 43.7603473856229 4.8686487491511015 0 0 0 +911 2 3 0.5564 43.2397024819597 43.9207537163753 4.326134358669964 0 0 0 + +Velocities + +1 0 0 0 +2 0 0 0 +3 0 0 0 +4 0 0 0 +5 0 0 0 +6 0 0 0 +7 0 0 0 +8 0 0 0 +9 0 0 0 +10 0 0 0 +11 0 0 0 +12 0 0 0 +13 0 0 0 +14 0 0 0 +15 0 0 0 +16 0 0 0 +17 0 0 0 +20 0 0 0 +73 0 0 0 +74 0 0 0 +77 0 0 0 +78 0 0 0 +81 0 0 0 +82 0 0 0 +85 0 0 0 +86 0 0 0 +89 0 0 0 +18 0 0 0 +19 0 0 0 +21 0 0 0 +22 0 0 0 +23 0 0 0 +24 0 0 0 +25 0 0 0 +26 0 0 0 +27 0 0 0 +28 0 0 0 +29 0 0 0 +30 0 0 0 +31 0 0 0 +32 0 0 0 +33 0 0 0 +34 0 0 0 +35 0 0 0 +36 0 0 0 +90 0 0 0 +93 0 0 0 +94 0 0 0 +97 0 0 0 +98 0 0 0 +101 0 0 0 +102 0 0 0 +105 0 0 0 +106 0 0 0 +37 0 0 0 +38 0 0 0 +39 0 0 0 +40 0 0 0 +41 0 0 0 +42 0 0 0 +43 0 0 0 +44 0 0 0 +45 0 0 0 +46 0 0 0 +47 0 0 0 +48 0 0 0 +49 0 0 0 +50 0 0 0 +51 0 0 0 +52 0 0 0 +53 0 0 0 +56 0 0 0 +109 0 0 0 +110 0 0 0 +113 0 0 0 +114 0 0 0 +117 0 0 0 +118 0 0 0 +121 0 0 0 +122 0 0 0 +125 0 0 0 +54 0 0 0 +55 0 0 0 +57 0 0 0 +58 0 0 0 +59 0 0 0 +60 0 0 0 +61 0 0 0 +62 0 0 0 +63 0 0 0 +64 0 0 0 +65 0 0 0 +66 0 0 0 +67 0 0 0 +68 0 0 0 +69 0 0 0 +70 0 0 0 +71 0 0 0 +72 0 0 0 +126 0 0 0 +129 0 0 0 +130 0 0 0 +133 0 0 0 +134 0 0 0 +137 0 0 0 +138 0 0 0 +141 0 0 0 +142 0 0 0 +75 0 0 0 +76 0 0 0 +79 0 0 0 +80 0 0 0 +83 0 0 0 +84 0 0 0 +87 0 0 0 +88 0 0 0 +92 0 0 0 +145 0 0 0 +146 0 0 0 +147 0 0 0 +148 0 0 0 +149 0 0 0 +150 0 0 0 +151 0 0 0 +152 0 0 0 +153 0 0 0 +154 0 0 0 +155 0 0 0 +156 0 0 0 +157 0 0 0 +158 0 0 0 +159 0 0 0 +160 0 0 0 +161 0 0 0 +164 0 0 0 +91 0 0 0 +95 0 0 0 +96 0 0 0 +99 0 0 0 +100 0 0 0 +103 0 0 0 +104 0 0 0 +107 0 0 0 +108 0 0 0 +162 0 0 0 +163 0 0 0 +165 0 0 0 +166 0 0 0 +167 0 0 0 +168 0 0 0 +169 0 0 0 +170 0 0 0 +171 0 0 0 +172 0 0 0 +173 0 0 0 +174 0 0 0 +175 0 0 0 +176 0 0 0 +177 0 0 0 +178 0 0 0 +179 0 0 0 +180 0 0 0 +111 0 0 0 +112 0 0 0 +115 0 0 0 +116 0 0 0 +119 0 0 0 +120 0 0 0 +123 0 0 0 +124 0 0 0 +128 0 0 0 +181 0 0 0 +182 0 0 0 +183 0 0 0 +184 0 0 0 +185 0 0 0 +186 0 0 0 +187 0 0 0 +188 0 0 0 +189 0 0 0 +190 0 0 0 +191 0 0 0 +192 0 0 0 +193 0 0 0 +194 0 0 0 +195 0 0 0 +196 0 0 0 +197 0 0 0 +200 0 0 0 +127 0 0 0 +131 0 0 0 +132 0 0 0 +135 0 0 0 +136 0 0 0 +139 0 0 0 +140 0 0 0 +143 0 0 0 +144 0 0 0 +198 0 0 0 +199 0 0 0 +201 0 0 0 +202 0 0 0 +203 0 0 0 +204 0 0 0 +205 0 0 0 +206 0 0 0 +207 0 0 0 +208 0 0 0 +209 0 0 0 +210 0 0 0 +211 0 0 0 +212 0 0 0 +213 0 0 0 +214 0 0 0 +215 0 0 0 +216 0 0 0 +217 0 0 0 +218 0 0 0 +219 0 0 0 +220 0 0 0 +221 0 0 0 +222 0 0 0 +223 0 0 0 +224 0 0 0 +225 0 0 0 +226 0 0 0 +227 0 0 0 +228 0 0 0 +229 0 0 0 +230 0 0 0 +231 0 0 0 +232 0 0 0 +233 0 0 0 +236 0 0 0 +289 0 0 0 +293 0 0 0 +297 0 0 0 +301 0 0 0 +305 0 0 0 +234 0 0 0 +235 0 0 0 +237 0 0 0 +238 0 0 0 +239 0 0 0 +240 0 0 0 +241 0 0 0 +242 0 0 0 +243 0 0 0 +244 0 0 0 +245 0 0 0 +246 0 0 0 +247 0 0 0 +248 0 0 0 +249 0 0 0 +250 0 0 0 +251 0 0 0 +252 0 0 0 +309 0 0 0 +313 0 0 0 +317 0 0 0 +321 0 0 0 +253 0 0 0 +254 0 0 0 +255 0 0 0 +256 0 0 0 +257 0 0 0 +258 0 0 0 +259 0 0 0 +260 0 0 0 +261 0 0 0 +262 0 0 0 +263 0 0 0 +264 0 0 0 +265 0 0 0 +266 0 0 0 +267 0 0 0 +268 0 0 0 +269 0 0 0 +272 0 0 0 +325 0 0 0 +329 0 0 0 +333 0 0 0 +337 0 0 0 +341 0 0 0 +270 0 0 0 +271 0 0 0 +273 0 0 0 +274 0 0 0 +275 0 0 0 +276 0 0 0 +277 0 0 0 +278 0 0 0 +279 0 0 0 +280 0 0 0 +281 0 0 0 +282 0 0 0 +283 0 0 0 +284 0 0 0 +285 0 0 0 +286 0 0 0 +287 0 0 0 +288 0 0 0 +345 0 0 0 +349 0 0 0 +353 0 0 0 +357 0 0 0 +290 0 0 0 +291 0 0 0 +292 0 0 0 +294 0 0 0 +295 0 0 0 +296 0 0 0 +298 0 0 0 +299 0 0 0 +300 0 0 0 +302 0 0 0 +303 0 0 0 +304 0 0 0 +308 0 0 0 +361 0 0 0 +362 0 0 0 +365 0 0 0 +366 0 0 0 +369 0 0 0 +370 0 0 0 +373 0 0 0 +374 0 0 0 +377 0 0 0 +306 0 0 0 +307 0 0 0 +310 0 0 0 +311 0 0 0 +312 0 0 0 +314 0 0 0 +315 0 0 0 +316 0 0 0 +318 0 0 0 +319 0 0 0 +320 0 0 0 +322 0 0 0 +323 0 0 0 +324 0 0 0 +378 0 0 0 +381 0 0 0 +382 0 0 0 +385 0 0 0 +386 0 0 0 +389 0 0 0 +390 0 0 0 +393 0 0 0 +394 0 0 0 +326 0 0 0 +327 0 0 0 +328 0 0 0 +330 0 0 0 +331 0 0 0 +332 0 0 0 +334 0 0 0 +335 0 0 0 +336 0 0 0 +338 0 0 0 +339 0 0 0 +340 0 0 0 +344 0 0 0 +397 0 0 0 +398 0 0 0 +401 0 0 0 +402 0 0 0 +405 0 0 0 +406 0 0 0 +409 0 0 0 +410 0 0 0 +413 0 0 0 +342 0 0 0 +343 0 0 0 +346 0 0 0 +347 0 0 0 +348 0 0 0 +350 0 0 0 +351 0 0 0 +352 0 0 0 +354 0 0 0 +355 0 0 0 +356 0 0 0 +358 0 0 0 +359 0 0 0 +360 0 0 0 +414 0 0 0 +417 0 0 0 +418 0 0 0 +421 0 0 0 +422 0 0 0 +425 0 0 0 +426 0 0 0 +429 0 0 0 +430 0 0 0 +363 0 0 0 +364 0 0 0 +367 0 0 0 +368 0 0 0 +371 0 0 0 +372 0 0 0 +375 0 0 0 +376 0 0 0 +380 0 0 0 +433 0 0 0 +434 0 0 0 +435 0 0 0 +436 0 0 0 +437 0 0 0 +438 0 0 0 +439 0 0 0 +440 0 0 0 +441 0 0 0 +442 0 0 0 +443 0 0 0 +444 0 0 0 +445 0 0 0 +446 0 0 0 +447 0 0 0 +448 0 0 0 +449 0 0 0 +452 0 0 0 +824 23.28678663838591 -19.695178733121715 -4.712860628654516 +882 -7.0610581976405244 16.44204311186104 -4.175586130223243 +915 5.458359862786789 12.338077912032869 3.646984172142374 +839 20.392115541402525 21.839207526251702 -29.285410530315588 +880 -1.6972489953530285 5.884325737897911 -5.109687018230828 +897 -0.5612899831289091 6.907522350424367 -17.06603259626599 +881 -3.29469084908246 18.230178486719424 -2.0874433657999796 +840 0.3491624797675958 -9.4770564186721 5.993889540912456 +823 -2.4113508906287486 0.7060826232690176 4.591531586272169 +825 -9.503739029582237 10.088287372649603 1.9260324522526424 +838 -4.206308232163817 2.7689815350821445 -3.2345774478153677 +918 5.963097489077942 -5.811799881204121 -1.1246744751170932 +895 -3.6065546286281265 3.360807936038344 -2.5135837850671177 +913 -3.9429603880542876 -3.803003714965937 4.88513733901858 +896 7.160890299407335 0.32762830929124437 -20.137386051219497 +379 0 0 0 +383 0 0 0 +384 0 0 0 +387 0 0 0 +388 0 0 0 +391 0 0 0 +392 0 0 0 +395 0 0 0 +396 0 0 0 +450 0 0 0 +451 0 0 0 +453 0 0 0 +454 0 0 0 +455 0 0 0 +456 0 0 0 +457 0 0 0 +458 0 0 0 +459 0 0 0 +460 0 0 0 +461 0 0 0 +462 0 0 0 +463 0 0 0 +464 0 0 0 +465 0 0 0 +466 0 0 0 +467 0 0 0 +468 0 0 0 +399 0 0 0 +400 0 0 0 +403 0 0 0 +404 0 0 0 +407 0 0 0 +408 0 0 0 +411 0 0 0 +412 0 0 0 +416 0 0 0 +469 0 0 0 +470 0 0 0 +471 0 0 0 +472 0 0 0 +473 0 0 0 +474 0 0 0 +475 0 0 0 +476 0 0 0 +477 0 0 0 +478 0 0 0 +479 0 0 0 +480 0 0 0 +481 0 0 0 +482 0 0 0 +483 0 0 0 +484 0 0 0 +485 0 0 0 +488 0 0 0 +415 0 0 0 +419 0 0 0 +420 0 0 0 +423 0 0 0 +424 0 0 0 +427 0 0 0 +428 0 0 0 +431 0 0 0 +432 0 0 0 +486 0 0 0 +487 0 0 0 +489 0 0 0 +490 0 0 0 +491 0 0 0 +492 0 0 0 +493 0 0 0 +494 0 0 0 +495 0 0 0 +496 0 0 0 +497 0 0 0 +498 0 0 0 +499 0 0 0 +500 0 0 0 +501 0 0 0 +502 0 0 0 +503 0 0 0 +504 0 0 0 +916 2.1969507203442245 -1.4352986791463374 -7.127919603909629 +917 11.826235663356204 14.279824537641929 -14.280083496635585 +505 0 0 0 +506 0 0 0 +507 0 0 0 +508 0 0 0 +509 0 0 0 +510 0 0 0 +511 0 0 0 +512 0 0 0 +513 0 0 0 +514 0 0 0 +515 0 0 0 +516 0 0 0 +517 0 0 0 +518 0 0 0 +519 0 0 0 +520 0 0 0 +521 0 0 0 +524 0 0 0 +577 0 0 0 +578 0 0 0 +581 0 0 0 +582 0 0 0 +585 0 0 0 +586 0 0 0 +589 0 0 0 +590 0 0 0 +593 0 0 0 +817 1.6133973243890818 0.09544910649802017 -2.82837163408008 +934 -0.7137103646976727 -3.722196372187516 0.848848803609948 +844 -1.412310995403245 2.5213507567859863 -4.599202803630543 +865 8.862935798755592 -1.7466754230232333 -1.6569510007225825 +926 -4.119692818575567 8.294228711700969 -32.74811918647688 +936 -15.928953261034998 -9.92364110983116 -15.23435729552565 +845 -7.482059146842958 -2.336334839582908 -12.584395592557943 +819 19.704188351794787 13.480076284531094 -16.836845023051307 +884 -5.8411676590434105 -3.4674785948480853 3.373261182910667 +928 -0.47949465869401636 4.8766140418593915 -1.7082902202551018 +832 3.7664949439970346 -7.725237251790142 2.249127795467372 +866 8.574128387623029 11.87092357709237 -33.55660077300949 +879 2.397970035203643 -1.0067012033099316 -24.55246411236801 +929 3.276394804624606 -17.02257780299615 0.9984492433600977 +935 20.101385093495328 5.113530565709303 -4.402939514605331 +909 -4.28073098421694 -15.637815198236153 -13.025293876950634 +846 -12.564589941629468 -6.4025051268954645 -20.75775453419462 +867 8.983700225517605 -3.390103398382499 10.693415861649115 +914 -2.2270563485919563 -24.131906542363726 6.875944405629472 +818 0.2383020958130696 -5.676983900196928 -7.219651526329348 +793 5.148041806008255 2.984645492151128 3.4961269673039586 +833 -0.6438138903502075 -2.2828874172817644 -2.0720922776886743 +834 10.612584098261342 -7.3667177513881885 16.15587930450157 +930 6.00984818290816 8.246158764929453 -15.698501664737071 +883 -3.3507225248985764 -0.5583884018684485 4.849649083643576 +794 3.908344161677918 -24.184551279453736 8.492626116154728 +795 8.894549364978065 12.946246804004156 12.17949248871838 +522 0 0 0 +523 0 0 0 +525 0 0 0 +526 0 0 0 +527 0 0 0 +528 0 0 0 +529 0 0 0 +530 0 0 0 +531 0 0 0 +532 0 0 0 +533 0 0 0 +534 0 0 0 +535 0 0 0 +536 0 0 0 +537 0 0 0 +538 0 0 0 +539 0 0 0 +540 0 0 0 +594 0 0 0 +597 0 0 0 +598 0 0 0 +601 0 0 0 +602 0 0 0 +605 0 0 0 +606 0 0 0 +609 0 0 0 +610 0 0 0 +541 0 0 0 +542 0 0 0 +543 0 0 0 +544 0 0 0 +545 0 0 0 +546 0 0 0 +547 0 0 0 +548 0 0 0 +549 0 0 0 +550 0 0 0 +551 0 0 0 +552 0 0 0 +553 0 0 0 +554 0 0 0 +555 0 0 0 +556 0 0 0 +557 0 0 0 +560 0 0 0 +613 0 0 0 +614 0 0 0 +617 0 0 0 +618 0 0 0 +621 0 0 0 +622 0 0 0 +625 0 0 0 +626 0 0 0 +629 0 0 0 +558 0 0 0 +559 0 0 0 +561 0 0 0 +562 0 0 0 +563 0 0 0 +564 0 0 0 +565 0 0 0 +566 0 0 0 +567 0 0 0 +568 0 0 0 +569 0 0 0 +570 0 0 0 +571 0 0 0 +572 0 0 0 +573 0 0 0 +574 0 0 0 +575 0 0 0 +576 0 0 0 +630 0 0 0 +633 0 0 0 +634 0 0 0 +637 0 0 0 +638 0 0 0 +641 0 0 0 +642 0 0 0 +645 0 0 0 +646 0 0 0 +857 0.014723103701010352 19.617056339014884 16.55424143708416 +856 -0.643223754474494 5.776893808258414 1.1873537786475037 +892 -3.075450592140558 0.21721350023132013 -1.4569947460087087 +893 -16.397277523345814 -3.4380854612300413 0.6965615832113001 +886 -0.2961775166926003 1.3204871191677252 -6.423441607226728 +828 -5.723804354158924 -2.2689365841904983 2.5260940343682323 +887 0.8430831533311819 -13.339077650133666 15.172508195501921 +826 -4.448639032696121 -0.8915914080568843 2.3567943259561948 +827 1.718412324889533 -14.893863590144628 14.797129976414348 +894 -6.427973685028659 -12.558615271775233 -7.485451456789206 +925 8.402235075352133 3.407952177949016 -3.5053149045150525 +858 -6.427819874217524 -13.261042052865486 -2.844099672535822 +878 4.549175257644374 -9.190685290399665 7.233790964076811 +812 1.6130765364411193 6.523491914724538 -2.1666788533706773 +927 5.411595894339899 18.95778556645519 0.4163503598847362 +888 6.673800249844219 -4.147769988251276 11.562868346675096 +877 0.7642590168406848 -0.42640846170725205 -0.24362676533615443 +835 4.762512418319816 4.257619894363519 -2.633248633741173 +811 2.94897877928045 1.1358222911198308 3.501491126078737 +837 -25.574582055486644 8.173269863077355 -15.333432600063208 +579 0 0 0 +580 0 0 0 +583 0 0 0 +584 0 0 0 +587 0 0 0 +588 0 0 0 +591 0 0 0 +592 0 0 0 +596 0 0 0 +649 0 0 0 +650 0 0 0 +651 0 0 0 +653 0 0 0 +654 0 0 0 +655 0 0 0 +657 0 0 0 +658 0 0 0 +659 0 0 0 +661 0 0 0 +662 0 0 0 +663 0 0 0 +665 0 0 0 +864 18.10875991489158 -1.221818047957972 14.493518869719745 +885 -3.50759902491298 9.459430974379575 4.647666016780896 +891 1.2937876234992576 -13.218582770473045 1.8043374968280674 +905 -4.091578474774505 3.159726887798095 -1.8642051540811495 +847 13.821135507553436 3.78277650099749 -0.8935962180188131 +807 -2.855822557363695 -1.3802914256701821 1.3207757685673218 +842 -3.5610017924774 20.399114965452245 -9.059382158173541 +806 -4.05498634870798 -0.7854363713825808 -8.046995507898338 +841 2.77935600657832 0.33087027354111276 -3.276950737363777 +848 14.223073217510889 7.872740511148931 10.887767283489458 +805 -1.6775622324299977 -2.2096661714145456 4.5967537734138295 +862 5.242654019377736 5.918079707262924 -8.884230198450263 +808 -3.696957383720496 1.0048882207315841 -0.5768482173888145 +863 -1.8703493217333826 5.862886335539861 9.68692462574889 +906 18.26182603645302 7.175694562498453 -2.7522051758285015 +803 3.2862566934744275 -9.793076664879903 3.0089122195092575 +820 -6.318316424453873 -6.3876103453941235 -3.8277653578536937 +813 2.860647424855888 1.4990458438578118 3.0590515326924304 +830 17.528802909679435 -19.339237046941598 -20.741951943235076 +809 -1.7667991174728181 2.556579099847797 -3.7133211964009396 +849 -1.1901850692743416 -8.440379804790025 -1.6424701640814479 +814 1.1332861799827034 0.6093309476680691 1.6239157816953607 +816 8.576684394424559 3.76294659470765 3.1067139692854044 +933 3.343313506115779 -12.788319535305213 0.4254781025251201 +932 1.2123994730269427 3.3154650357069606 -3.334409286644367 +802 3.413872469336105 -1.1546266031788768 -7.788063759324826 +931 -1.4494894135693275 -0.007254181008071915 -2.3332218927708426 +907 -5.153001723767468 0.1363135393043927 2.075664750863472 +831 -10.004566446956199 14.6294729429816 -0.9646159688100753 +804 -7.991671584288851 -7.475452917857694 -23.323610756314213 +904 -7.100120239541285 -0.3942667752088697 1.4081501423590068 +829 1.9015007439507077 5.283166213121213 -5.6785558614538445 +890 -19.32307212346698 3.2014322404638675 -4.971981839089952 +919 -2.338652775866846 -1.6192256874434943 3.5872094229145635 +908 -4.506448801038724 7.6944348035494805 10.147202763194022 +800 0.525815621025557 0.8800480170316483 -0.20140766169559945 +859 -3.7638632187225913 -1.3301900297863984 -1.6857540996503018 +861 -1.300800867558945 -21.968770646198 -11.380968378191717 +889 -0.13291154686447318 0.408222226270759 0.5188896950022159 +860 2.8418653167563583 -10.860696318995991 -7.274081987407397 +822 18.555841947164804 1.3488795446530215 -2.57263197376979 +821 2.5914509962410404 6.1128885622856535 -6.891713022600967 +595 0 0 0 +599 0 0 0 +600 0 0 0 +603 0 0 0 +604 0 0 0 +607 0 0 0 +608 0 0 0 +611 0 0 0 +612 0 0 0 +666 0 0 0 +667 0 0 0 +669 0 0 0 +670 0 0 0 +671 0 0 0 +673 0 0 0 +674 0 0 0 +675 0 0 0 +677 0 0 0 +678 0 0 0 +679 0 0 0 +681 0 0 0 +682 0 0 0 +683 0 0 0 +615 0 0 0 +616 0 0 0 +619 0 0 0 +620 0 0 0 +623 0 0 0 +624 0 0 0 +627 0 0 0 +628 0 0 0 +632 0 0 0 +685 0 0 0 +686 0 0 0 +687 0 0 0 +689 0 0 0 +690 0 0 0 +691 0 0 0 +693 0 0 0 +694 0 0 0 +695 0 0 0 +697 0 0 0 +698 0 0 0 +699 0 0 0 +701 0 0 0 +631 0 0 0 +635 0 0 0 +636 0 0 0 +639 0 0 0 +640 0 0 0 +643 0 0 0 +644 0 0 0 +647 0 0 0 +648 0 0 0 +702 0 0 0 +703 0 0 0 +705 0 0 0 +706 0 0 0 +707 0 0 0 +709 0 0 0 +710 0 0 0 +711 0 0 0 +713 0 0 0 +714 0 0 0 +715 0 0 0 +717 0 0 0 +718 0 0 0 +719 0 0 0 +801 6.3791360737229175 -0.06294951897585185 6.275276534287049 +852 9.533204722301026 3.635358487275625 11.325241984676676 +876 -7.5288457960325195 10.343955685749071 9.174112903806698 +851 11.324630200416946 -5.3841269941632195 -4.331280522070834 +836 -18.948267184095485 3.059583577066092 -13.205211938026421 +874 0.11331962980175045 -2.6443097750575877 1.3904229166613291 +875 5.578453451251161 -1.707571521972893 -5.365721983984957 +850 3.508833846356138 -4.177464350024476 -2.929550119627118 +920 9.735651740617827 11.172654877683243 -1.520392490494708 +921 2.634342633192178 -7.473941525247307 -10.3819677968746 +799 2.480261876941381 2.6479286070540775 2.8757710276609134 +652 0 0 0 +656 0 0 0 +660 0 0 0 +664 0 0 0 +668 0 0 0 +721 0 0 0 +722 0 0 0 +723 0 0 0 +724 0 0 0 +725 0 0 0 +726 0 0 0 +727 0 0 0 +728 0 0 0 +729 0 0 0 +730 0 0 0 +731 0 0 0 +732 0 0 0 +733 0 0 0 +734 0 0 0 +735 0 0 0 +736 0 0 0 +737 0 0 0 +740 0 0 0 +855 -4.983418977664709 7.316762475632069 -4.804677515261691 +853 -0.9889242911612474 4.9363545378208835 -3.893215427287619 +924 24.809030366392236 12.938030894027968 -7.929148423342626 +796 -2.042486989230798 -1.6716889696169193 4.818040886059996 +902 -12.24631912078176 -9.296091792191639 -5.933828252367176 +903 14.861767381200762 0.646302630400826 8.128909247439392 +898 -2.268970865642067 0.19593504253976693 -1.7002095325194038 +797 13.389488449540423 1.304501878497851 -5.024765837418713 +798 -4.04938216085792 -15.534814466192707 11.193556197029825 +810 -3.4873315530660745 -26.291881956134898 -3.7360180315706857 +854 -0.050097723565420214 1.1979024312153128 9.895624196355202 +923 -20.553020845996645 -9.899327350049255 -9.819708647345967 +922 4.523293437546675 5.218998274954441 -4.49072202518129 +900 7.633861074709448 -2.2307704025903523 4.296521673635092 +899 -19.369173009793435 5.968253817215517 -16.94178229768782 +901 3.1298945853524573 1.0199579971809891 5.836464708883643 +815 12.880886365907195 -2.18582234580474 10.172206114924288 +843 3.8805061810272847 -6.900108272859447 -7.842804013717792 +672 0 0 0 +676 0 0 0 +680 0 0 0 +684 0 0 0 +738 0 0 0 +739 0 0 0 +741 0 0 0 +742 0 0 0 +743 0 0 0 +744 0 0 0 +745 0 0 0 +746 0 0 0 +747 0 0 0 +748 0 0 0 +749 0 0 0 +750 0 0 0 +751 0 0 0 +752 0 0 0 +753 0 0 0 +754 0 0 0 +755 0 0 0 +756 0 0 0 +688 0 0 0 +692 0 0 0 +696 0 0 0 +700 0 0 0 +704 0 0 0 +757 0 0 0 +758 0 0 0 +759 0 0 0 +760 0 0 0 +761 0 0 0 +762 0 0 0 +763 0 0 0 +764 0 0 0 +765 0 0 0 +766 0 0 0 +767 0 0 0 +768 0 0 0 +769 0 0 0 +770 0 0 0 +771 0 0 0 +772 0 0 0 +773 0 0 0 +776 0 0 0 +708 0 0 0 +712 0 0 0 +716 0 0 0 +720 0 0 0 +774 0 0 0 +775 0 0 0 +777 0 0 0 +778 0 0 0 +779 0 0 0 +780 0 0 0 +781 0 0 0 +782 0 0 0 +783 0 0 0 +784 0 0 0 +785 0 0 0 +786 0 0 0 +787 0 0 0 +788 0 0 0 +789 0 0 0 +790 0 0 0 +791 0 0 0 +792 0 0 0 +871 3.8388411617482983 2.1415774247586086 2.2282258014613365 +910 7.602860298670014 2.6393823107390926 0.5414737324680828 +873 20.507332409943604 5.51145846781714 8.496326839610182 +912 -3.629349712693535 23.337951853868613 -32.58198418026529 +872 4.080216979227207 -18.995820981792978 -6.328839221258122 +869 25.409329042660474 4.159096283589856 8.003159128696433 +868 -6.119380276761435 0.9901059131840709 -6.330598686020231 +870 -10.78856535095556 -17.561195466544348 -21.63165476286472 +911 14.291030359419361 -16.1359695519986 6.557863766321599 + +Bonds + +1 1 880 881 +2 1 880 882 +3 1 823 824 +4 1 823 825 +5 1 838 839 +6 1 838 840 +7 1 895 896 +8 1 895 897 +9 1 913 914 +10 1 913 915 +11 1 916 917 +12 1 916 918 +13 1 817 818 +14 1 817 819 +15 1 934 935 +16 1 934 936 +17 1 844 845 +18 1 844 846 +19 1 865 866 +20 1 865 867 +21 1 928 929 +22 1 928 930 +23 1 832 833 +24 1 832 834 +25 1 793 794 +26 1 793 795 +27 1 883 884 +28 1 883 885 +29 1 856 857 +30 1 856 858 +31 1 892 893 +32 1 892 894 +33 1 886 887 +34 1 886 888 +35 1 826 827 +36 1 826 828 +37 1 925 926 +38 1 925 927 +39 1 877 878 +40 1 877 879 +41 1 835 836 +42 1 835 837 +43 1 811 812 +44 1 811 813 +45 1 847 848 +46 1 847 849 +47 1 841 842 +48 1 841 843 +49 1 805 806 +50 1 805 807 +51 1 862 863 +52 1 862 864 +53 1 808 809 +54 1 808 810 +55 1 820 821 +56 1 820 822 +57 1 814 815 +58 1 814 816 +59 1 802 803 +60 1 802 804 +61 1 931 932 +62 1 931 933 +63 1 907 908 +64 1 907 909 +65 1 904 905 +66 1 904 906 +67 1 829 830 +68 1 829 831 +69 1 919 920 +70 1 919 921 +71 1 859 860 +72 1 859 861 +73 1 889 890 +74 1 889 891 +75 1 874 875 +76 1 874 876 +77 1 850 851 +78 1 850 852 +79 1 799 800 +80 1 799 801 +81 1 853 854 +82 1 853 855 +83 1 796 797 +84 1 796 798 +85 1 898 899 +86 1 898 900 +87 1 922 923 +88 1 922 924 +89 1 901 902 +90 1 901 903 +91 1 871 872 +92 1 871 873 +93 1 910 911 +94 1 910 912 +95 1 868 869 +96 1 868 870 + +Angles + +1 1 881 880 882 +2 1 824 823 825 +3 1 839 838 840 +4 1 896 895 897 +5 1 914 913 915 +6 1 917 916 918 +7 1 818 817 819 +8 1 935 934 936 +9 1 845 844 846 +10 1 866 865 867 +11 1 929 928 930 +12 1 833 832 834 +13 1 794 793 795 +14 1 884 883 885 +15 1 857 856 858 +16 1 893 892 894 +17 1 887 886 888 +18 1 827 826 828 +19 1 926 925 927 +20 1 878 877 879 +21 1 836 835 837 +22 1 812 811 813 +23 1 848 847 849 +24 1 842 841 843 +25 1 806 805 807 +26 1 863 862 864 +27 1 809 808 810 +28 1 821 820 822 +29 1 815 814 816 +30 1 803 802 804 +31 1 932 931 933 +32 1 908 907 909 +33 1 905 904 906 +34 1 830 829 831 +35 1 920 919 921 +36 1 860 859 861 +37 1 890 889 891 +38 1 875 874 876 +39 1 851 850 852 +40 1 800 799 801 +41 1 854 853 855 +42 1 797 796 798 +43 1 899 898 900 +44 1 923 922 924 +45 1 902 901 903 +46 1 872 871 873 +47 1 911 910 912 +48 1 869 868 870 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water b/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water new file mode 100644 index 0000000000..9fccbf733b --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water @@ -0,0 +1,51 @@ +# Initialization +units metal +boundary p p p +atom_style full +processors * * 1 # domain decomposition over x and y +read_data ./gra_water.data +mass 1 12.0107 # carbon mass (g/mole) +mass 2 15.9994 # oxygen mass (g/mole) +mass 3 1.008 # hydrogen mass (g/mole) +# Separate atom groups +group gr molecule 1 +group water molecule 2 +######################## Potential defition ############################## +# Interlayer potential +pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +#################################################################### +pair_coeff 1 1 none +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw # C-water +# bond and angle +bond_style harmonic +bond_coeff 1 0.0 0.9572 +angle_style harmonic +angle_coeff 1 0.0 104.52 +# define kspace calculation +kspace_style pppm/tip4p 1E-5 +# Neighbor update settings +neighbor 2.0 bin +neigh_modify every 1 delay 5 check yes page 1000000 one 100000 +#################################################################### +# Calculate pair energy +compute 1 all pair lj/cut/tip4p/long +compute 2 all pair ilp/water/2dm +compute wt water temp +variable TIP4P equal c_1 +variable EILP equal c_2 # total interlayer energy +variable temp_wt equal c_wt +############# Output ############## +thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt +thermo 100 +thermo_modify lost error + +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 + +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water.opt b/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water.opt new file mode 100644 index 0000000000..1b38ab6e6e --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water.opt @@ -0,0 +1,51 @@ +# Initialization +units metal +boundary p p p +atom_style full +processors * * 1 # domain decomposition over x and y +read_data ./gra_water.data +mass 1 12.0107 # carbon mass (g/mole) +mass 2 15.9994 # oxygen mass (g/mole) +mass 3 1.008 # hydrogen mass (g/mole) +# Separate atom groups +group gr molecule 1 +group water molecule 2 +######################## Potential defition ############################## +# Interlayer potential +pair_style hybrid/overlay ilp/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +#################################################################### +pair_coeff 1 1 none +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * ilp/water/2dm/opt COH.ILP C Ow Hw # C-water +# bond and angle +bond_style harmonic +bond_coeff 1 0.0 0.9572 +angle_style harmonic +angle_coeff 1 0.0 104.52 +# define kspace calculation +kspace_style pppm/tip4p 1E-5 +# Neighbor update settings +neighbor 2.0 bin +neigh_modify every 1 delay 5 check yes page 1000000 one 100000 +#################################################################### +# Calculate pair energy +compute 1 all pair lj/cut/tip4p/long +compute 2 all pair ilp/water/2dm/opt +compute wt water temp +variable TIP4P equal c_1 +variable EILP equal c_2 # total interlayer energy +variable temp_wt equal c_wt +############# Output ############## +thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt +thermo 100 +thermo_modify lost error + +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 + +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.1 b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.1 new file mode 100644 index 0000000000..6e13280f70 --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.1 @@ -0,0 +1,234 @@ +LAMMPS (23 Jun 2022) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Initialization +units metal +boundary p p p +atom_style full +processors * * 1 # domain decomposition over x and y +read_data ./gra_water.data +Reading data file ... + orthogonal box = (0 0 0) to (46.92336 44.331078 200) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 936 atoms + reading velocities ... + 936 velocities + scanning bonds ... + 2 = max bonds/atom + scanning angles ... + 1 = max angles/atom + reading bonds ... + 96 bonds + reading angles ... + 48 angles +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.005 seconds + read_data CPU = 0.020 seconds +mass 1 12.0107 # carbon mass (g/mole) +mass 2 15.9994 # oxygen mass (g/mole) +mass 3 1.008 # hydrogen mass (g/mole) +# Separate atom groups +group gr molecule 1 +792 atoms in group gr +group water molecule 2 +144 atoms in group water +######################## Potential defition ############################## +# Interlayer potential +pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +#################################################################### +pair_coeff 1 1 none +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw # C-water +Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +# bond and angle +bond_style harmonic +bond_coeff 1 0.0 0.9572 +angle_style harmonic +angle_coeff 1 0.0 104.52 +# define kspace calculation +kspace_style pppm/tip4p 1E-5 +# Neighbor update settings +neighbor 2.0 bin +neigh_modify every 1 delay 5 check yes page 1000000 one 100000 +#################################################################### +# Calculate pair energy +compute 1 all pair lj/cut/tip4p/long +compute 2 all pair ilp/water/2dm +compute wt water temp +variable TIP4P equal c_1 +variable EILP equal c_2 # total interlayer energy +variable temp_wt equal c_wt +############# Output ############## +thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt +thermo 100 +thermo_modify lost error + +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 + 0 = # of size 2 clusters + 0 = # of size 3 clusters + 0 = # of size 4 clusters + 48 = # of frozen angles + find clusters CPU = 0.001 seconds + +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 +@Article{Ouyang2018 + author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, + journal = {Nano Letters}, + volume = 18, + pages = {6009} + year = 2018, +} + +- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +@Article{Ouyang2021 + author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J. Chem. Theory Comput.}, + volume = 17, + pages = {7237–7245} + year = 2021, +} + +- ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 +@Article{Feng2023 + author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang}, + title = {Registry-Dependent Potential for Interfaces of Water with Graphene}, + journal = {J. Phys. Chem. C}, + volume = 127, + pages = {8704-8713} + year = 2023, +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +PPPM initialization ... + extracting TIP4P info from pair style + using 12-bit tables for long-range coulomb (../kspace.cpp:342) + G vector (1/distance) = 0.28684806 + grid = 25 24 80 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0001640931 + estimated relative force accuracy = 1.1395635e-05 + using single precision MKL FFT + 3d grid and FFT values/proc = 84320 48000 +WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 100000, page size: 1000000 + master list distance cutoff = 18 + ghost atom cutoff = 18 + binsize = 9, bins = 6 5 23 + 3 neighbor lists, perpetual/occasional/extra = 3 0 0 + (1) pair ilp/water/2dm, perpetual + attributes: full, newton on, ghost + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard + (2) pair lj/cut/tip4p/long, perpetual, skip from (3) + attributes: half, newton on + pair build: skip + stencil: none + bin: none + (3) neighbor class addition, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +SHAKE stats (type/ave/delta/count) on step 0 +Bond: 1 0.957201 2.19705e-06 96 +Angle: 1 104.52 0.000203056 48 +Per MPI rank memory allocation (min/avg/max) = 33.53 | 33.53 | 33.53 Mbytes + Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt + 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 +SHAKE stats (type/ave/delta/count) on step 100 +Bond: 1 0.9572 9.54949e-07 96 +Angle: 1 104.52 6.01522e-05 48 + 100 -17.494868 -20.796993 3.3021253 188.4955 -1.8981262 268.90898 +SHAKE stats (type/ave/delta/count) on step 200 +Bond: 1 0.9572 9.63922e-07 96 +Angle: 1 104.52 7.7021e-05 48 + 200 -17.486271 -21.194892 3.7086213 188.14561 -1.9871708 302.01203 +SHAKE stats (type/ave/delta/count) on step 300 +Bond: 1 0.9572 1.4264e-06 96 +Angle: 1 104.52 6.48393e-05 48 + 300 -17.502844 -20.993704 3.49086 188.23268 -1.8457229 284.27861 +SHAKE stats (type/ave/delta/count) on step 400 +Bond: 1 0.9572 1.33728e-06 96 +Angle: 1 104.52 7.6239e-05 48 + 400 -17.495287 -20.828353 3.3330658 188.48002 -1.8429075 271.42862 +SHAKE stats (type/ave/delta/count) on step 500 +Bond: 1 0.9572 1.14685e-06 96 +Angle: 1 104.52 8.58621e-05 48 + 500 -17.491435 -20.443044 2.9516084 188.7589 -1.8566335 240.36459 +SHAKE stats (type/ave/delta/count) on step 600 +Bond: 1 0.9572 9.17601e-07 96 +Angle: 1 104.52 8.24516e-05 48 + 600 -17.505684 -20.608457 3.1027731 188.72078 -1.9560796 252.67471 +SHAKE stats (type/ave/delta/count) on step 700 +Bond: 1 0.9572 9.50422e-07 96 +Angle: 1 104.52 5.62423e-05 48 + 700 -17.496703 -21.072663 3.5759596 188.2777 -1.9833956 291.20871 +SHAKE stats (type/ave/delta/count) on step 800 +Bond: 1 0.9572 1.15262e-06 96 +Angle: 1 104.52 7.02157e-05 48 + 800 -17.478623 -20.819504 3.3408809 188.37868 -1.9112996 272.06505 +SHAKE stats (type/ave/delta/count) on step 900 +Bond: 1 0.9572 9.14138e-07 96 +Angle: 1 104.52 6.98742e-05 48 + 900 -17.48086 -20.728495 3.2476349 188.59022 -1.8922102 264.47155 +SHAKE stats (type/ave/delta/count) on step 1000 +Bond: 1 0.9572 1.00586e-06 96 +Angle: 1 104.52 0.000111712 48 + 1000 -17.498465 -20.331545 2.8330804 188.87473 -1.812177 230.71225 +Loop time of 20.801 on 1 procs for 1000 steps with 936 atoms + +Performance: 4.154 ns/day, 5.778 hours/ns, 48.075 timesteps/s +99.9% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 16.429 | 16.429 | 16.429 | 0.0 | 78.98 +Bond | 0.0010991 | 0.0010991 | 0.0010991 | 0.0 | 0.01 +Kspace | 3.4769 | 3.4769 | 3.4769 | 0.0 | 16.72 +Neigh | 0.83359 | 0.83359 | 0.83359 | 0.0 | 4.01 +Comm | 0.028825 | 0.028825 | 0.028825 | 0.0 | 0.14 +Output | 0.00046349 | 0.00046349 | 0.00046349 | 0.0 | 0.00 +Modify | 0.01943 | 0.01943 | 0.01943 | 0.0 | 0.09 +Other | | 0.01154 | | | 0.06 + +Nlocal: 936 ave 936 max 936 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 5242 ave 5242 max 5242 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 431382 ave 431382 max 431382 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 431382 +Ave neighs/atom = 460.87821 +Ave special neighs/atom = 0.30769231 +Neighbor list builds = 28 +Dangerous builds = 0 +Total wall time: 0:00:21 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.4 b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.4 new file mode 100644 index 0000000000..078ca76e2e --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.4 @@ -0,0 +1,234 @@ +LAMMPS (23 Jun 2022) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Initialization +units metal +boundary p p p +atom_style full +processors * * 1 # domain decomposition over x and y +read_data ./gra_water.data +Reading data file ... + orthogonal box = (0 0 0) to (46.92336 44.331078 200) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 936 atoms + reading velocities ... + 936 velocities + scanning bonds ... + 2 = max bonds/atom + scanning angles ... + 1 = max angles/atom + reading bonds ... + 96 bonds + reading angles ... + 48 angles +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.003 seconds + read_data CPU = 0.018 seconds +mass 1 12.0107 # carbon mass (g/mole) +mass 2 15.9994 # oxygen mass (g/mole) +mass 3 1.008 # hydrogen mass (g/mole) +# Separate atom groups +group gr molecule 1 +792 atoms in group gr +group water molecule 2 +144 atoms in group water +######################## Potential defition ############################## +# Interlayer potential +pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +#################################################################### +pair_coeff 1 1 none +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw # C-water +Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +# bond and angle +bond_style harmonic +bond_coeff 1 0.0 0.9572 +angle_style harmonic +angle_coeff 1 0.0 104.52 +# define kspace calculation +kspace_style pppm/tip4p 1E-5 +# Neighbor update settings +neighbor 2.0 bin +neigh_modify every 1 delay 5 check yes page 1000000 one 100000 +#################################################################### +# Calculate pair energy +compute 1 all pair lj/cut/tip4p/long +compute 2 all pair ilp/water/2dm +compute wt water temp +variable TIP4P equal c_1 +variable EILP equal c_2 # total interlayer energy +variable temp_wt equal c_wt +############# Output ############## +thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt +thermo 100 +thermo_modify lost error + +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 + 0 = # of size 2 clusters + 0 = # of size 3 clusters + 0 = # of size 4 clusters + 48 = # of frozen angles + find clusters CPU = 0.001 seconds + +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 +@Article{Ouyang2018 + author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, + journal = {Nano Letters}, + volume = 18, + pages = {6009} + year = 2018, +} + +- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +@Article{Ouyang2021 + author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J. Chem. Theory Comput.}, + volume = 17, + pages = {7237–7245} + year = 2021, +} + +- ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 +@Article{Feng2023 + author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang}, + title = {Registry-Dependent Potential for Interfaces of Water with Graphene}, + journal = {J. Phys. Chem. C}, + volume = 127, + pages = {8704-8713} + year = 2023, +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +PPPM initialization ... + extracting TIP4P info from pair style + using 12-bit tables for long-range coulomb (../kspace.cpp:342) + G vector (1/distance) = 0.28684806 + grid = 25 24 80 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0001640931 + estimated relative force accuracy = 1.1395635e-05 + using single precision MKL FFT + 3d grid and FFT values/proc = 30685 12480 +WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 100000, page size: 1000000 + master list distance cutoff = 18 + ghost atom cutoff = 18 + binsize = 9, bins = 6 5 23 + 3 neighbor lists, perpetual/occasional/extra = 3 0 0 + (1) pair ilp/water/2dm, perpetual + attributes: full, newton on, ghost + pair build: full/bin/ghost + stencil: full/ghost/bin/3d + bin: standard + (2) pair lj/cut/tip4p/long, perpetual, skip from (3) + attributes: half, newton on + pair build: skip + stencil: none + bin: none + (3) neighbor class addition, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +SHAKE stats (type/ave/delta/count) on step 0 +Bond: 1 0.957201 2.19705e-06 96 +Angle: 1 104.52 0.000203056 48 +Per MPI rank memory allocation (min/avg/max) = 25.84 | 25.88 | 25.92 Mbytes + Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt + 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 +SHAKE stats (type/ave/delta/count) on step 100 +Bond: 1 0.9572 9.54949e-07 96 +Angle: 1 104.52 6.01522e-05 48 + 100 -17.494869 -20.796995 3.3021253 188.4955 -1.8981262 268.90898 +SHAKE stats (type/ave/delta/count) on step 200 +Bond: 1 0.9572 9.63922e-07 96 +Angle: 1 104.52 7.7021e-05 48 + 200 -17.48627 -21.194892 3.7086213 188.14561 -1.9871708 302.01203 +SHAKE stats (type/ave/delta/count) on step 300 +Bond: 1 0.9572 1.4264e-06 96 +Angle: 1 104.52 6.48393e-05 48 + 300 -17.502843 -20.993703 3.4908599 188.23268 -1.8457229 284.27861 +SHAKE stats (type/ave/delta/count) on step 400 +Bond: 1 0.9572 1.33728e-06 96 +Angle: 1 104.52 7.6239e-05 48 + 400 -17.495285 -20.82835 3.333065 188.48003 -1.8429074 271.42856 +SHAKE stats (type/ave/delta/count) on step 500 +Bond: 1 0.9572 1.14685e-06 96 +Angle: 1 104.52 8.58621e-05 48 + 500 -17.491436 -20.443043 2.9516075 188.7589 -1.8566335 240.36452 +SHAKE stats (type/ave/delta/count) on step 600 +Bond: 1 0.9572 9.17601e-07 96 +Angle: 1 104.52 8.24517e-05 48 + 600 -17.505683 -20.608456 3.1027734 188.72078 -1.9560795 252.67474 +SHAKE stats (type/ave/delta/count) on step 700 +Bond: 1 0.9572 9.50425e-07 96 +Angle: 1 104.52 5.62422e-05 48 + 700 -17.496706 -21.072664 3.575958 188.2777 -1.9833951 291.20858 +SHAKE stats (type/ave/delta/count) on step 800 +Bond: 1 0.9572 1.15256e-06 96 +Angle: 1 104.52 7.02177e-05 48 + 800 -17.478628 -20.819507 3.340879 188.37868 -1.9113009 272.06489 +SHAKE stats (type/ave/delta/count) on step 900 +Bond: 1 0.9572 9.14163e-07 96 +Angle: 1 104.52 6.98849e-05 48 + 900 -17.480865 -20.728504 3.2476386 188.5902 -1.8922108 264.47185 +SHAKE stats (type/ave/delta/count) on step 1000 +Bond: 1 0.9572 1.00568e-06 96 +Angle: 1 104.52 0.000111707 48 + 1000 -17.498474 -20.331607 2.833133 188.87466 -1.8121689 230.71654 +Loop time of 9.42273 on 4 procs for 1000 steps with 936 atoms + +Performance: 9.169 ns/day, 2.617 hours/ns, 106.126 timesteps/s +97.1% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.2328 | 4.3228 | 7.5931 | 103.1 | 45.88 +Bond | 0.00084131 | 0.00088983 | 0.00095229 | 0.0 | 0.01 +Kspace | 1.3979 | 4.6476 | 6.7252 | 98.8 | 49.32 +Neigh | 0.34367 | 0.34371 | 0.34376 | 0.0 | 3.65 +Comm | 0.042806 | 0.062908 | 0.075887 | 5.4 | 0.67 +Output | 0.00037677 | 0.00041431 | 0.0004619 | 0.0 | 0.00 +Modify | 0.028432 | 0.031138 | 0.034528 | 1.3 | 0.33 +Other | | 0.01321 | | | 0.14 + +Nlocal: 234 ave 302 max 198 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Nghost: 2876.5 ave 3122 max 2632 min +Histogram: 1 0 1 0 0 0 0 1 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 107846 ave 150684 max 82181 min +Histogram: 2 0 0 0 1 0 0 0 0 1 + +Total # of neighbors = 431382 +Ave neighs/atom = 460.87821 +Ave special neighs/atom = 0.30769231 +Neighbor list builds = 28 +Dangerous builds = 0 +Total wall time: 0:00:09 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.1 b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.1 new file mode 100644 index 0000000000..c6a11d209d --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.1 @@ -0,0 +1,251 @@ +LAMMPS (23 Jun 2022) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Initialization +units metal +boundary p p p +atom_style full +processors * * 1 # domain decomposition over x and y +read_data ./gra_water.data +Reading data file ... + orthogonal box = (0 0 0) to (46.92336 44.331078 200) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 936 atoms + reading velocities ... + 936 velocities + scanning bonds ... + 2 = max bonds/atom + scanning angles ... + 1 = max angles/atom + reading bonds ... + 96 bonds + reading angles ... + 48 angles +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.005 seconds + read_data CPU = 0.020 seconds +mass 1 12.0107 # carbon mass (g/mole) +mass 2 15.9994 # oxygen mass (g/mole) +mass 3 1.008 # hydrogen mass (g/mole) +# Separate atom groups +group gr molecule 1 +792 atoms in group gr +group water molecule 2 +144 atoms in group water +######################## Potential defition ############################## +# Interlayer potential +pair_style hybrid/overlay ilp/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +#################################################################### +pair_coeff 1 1 none +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * ilp/water/2dm/opt COH.ILP C Ow Hw # C-water +Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +# bond and angle +bond_style harmonic +bond_coeff 1 0.0 0.9572 +angle_style harmonic +angle_coeff 1 0.0 104.52 +# define kspace calculation +kspace_style pppm/tip4p 1E-5 +# Neighbor update settings +neighbor 2.0 bin +neigh_modify every 1 delay 5 check yes page 1000000 one 100000 +#################################################################### +# Calculate pair energy +compute 1 all pair lj/cut/tip4p/long +compute 2 all pair ilp/water/2dm/opt +compute wt water temp +variable TIP4P equal c_1 +variable EILP equal c_2 # total interlayer energy +variable temp_wt equal c_wt +############# Output ############## +thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt +thermo 100 +thermo_modify lost error + +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 + 0 = # of size 2 clusters + 0 = # of size 3 clusters + 0 = # of size 4 clusters + 48 = # of frozen angles + find clusters CPU = 0.001 seconds + +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 +@Article{Ouyang2018 + author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, + journal = {Nano Letters}, + volume = 18, + pages = {6009} + year = 2018, +} + +- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +@Article{Ouyang2021 + author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J. Chem. Theory Comput.}, + volume = 17, + pages = {7237–7245} + year = 2021, +} + +- ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 +@Article{Feng2023 + author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang}, + title = {Registry-Dependent Potential for Interfaces of Water with Graphene}, + journal = {J. Phys. Chem. C}, + volume = 127, + pages = {8704-8713} + year = 2023, +} + +- ilp/graphene/hbn/opt potential doi:10.1145/3458817.3476137 +@inproceedings{gao2021lmff + author = {Gao, Ping and Duan, Xiaohui and Others}, + title = {LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors}, + year = {2021}, + isbn = {9781450384421}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3458817.3476137}, + doi = {10.1145/3458817.3476137}, + booktitle = {Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis}, + articleno = {42}, + numpages = {14}, + location = {St. Louis, Missouri}, + series = {SC'21}, +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +PPPM initialization ... + extracting TIP4P info from pair style + using 12-bit tables for long-range coulomb (../kspace.cpp:342) + G vector (1/distance) = 0.28684806 + grid = 25 24 80 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0001640931 + estimated relative force accuracy = 1.1395635e-05 + using single precision MKL FFT + 3d grid and FFT values/proc = 84320 48000 +WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 100000, page size: 1000000 + master list distance cutoff = 18 + ghost atom cutoff = 18 + binsize = 9, bins = 6 5 23 + 3 neighbor lists, perpetual/occasional/extra = 3 0 0 + (1) pair ilp/water/2dm/opt, perpetual + attributes: full, newton on + pair build: full/bin + stencil: full/bin/3d + bin: standard + (2) pair lj/cut/tip4p/long, perpetual, skip from (3) + attributes: half, newton on + pair build: skip + stencil: none + bin: none + (3) neighbor class addition, perpetual, half/full from (1) + attributes: half, newton on + pair build: halffull/newton + stencil: none + bin: none +SHAKE stats (type/ave/delta/count) on step 0 +Bond: 1 0.957201 2.19705e-06 96 +Angle: 1 104.52 0.000203056 48 +Per MPI rank memory allocation (min/avg/max) = 25.89 | 25.89 | 25.89 Mbytes + Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt + 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 +SHAKE stats (type/ave/delta/count) on step 100 +Bond: 1 0.9572 9.54949e-07 96 +Angle: 1 104.52 6.01522e-05 48 + 100 -17.494868 -20.796993 3.3021253 188.4955 -1.8981262 268.90898 +SHAKE stats (type/ave/delta/count) on step 200 +Bond: 1 0.9572 9.63922e-07 96 +Angle: 1 104.52 7.7021e-05 48 + 200 -17.486271 -21.194892 3.7086213 188.14561 -1.9871708 302.01203 +SHAKE stats (type/ave/delta/count) on step 300 +Bond: 1 0.9572 1.4264e-06 96 +Angle: 1 104.52 6.48393e-05 48 + 300 -17.502844 -20.993704 3.49086 188.23268 -1.8457229 284.27861 +SHAKE stats (type/ave/delta/count) on step 400 +Bond: 1 0.9572 1.33728e-06 96 +Angle: 1 104.52 7.6239e-05 48 + 400 -17.495287 -20.828353 3.3330658 188.48002 -1.8429075 271.42862 +SHAKE stats (type/ave/delta/count) on step 500 +Bond: 1 0.9572 1.14685e-06 96 +Angle: 1 104.52 8.58621e-05 48 + 500 -17.491436 -20.443044 2.9516084 188.7589 -1.8566335 240.36459 +SHAKE stats (type/ave/delta/count) on step 600 +Bond: 1 0.9572 9.17601e-07 96 +Angle: 1 104.52 8.24516e-05 48 + 600 -17.505684 -20.608457 3.1027731 188.72078 -1.9560796 252.67471 +SHAKE stats (type/ave/delta/count) on step 700 +Bond: 1 0.9572 9.50422e-07 96 +Angle: 1 104.52 5.62423e-05 48 + 700 -17.496701 -21.07266 3.5759595 188.2777 -1.9833956 291.20871 +SHAKE stats (type/ave/delta/count) on step 800 +Bond: 1 0.9572 1.15262e-06 96 +Angle: 1 104.52 7.02158e-05 48 + 800 -17.478623 -20.819504 3.340881 188.37868 -1.9112996 272.06506 +SHAKE stats (type/ave/delta/count) on step 900 +Bond: 1 0.9572 9.14138e-07 96 +Angle: 1 104.52 6.98742e-05 48 + 900 -17.480864 -20.728498 3.2476343 188.59022 -1.8922102 264.4715 +SHAKE stats (type/ave/delta/count) on step 1000 +Bond: 1 0.9572 1.00586e-06 96 +Angle: 1 104.52 0.000111711 48 + 1000 -17.498466 -20.331547 2.8330808 188.87473 -1.8121768 230.71228 +Loop time of 8.95265 on 1 procs for 1000 steps with 936 atoms + +Performance: 9.651 ns/day, 2.487 hours/ns, 111.699 timesteps/s +100.0% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 5.2127 | 5.2127 | 5.2127 | 0.0 | 58.23 +Bond | 0.00083377 | 0.00083377 | 0.00083377 | 0.0 | 0.01 +Kspace | 3.5005 | 3.5005 | 3.5005 | 0.0 | 39.10 +Neigh | 0.17946 | 0.17946 | 0.17946 | 0.0 | 2.00 +Comm | 0.028553 | 0.028553 | 0.028553 | 0.0 | 0.32 +Output | 0.00035446 | 0.00035446 | 0.00035446 | 0.0 | 0.00 +Modify | 0.01889 | 0.01889 | 0.01889 | 0.0 | 0.21 +Other | | 0.01135 | | | 0.13 + +Nlocal: 936 ave 936 max 936 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 5242 ave 5242 max 5242 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 431382 ave 431382 max 431382 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 431382 +Ave neighs/atom = 460.87821 +Ave special neighs/atom = 0.30769231 +Neighbor list builds = 28 +Dangerous builds = 0 +Total wall time: 0:00:09 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.4 b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.4 new file mode 100644 index 0000000000..852c429323 --- /dev/null +++ b/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.4 @@ -0,0 +1,251 @@ +LAMMPS (23 Jun 2022) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Initialization +units metal +boundary p p p +atom_style full +processors * * 1 # domain decomposition over x and y +read_data ./gra_water.data +Reading data file ... + orthogonal box = (0 0 0) to (46.92336 44.331078 200) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 936 atoms + reading velocities ... + 936 velocities + scanning bonds ... + 2 = max bonds/atom + scanning angles ... + 1 = max angles/atom + reading bonds ... + 96 bonds + reading angles ... + 48 angles +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.003 seconds + read_data CPU = 0.017 seconds +mass 1 12.0107 # carbon mass (g/mole) +mass 2 15.9994 # oxygen mass (g/mole) +mass 3 1.008 # hydrogen mass (g/mole) +# Separate atom groups +group gr molecule 1 +792 atoms in group gr +group water molecule 2 +144 atoms in group water +######################## Potential defition ############################## +# Interlayer potential +pair_style hybrid/overlay ilp/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +#################################################################### +pair_coeff 1 1 none +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * ilp/water/2dm/opt COH.ILP C Ow Hw # C-water +Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +# bond and angle +bond_style harmonic +bond_coeff 1 0.0 0.9572 +angle_style harmonic +angle_coeff 1 0.0 104.52 +# define kspace calculation +kspace_style pppm/tip4p 1E-5 +# Neighbor update settings +neighbor 2.0 bin +neigh_modify every 1 delay 5 check yes page 1000000 one 100000 +#################################################################### +# Calculate pair energy +compute 1 all pair lj/cut/tip4p/long +compute 2 all pair ilp/water/2dm/opt +compute wt water temp +variable TIP4P equal c_1 +variable EILP equal c_2 # total interlayer energy +variable temp_wt equal c_wt +############# Output ############## +thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt +thermo 100 +thermo_modify lost error + +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 + 0 = # of size 2 clusters + 0 = # of size 3 clusters + 0 = # of size 4 clusters + 48 = # of frozen angles + find clusters CPU = 0.001 seconds + +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +Your simulation uses code contributions which should be cited: + +- ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 +@Article{Ouyang2018 + author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, + journal = {Nano Letters}, + volume = 18, + pages = {6009} + year = 2018, +} + +- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +@Article{Ouyang2021 + author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J. Chem. Theory Comput.}, + volume = 17, + pages = {7237–7245} + year = 2021, +} + +- ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 +@Article{Feng2023 + author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang}, + title = {Registry-Dependent Potential for Interfaces of Water with Graphene}, + journal = {J. Phys. Chem. C}, + volume = 127, + pages = {8704-8713} + year = 2023, +} + +- ilp/graphene/hbn/opt potential doi:10.1145/3458817.3476137 +@inproceedings{gao2021lmff + author = {Gao, Ping and Duan, Xiaohui and Others}, + title = {LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors}, + year = {2021}, + isbn = {9781450384421}, + publisher = {Association for Computing Machinery}, + address = {New York, NY, USA}, + url = {https://doi.org/10.1145/3458817.3476137}, + doi = {10.1145/3458817.3476137}, + booktitle = {Proceedings of the International Conference for High Performance Computing, Networking, Storage and Analysis}, + articleno = {42}, + numpages = {14}, + location = {St. Louis, Missouri}, + series = {SC'21}, +} + +CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE + +PPPM initialization ... + extracting TIP4P info from pair style + using 12-bit tables for long-range coulomb (../kspace.cpp:342) + G vector (1/distance) = 0.28684806 + grid = 25 24 80 + stencil order = 5 + estimated absolute RMS force accuracy = 0.0001640931 + estimated relative force accuracy = 1.1395635e-05 + using single precision MKL FFT + 3d grid and FFT values/proc = 30685 12480 +WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +Neighbor list info ... + update every 1 steps, delay 5 steps, check yes + max neighbors/atom: 100000, page size: 1000000 + master list distance cutoff = 18 + ghost atom cutoff = 18 + binsize = 9, bins = 6 5 23 + 3 neighbor lists, perpetual/occasional/extra = 3 0 0 + (1) pair ilp/water/2dm/opt, perpetual + attributes: full, newton on + pair build: full/bin + stencil: full/bin/3d + bin: standard + (2) pair lj/cut/tip4p/long, perpetual, skip from (3) + attributes: half, newton on + pair build: skip + stencil: none + bin: none + (3) neighbor class addition, perpetual, half/full from (1) + attributes: half, newton on + pair build: halffull/newton + stencil: none + bin: none +SHAKE stats (type/ave/delta/count) on step 0 +Bond: 1 0.957201 2.19705e-06 96 +Angle: 1 104.52 0.000203056 48 +Per MPI rank memory allocation (min/avg/max) = 22.03 | 22.06 | 22.1 Mbytes + Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt + 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 +SHAKE stats (type/ave/delta/count) on step 100 +Bond: 1 0.9572 9.54949e-07 96 +Angle: 1 104.52 6.01522e-05 48 + 100 -17.494869 -20.796995 3.3021253 188.4955 -1.8981262 268.90898 +SHAKE stats (type/ave/delta/count) on step 200 +Bond: 1 0.9572 9.63922e-07 96 +Angle: 1 104.52 7.7021e-05 48 + 200 -17.48627 -21.194892 3.7086213 188.14561 -1.9871708 302.01203 +SHAKE stats (type/ave/delta/count) on step 300 +Bond: 1 0.9572 1.4264e-06 96 +Angle: 1 104.52 6.48393e-05 48 + 300 -17.502843 -20.993703 3.4908599 188.23268 -1.8457229 284.27861 +SHAKE stats (type/ave/delta/count) on step 400 +Bond: 1 0.9572 1.33728e-06 96 +Angle: 1 104.52 7.6239e-05 48 + 400 -17.495285 -20.82835 3.333065 188.48003 -1.8429074 271.42856 +SHAKE stats (type/ave/delta/count) on step 500 +Bond: 1 0.9572 1.14685e-06 96 +Angle: 1 104.52 8.58621e-05 48 + 500 -17.491436 -20.443043 2.9516075 188.7589 -1.8566335 240.36452 +SHAKE stats (type/ave/delta/count) on step 600 +Bond: 1 0.9572 9.17601e-07 96 +Angle: 1 104.52 8.24517e-05 48 + 600 -17.505682 -20.608456 3.1027734 188.72078 -1.9560795 252.67474 +SHAKE stats (type/ave/delta/count) on step 700 +Bond: 1 0.9572 9.50425e-07 96 +Angle: 1 104.52 5.62423e-05 48 + 700 -17.496706 -21.072664 3.575958 188.2777 -1.9833951 291.20858 +SHAKE stats (type/ave/delta/count) on step 800 +Bond: 1 0.9572 1.15256e-06 96 +Angle: 1 104.52 7.02177e-05 48 + 800 -17.478628 -20.819507 3.340879 188.37868 -1.9113009 272.0649 +SHAKE stats (type/ave/delta/count) on step 900 +Bond: 1 0.9572 9.14163e-07 96 +Angle: 1 104.52 6.98849e-05 48 + 900 -17.480868 -20.728506 3.2476383 188.5902 -1.8922108 264.47182 +SHAKE stats (type/ave/delta/count) on step 1000 +Bond: 1 0.9572 1.00568e-06 96 +Angle: 1 104.52 0.000111707 48 + 1000 -17.498472 -20.331605 2.8331335 188.87466 -1.8121689 230.71657 +Loop time of 4.7828 on 4 procs for 1000 steps with 936 atoms + +Performance: 18.065 ns/day, 1.329 hours/ns, 209.082 timesteps/s +96.3% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.26735 | 1.3839 | 3.2059 | 99.7 | 28.93 +Bond | 0.00079377 | 0.00086039 | 0.00093529 | 0.0 | 0.02 +Kspace | 1.4248 | 3.2254 | 4.3332 | 64.6 | 67.44 +Neigh | 0.061885 | 0.061916 | 0.061951 | 0.0 | 1.29 +Comm | 0.044281 | 0.065185 | 0.078628 | 5.1 | 1.36 +Output | 0.0003482 | 0.0003787 | 0.00040746 | 0.0 | 0.01 +Modify | 0.028727 | 0.031529 | 0.034914 | 1.3 | 0.66 +Other | | 0.01367 | | | 0.29 + +Nlocal: 234 ave 302 max 198 min +Histogram: 2 0 0 1 0 0 0 0 0 1 +Nghost: 2876.5 ave 3122 max 2632 min +Histogram: 1 0 1 0 0 0 0 1 0 1 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 107846 ave 150684 max 82181 min +Histogram: 2 0 0 0 1 0 0 0 0 1 + +Total # of neighbors = 431382 +Ave neighs/atom = 460.87821 +Ave special neighs/atom = 0.30769231 +Neighbor list builds = 28 +Dangerous builds = 0 +Total wall time: 0:00:04 From 50858205f66fea71233ee1493d14431069833d98 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 18 May 2023 11:43:54 -0600 Subject: [PATCH 222/448] refresh log files for fix ttm/mod example --- ...tm.mod.g++.1 => log.18May23.ttm.mod.g++.1} | 56 +++++++++---------- ...tm.mod.g++.4 => log.18May23.ttm.mod.g++.4} | 55 +++++++++--------- 2 files changed, 54 insertions(+), 57 deletions(-) rename examples/ttm/{log.20Apr22.ttm.mod.g++.1 => log.18May23.ttm.mod.g++.1} (70%) rename examples/ttm/{log.20Apr22.ttm.mod.g++.4 => log.18May23.ttm.mod.g++.4} (71%) diff --git a/examples/ttm/log.20Apr22.ttm.mod.g++.1 b/examples/ttm/log.18May23.ttm.mod.g++.1 similarity index 70% rename from examples/ttm/log.20Apr22.ttm.mod.g++.1 rename to examples/ttm/log.18May23.ttm.mod.g++.1 index 6c0470617b..b97e8ab0ea 100644 --- a/examples/ttm/log.20Apr22.ttm.mod.g++.1 +++ b/examples/ttm/log.18May23.ttm.mod.g++.1 @@ -1,6 +1,4 @@ -LAMMPS (24 Mar 2022) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) - using 1 OpenMP thread(s) per MPI task +LAMMPS (28 Mar 2023 - Development) units metal atom_style atomic boundary p p p @@ -15,7 +13,7 @@ mass 1 28.0855 create_atoms 1 box basis 1 1 basis 2 1 basis 3 1 basis 4 1 basis 5 1 basis 6 1 basis 7 1 basis 8 1 Created 8000 atoms using lattice units in orthogonal box = (0 0 0) to (54.309 54.309 54.309) - create_atoms CPU = 0.001 seconds + create_atoms CPU = 0.002 seconds pair_style sw pair_coeff * * Si.sw Si @@ -42,12 +40,12 @@ CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE Your simulation uses code contributions which should be cited: -- fix ttm/mod command: +- fix ttm/mod command: doi:10.1088/0953-8984/26/47/475401, doi:10.1002/ctpp.201310025 @article{Pisarev2014, author = {Pisarev, V. V. and Starikov, S. V.}, -title = {{Atomistic simulation of ion track formation in UO2.}}, -journal = {J.~Phys.:~Condens.~Matter}, +title = {Atomistic Simulation of Ion Track Formation in {UO$_2$}.}, +journal = {J.~Phys.\ Condens.\ Matter}, volume = {26}, number = {47}, pages = {475401}, @@ -56,8 +54,8 @@ year = {2014} @article{Norman2013, author = {Norman, G. E. and Starikov, S. V. and Stegailov, V. V. and Saitov, I. M. and Zhilyaev, P. A.}, -title = {{Atomistic Modeling of Warm Dense Matter in the Two-Temperature State}}, -journal = {Contrib.~Plasm.~Phys.}, +title = {Atomistic Modeling of Warm Dense Matter in the Two-Temperature State}, +journal = {Contrib.\ Plasma Phys.}, number = {2}, volume = {53}, pages = {129--139}, @@ -67,7 +65,7 @@ year = {2013} CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE Neighbor list info ... - update every 5 steps, delay 0 steps, check yes + update: every = 5 steps, delay = 0 steps, check = yes max neighbors/atom: 2000, page size: 100000 master list distance cutoff = 5.77118 ghost atom cutoff = 5.77118 @@ -81,30 +79,30 @@ Neighbor list info ... Per MPI rank memory allocation (min/avg/max) = 4.433 | 4.433 | 4.433 Mbytes Step Temp TotEng f_twotemp[1] f_twotemp[2] 0 0 -34692.79996100604 -52.79390940511979 0 - 100 2.004897156140836 -34690.27961013186 -55.34997305431884 0.01301140393178354 - 200 2.837118035232607 -34687.74741132015 -57.93445748841878 0.02696025968760173 - 300 4.263087164947482 -34684.98084093686 -60.75945453846786 0.02175636603841567 - 400 5.568003854939066 -34682.25271040963 -63.56896518300501 0.0300061848347275 - 500 6.225602451570786 -34679.49948952029 -66.40897551884576 0.02768827702656702 - 600 7.608847536264781 -34676.69728436362 -69.32060611557266 0.05579466731854093 - 700 9.049471241531297 -34674.00093206036 -72.10055094219446 0.004335980559879027 - 800 9.826796099683211 -34671.27720242751 -74.9501061086213 0.02371649678091513 - 900 11.8609224958918 -34668.35091308811 -77.98544170794551 0.004658649791374929 - 1000 13.88037467640968 -34665.35025858006 -81.16445160194114 0.07684078334464739 -Loop time of 4.85247 on 1 procs for 1000 steps with 8000 atoms + 100 2.004897156140836 -34690.27961013186 -55.3499730543189 0.01301140393178352 + 200 2.837118035232607 -34687.74741132015 -57.93445748841876 0.02696025968760173 + 300 4.263087164947482 -34684.98084093686 -60.75945453846793 0.02175636603841567 + 400 5.568003854939066 -34682.25271040963 -63.56896518300499 0.03000618483472749 + 500 6.225602451570786 -34679.49948952029 -66.40897551884574 0.02768827702656703 + 600 7.608847536264781 -34676.69728436362 -69.32060611557282 0.05579466731854091 + 700 9.049471241531297 -34674.00093206036 -72.10055094219462 0.004335980559879032 + 800 9.826796099683211 -34671.27720242751 -74.95010610862134 0.02371649678091515 + 900 11.8609224958918 -34668.35091308811 -77.98544170794545 0.004658649791374908 + 1000 13.88037467640968 -34665.35025858006 -81.16445160194111 0.07684078334464743 +Loop time of 2.48942 on 1 procs for 1000 steps with 8000 atoms -Performance: 1.781 ns/day, 13.479 hours/ns, 206.081 timesteps/s -99.8% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 3.471 ns/day, 6.915 hours/ns, 401.700 timesteps/s, 3.214 Matom-step/s +100.0% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 4.1286 | 4.1286 | 4.1286 | 0.0 | 85.08 +Pair | 2.126 | 2.126 | 2.126 | 0.0 | 85.40 Neigh | 0 | 0 | 0 | 0.0 | 0.00 -Comm | 0.030972 | 0.030972 | 0.030972 | 0.0 | 0.64 -Output | 0.0026351 | 0.0026351 | 0.0026351 | 0.0 | 0.05 -Modify | 0.67848 | 0.67848 | 0.67848 | 0.0 | 13.98 -Other | | 0.01182 | | | 0.24 +Comm | 0.016147 | 0.016147 | 0.016147 | 0.0 | 0.65 +Output | 0.0013116 | 0.0013116 | 0.0013116 | 0.0 | 0.05 +Modify | 0.33864 | 0.33864 | 0.33864 | 0.0 | 13.60 +Other | | 0.007318 | | | 0.29 Nlocal: 8000 ave 8000 max 8000 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -119,4 +117,4 @@ Total # of neighbors = 272000 Ave neighs/atom = 34 Neighbor list builds = 0 Dangerous builds = 0 -Total wall time: 0:00:04 +Total wall time: 0:00:02 diff --git a/examples/ttm/log.20Apr22.ttm.mod.g++.4 b/examples/ttm/log.18May23.ttm.mod.g++.4 similarity index 71% rename from examples/ttm/log.20Apr22.ttm.mod.g++.4 rename to examples/ttm/log.18May23.ttm.mod.g++.4 index fdf9b0cfb5..ea675c8594 100644 --- a/examples/ttm/log.20Apr22.ttm.mod.g++.4 +++ b/examples/ttm/log.18May23.ttm.mod.g++.4 @@ -1,6 +1,5 @@ -LAMMPS (24 Mar 2022) -OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) - using 1 OpenMP thread(s) per MPI task +LAMMPS (28 Mar 2023 - Development) +WARNING: Using I/O redirection is unreliable with parallel runs. Better to use the -in switch to read input files. (../lammps.cpp:531) units metal atom_style atomic boundary p p p @@ -15,7 +14,7 @@ mass 1 28.0855 create_atoms 1 box basis 1 1 basis 2 1 basis 3 1 basis 4 1 basis 5 1 basis 6 1 basis 7 1 basis 8 1 Created 8000 atoms using lattice units in orthogonal box = (0 0 0) to (54.309 54.309 54.309) - create_atoms CPU = 0.000 seconds + create_atoms CPU = 0.001 seconds pair_style sw pair_coeff * * Si.sw Si @@ -42,12 +41,12 @@ CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE Your simulation uses code contributions which should be cited: -- fix ttm/mod command: +- fix ttm/mod command: doi:10.1088/0953-8984/26/47/475401, doi:10.1002/ctpp.201310025 @article{Pisarev2014, author = {Pisarev, V. V. and Starikov, S. V.}, -title = {{Atomistic simulation of ion track formation in UO2.}}, -journal = {J.~Phys.:~Condens.~Matter}, +title = {Atomistic Simulation of Ion Track Formation in {UO$_2$}.}, +journal = {J.~Phys.\ Condens.\ Matter}, volume = {26}, number = {47}, pages = {475401}, @@ -56,8 +55,8 @@ year = {2014} @article{Norman2013, author = {Norman, G. E. and Starikov, S. V. and Stegailov, V. V. and Saitov, I. M. and Zhilyaev, P. A.}, -title = {{Atomistic Modeling of Warm Dense Matter in the Two-Temperature State}}, -journal = {Contrib.~Plasm.~Phys.}, +title = {Atomistic Modeling of Warm Dense Matter in the Two-Temperature State}, +journal = {Contrib.\ Plasma Phys.}, number = {2}, volume = {53}, pages = {129--139}, @@ -67,7 +66,7 @@ year = {2013} CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE Neighbor list info ... - update every 5 steps, delay 0 steps, check yes + update: every = 5 steps, delay = 0 steps, check = yes max neighbors/atom: 2000, page size: 100000 master list distance cutoff = 5.77118 ghost atom cutoff = 5.77118 @@ -81,30 +80,30 @@ Neighbor list info ... Per MPI rank memory allocation (min/avg/max) = 3.436 | 3.436 | 3.436 Mbytes Step Temp TotEng f_twotemp[1] f_twotemp[2] 0 0 -34692.79996100361 -52.79390940511979 0 - 100 1.852689977101411 -34690.49204900486 -55.14271612882062 0.027261886765771 - 200 2.735750477179192 -34688.11139028054 -57.57110998717796 0.03387986355513582 - 300 3.931848271449558 -34685.54667417785 -60.18684521127226 0.02261256315262404 - 400 5.462009198576365 -34682.74455105668 -63.05420336037231 0.002402241637719583 - 500 6.267811692893873 -34679.96493887379 -65.93304222280049 0.02448378880218699 - 600 7.21148216150661 -34677.41455784726 -68.58391420045932 0.04114045759945373 - 700 8.84660534187052 -34674.40610468235 -71.68798344296847 0.0237298402743454 - 800 10.1748456457686 -34671.08749605772 -75.11943618276236 0.007538225788030298 - 900 11.27479036162859 -34668.4118066423 -77.92921692176769 0.02537529314475071 - 1000 13.26881394868076 -34665.56617589539 -80.91544540266329 0.03112665440209921 -Loop time of 1.60214 on 4 procs for 1000 steps with 8000 atoms + 100 1.852689977101411 -34690.49204900486 -55.14271612882064 0.02726188676577098 + 200 2.735750477179192 -34688.11139028054 -57.57110998717798 0.03387986355513584 + 300 3.931848271449558 -34685.54667417785 -60.18684521127231 0.02261256315262403 + 400 5.462009198576365 -34682.74455105668 -63.05420336037233 0.002402241637719578 + 500 6.267811692893873 -34679.96493887379 -65.93304222280051 0.02448378880218699 + 600 7.21148216150661 -34677.41455784726 -68.58391420045926 0.04114045759945374 + 700 8.84660534187052 -34674.40610468235 -71.68798344296859 0.02372984027434538 + 800 10.1748456457686 -34671.08749605772 -75.11943618276216 0.007538225788030307 + 900 11.27479036162859 -34668.4118066423 -77.92921692176756 0.02537529314475071 + 1000 13.26881394868076 -34665.56617589539 -80.91544540266317 0.03112665440209921 +Loop time of 0.995347 on 4 procs for 1000 steps with 8000 atoms -Performance: 5.393 ns/day, 4.450 hours/ns, 624.165 timesteps/s -99.7% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 8.680 ns/day, 2.765 hours/ns, 1004.675 timesteps/s, 8.037 Matom-step/s +97.9% CPU use with 4 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 1.0424 | 1.0558 | 1.0696 | 1.0 | 65.90 +Pair | 0.65351 | 0.6616 | 0.66783 | 0.8 | 66.47 Neigh | 0 | 0 | 0 | 0.0 | 0.00 -Comm | 0.05072 | 0.063773 | 0.079458 | 4.9 | 3.98 -Output | 0.0024362 | 0.0024703 | 0.0025297 | 0.1 | 0.15 -Modify | 0.47018 | 0.47332 | 0.48004 | 0.6 | 29.54 -Other | | 0.006786 | | | 0.42 +Comm | 0.041606 | 0.048314 | 0.056589 | 2.9 | 4.85 +Output | 0.0014609 | 0.0014742 | 0.0014968 | 0.0 | 0.15 +Modify | 0.27934 | 0.28016 | 0.28089 | 0.1 | 28.15 +Other | | 0.003798 | | | 0.38 Nlocal: 2000 ave 2000 max 2000 min Histogram: 4 0 0 0 0 0 0 0 0 0 From c73b7483b2ab8cfc84f507ec07abfe9f8e0931e8 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Thu, 18 May 2023 11:47:20 -0600 Subject: [PATCH 223/448] swtich loop order back to be consistent with rest of file --- src/EXTRA-FIX/fix_ttm_mod.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-FIX/fix_ttm_mod.cpp b/src/EXTRA-FIX/fix_ttm_mod.cpp index a5dea815ea..79af414f0a 100644 --- a/src/EXTRA-FIX/fix_ttm_mod.cpp +++ b/src/EXTRA-FIX/fix_ttm_mod.cpp @@ -894,9 +894,9 @@ double FixTTMMod::compute_vector(int n) double dz = domain->zprd/nzgrid; double del_vol = dx*dy*dz; - for (int ix = 0; ix < nxgrid; ix++) + for (int iz = 0; iz < nzgrid; iz++) for (int iy = 0; iy < nygrid; iy++) - for (int iz = 0; iz < nzgrid; iz++) { + for (int ix = 0; ix < nxgrid; ix++) { e_energy += el_sp_heat_integral(T_electron[iz][iy][ix])*del_vol; transfer_energy += net_energy_transfer_all[iz][iy][ix]*update->dt; } From 9da310a33e947d9e07a7b3ea4540b9aaeab61274 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 May 2023 00:40:45 -0400 Subject: [PATCH 224/448] spelling --- doc/src/Build_manual.rst | 2 +- doc/src/variable.rst | 2 +- doc/utils/sphinx-config/false_positives.txt | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/src/Build_manual.rst b/doc/src/Build_manual.rst index e9a55134da..4b4bfa5a45 100644 --- a/doc/src/Build_manual.rst +++ b/doc/src/Build_manual.rst @@ -52,7 +52,7 @@ can be translated to different output format using the `Sphinx incorporates programmer documentation extracted from the LAMMPS C++ sources through the `Doxygen `_ program. Currently the translation to HTML, PDF (via LaTeX), ePUB (for many e-book readers) -and MOBI (for Amazon Kindle(tm) readers) are supported. For that to work a +and MOBI (for Amazon Kindle readers) are supported. For that to work a Python interpreter version 3.8 or later, the ``doxygen`` tools and internet access to download additional files and tools are required. This download is usually only required once or after the documentation diff --git a/doc/src/variable.rst b/doc/src/variable.rst index afa491e96e..1c76a2acf4 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -1474,7 +1474,7 @@ commands .. code-block:: LAMMPS # delete_atoms random fraction 0.5 yes all NULL 49839 - # run 0 + # run 0 post no variable t equal temp # this thermo keyword invokes a temperature compute print "Temperature of system = $t" run 1000 diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index d2d15633af..2951f7d12e 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -3736,6 +3736,7 @@ Umin un unary uncomment +uncommented uncompress uncompute underprediction From 7c14b750ef5fbf9be610aeaf122c37d6d872537e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 19 May 2023 00:40:54 -0400 Subject: [PATCH 225/448] improve error message --- src/DIFFRACTION/compute_xrd.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/DIFFRACTION/compute_xrd.cpp b/src/DIFFRACTION/compute_xrd.cpp index 010e5bcb7d..426248b31e 100644 --- a/src/DIFFRACTION/compute_xrd.cpp +++ b/src/DIFFRACTION/compute_xrd.cpp @@ -90,8 +90,7 @@ ComputeXRD::ComputeXRD(LAMMPS *lmp, int narg, char **arg) : ztype[i] = j; } } - if (ztype[i] == XRDmaxType + 1) - error->all(FLERR,"Compute XRD: Invalid ASF atom type"); + if (ztype[i] == XRDmaxType + 1) error->all(FLERR,"Compute XRD: Invalid ASF atom type {}", arg[iarg]); iarg++; } From 22d9c047f44a9417028831c981889ec8e08f2e05 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Fri, 19 May 2023 22:52:18 +0800 Subject: [PATCH 226/448] update doc file --- doc/src/pair_ilp_water_2dm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/pair_ilp_water_2dm.rst b/doc/src/pair_ilp_water_2dm.rst index 5dc287493b..c611fb9275 100644 --- a/doc/src/pair_ilp_water_2dm.rst +++ b/doc/src/pair_ilp_water_2dm.rst @@ -163,4 +163,4 @@ tap_flag = 1 .. _Feng: -**(Feng)** Z. Feng, W. Ouyang, J. Phys. Chem. C. accepted (2023). +**(Feng)** Z. Feng and W. Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023). From 0334ddb7c69a36b33757694b905820f56d8b90f2 Mon Sep 17 00:00:00 2001 From: Wengen Ouyang <34092370+oywg11@users.noreply.github.com> Date: Fri, 19 May 2023 22:57:45 +0800 Subject: [PATCH 227/448] Update pair_ilp_water_2dm.rst --- doc/src/pair_ilp_water_2dm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/pair_ilp_water_2dm.rst b/doc/src/pair_ilp_water_2dm.rst index 5dc287493b..8ba75fb857 100644 --- a/doc/src/pair_ilp_water_2dm.rst +++ b/doc/src/pair_ilp_water_2dm.rst @@ -163,4 +163,4 @@ tap_flag = 1 .. _Feng: -**(Feng)** Z. Feng, W. Ouyang, J. Phys. Chem. C. accepted (2023). +**(Feng)** Z. Feng and W. Ouyang et al., J. Phys. Chem. C. 127, 8704-8713 (2023). From 7ec842d9cbcfa1f63496383f66125cdc1a9d47dd Mon Sep 17 00:00:00 2001 From: jtclemm Date: Fri, 19 May 2023 13:50:11 -0600 Subject: [PATCH 228/448] Adding requested feature to normalize forces --- src/BPM/bond_bpm_rotational.cpp | 28 ++++++++++++++++++++-------- src/BPM/bond_bpm_rotational.h | 2 +- src/BPM/bond_bpm_spring.cpp | 16 ++++++++++++++-- src/BPM/bond_bpm_spring.h | 2 +- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/BPM/bond_bpm_rotational.cpp b/src/BPM/bond_bpm_rotational.cpp index ac29c0e376..5c5c0218b6 100644 --- a/src/BPM/bond_bpm_rotational.cpp +++ b/src/BPM/bond_bpm_rotational.cpp @@ -50,6 +50,7 @@ BondBPMRotational::BondBPMRotational(LAMMPS *_lmp) : { partial_flag = 1; smooth_flag = 1; + normalize_flag = 0; single_extra = 7; svector = new double[7]; @@ -203,6 +204,13 @@ double BondBPMRotational::elastic_forces(int i1, int i2, int type, double r_mag, double Ts[3], Tb[3], Tt[3], Tbp[3], Ttp[3], Tsp[3], T_rot[3], Ttmp[3]; double **quat = atom->quat; + double r0_mag_inv = 1.0 / r0_mag; + double Kr_type = Kr[type]; + double Ks_type = Ks[type]; + if (normalize_flag) { + Kr_type *= r0_mag_inv; + Ks_type *= r0_mag_inv; + } q1[0] = quat[i1][0]; q1[1] = quat[i1][1]; @@ -217,26 +225,26 @@ double BondBPMRotational::elastic_forces(int i1, int i2, int type, double r_mag, // Calculate normal forces, rb = bond vector in particle 1's frame MathExtra::qconjugate(q2, q2inv); MathExtra::quatrotvec(q2inv, r, rb); - Fr = Kr[type] * (r_mag - r0_mag); + Fr = Kr_type * (r_mag - r0_mag); MathExtra::scale3(Fr * r_mag_inv, rb, F_rot); // Calculate forces due to tangential displacements (no rotation) r0_dot_rb = MathExtra::dot3(r0, rb); - c = r0_dot_rb * r_mag_inv / r0_mag; + c = r0_dot_rb * r_mag_inv * r0_mag_inv; gamma = acos_limit(c); MathExtra::cross3(rb, r0, rb_x_r0); MathExtra::cross3(rb, rb_x_r0, s); MathExtra::norm3(s); - MathExtra::scale3(Ks[type] * r_mag * gamma, s, Fs); + MathExtra::scale3(Ks_type * r_mag * gamma, s, Fs); // Calculate torque due to tangential displacements MathExtra::cross3(r0, rb, t); MathExtra::norm3(t); - MathExtra::scale3(0.5 * r_mag * Ks[type] * r_mag * gamma, t, Ts); + MathExtra::scale3(0.5 * r_mag * Ks_type * r_mag * gamma, t, Ts); // Relative rotation force/torque // Use representation of X'Y'Z' rotations from Wang, Mora 2009 @@ -316,12 +324,12 @@ double BondBPMRotational::elastic_forces(int i1, int i2, int type, double r_mag, Ttp[1] = 0.0; Ttp[2] = Kt[type] * psi; - Fsp[0] = -0.5 * Ks[type] * r_mag * theta * cos_phi; - Fsp[1] = -0.5 * Ks[type] * r_mag * theta * sin_phi; + Fsp[0] = -0.5 * Ks_type * r_mag * theta * cos_phi; + Fsp[1] = -0.5 * Ks_type * r_mag * theta * sin_phi; Fsp[2] = 0.0; - Tsp[0] = 0.25 * Ks[type] * r_mag * r_mag * theta * sin_phi; - Tsp[1] = -0.25 * Ks[type] * r_mag * r_mag * theta * cos_phi; + Tsp[0] = 0.25 * Ks_type * r_mag * r_mag * theta * sin_phi; + Tsp[1] = -0.25 * Ks_type * r_mag * r_mag * theta * cos_phi; Tsp[2] = 0.0; // Rotate forces/torques back to 1st particle's frame @@ -667,6 +675,10 @@ void BondBPMRotational::settings(int narg, char **arg) if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command, missing option for smooth"); smooth_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); i += 1; + } else if (strcmp(arg[iarg], "normalize") == 0) { + if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command, missing option for normalize"); + normalize_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); + i += 1; } else { error->all(FLERR, "Illegal bond bpm command, invalid argument {}", arg[iarg]); } diff --git a/src/BPM/bond_bpm_rotational.h b/src/BPM/bond_bpm_rotational.h index 0fb38e7343..9fdc418d2d 100644 --- a/src/BPM/bond_bpm_rotational.h +++ b/src/BPM/bond_bpm_rotational.h @@ -41,7 +41,7 @@ class BondBPMRotational : public BondBPM { protected: double *Kr, *Ks, *Kt, *Kb, *gnorm, *gslide, *groll, *gtwist; double *Fcr, *Fcs, *Tct, *Tcb; - int smooth_flag; + int smooth_flag, normalize_flag; double elastic_forces(int, int, int, double, double, double, double *, double *, double *, double *, double *, double *); diff --git a/src/BPM/bond_bpm_spring.cpp b/src/BPM/bond_bpm_spring.cpp index ed4e71daf1..37b79f93fb 100644 --- a/src/BPM/bond_bpm_spring.cpp +++ b/src/BPM/bond_bpm_spring.cpp @@ -37,6 +37,7 @@ BondBPMSpring::BondBPMSpring(LAMMPS *_lmp) : { partial_flag = 1; smooth_flag = 1; + normalize_flag = 0; single_extra = 1; svector = new double[1]; @@ -190,7 +191,10 @@ void BondBPMSpring::compute(int eflag, int vflag) } rinv = 1.0 / r; - fbond = k[type] * (r0 - r); + if (normalize_flag) + fbond = -k[type] * e; + else + fbond = k[type] * (r0 - r); delvx = v[i1][0] - v[i2][0]; delvy = v[i1][1] - v[i2][1]; @@ -302,6 +306,10 @@ void BondBPMSpring::settings(int narg, char **arg) if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command, missing option for smooth"); smooth_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); i += 1; + } else if (strcmp(arg[iarg], "normalize") == 0) { + if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command, missing option for normalize"); + normalize_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); + i += 1; } else { error->all(FLERR, "Illegal bond bpm command, invalid argument {}", arg[iarg]); } @@ -376,7 +384,11 @@ double BondBPMSpring::single(int type, double rsq, int i, int j, double &fforce) double r = sqrt(rsq); double rinv = 1.0 / r; - fforce = k[type] * (r0 - r); + + if (normalize_flag) + fforce = k[type] * (r0 - r) / r0; + else + fforce = k[type] * (r0 - r); double **x = atom->x; double **v = atom->v; diff --git a/src/BPM/bond_bpm_spring.h b/src/BPM/bond_bpm_spring.h index 409469bef3..93f4b49a26 100644 --- a/src/BPM/bond_bpm_spring.h +++ b/src/BPM/bond_bpm_spring.h @@ -40,7 +40,7 @@ class BondBPMSpring : public BondBPM { protected: double *k, *ecrit, *gamma; - int smooth_flag; + int smooth_flag, normalize_flag; void allocate(); void store_data(); From cb5934cbcdbf6ea4098451473d45126c79f99ca2 Mon Sep 17 00:00:00 2001 From: jtclemm Date: Fri, 19 May 2023 13:51:53 -0600 Subject: [PATCH 229/448] Adding option to doc files, clarifying normal forces in compute pair/bond local --- doc/src/bond_bpm_rotational.rst | 6 ++++++ doc/src/bond_bpm_spring.rst | 8 +++++++- doc/src/compute_bond_local.rst | 5 ++++- doc/src/compute_pair_local.rst | 4 +++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/doc/src/bond_bpm_rotational.rst b/doc/src/bond_bpm_rotational.rst index ba93d679ba..0baf7e35b1 100644 --- a/doc/src/bond_bpm_rotational.rst +++ b/doc/src/bond_bpm_rotational.rst @@ -30,6 +30,9 @@ Syntax *smooth* value = *yes* or *no* smooths bond forces near the breaking point + *normalize* value = *yes* or *no* + normalizes normal and shear forces by the reference length + *break/no* indicates that bonds should not break during a run @@ -136,6 +139,9 @@ or :doc:`read_restart ` commands: * :math:`\gamma_r` (force*distance/velocity units) * :math:`\gamma_t` (force*distance/velocity units) +However, the *normalize* option will normalize the radial and shear forces +by :math:`r_0` such that :math:`k_r` and :math:`k_s` are unit less. + By default, pair forces are not calculated between bonded particles. Pair forces can alternatively be overlaid on top of bond forces using the *overlay/pair* keyword. These settings require specific diff --git a/doc/src/bond_bpm_spring.rst b/doc/src/bond_bpm_spring.rst index 5762dbe208..6da0d25a4a 100644 --- a/doc/src/bond_bpm_spring.rst +++ b/doc/src/bond_bpm_spring.rst @@ -30,6 +30,9 @@ Syntax *smooth* value = *yes* or *no* smooths bond forces near the breaking point + *normalize* value = *yes* or *no* + normalizes bond forces by their reference length + *break/no* indicates that bonds should not break during a run @@ -66,7 +69,7 @@ particles based on a model described by Clemmer and Robbins F = k (r - r_0) w -where :math:`k_r` is a stiffness, :math:`r` is the current distance +where :math:`k` is a stiffness, :math:`r` is the current distance and :math:`r_0` is the initial distance between the two particles, and :math:`w` is an optional smoothing factor discussed below. Bonds will break at a strain of :math:`\epsilon_c`. This is done by setting by @@ -102,6 +105,9 @@ the data file or restart files read by the :doc:`read_data * :math:`\epsilon_c` (unit less) * :math:`\gamma` (force/velocity units) +However, the *normalize* option will normalize the elastic bond force by +:math:`r_0` such that :math:`k` is unit less. + By default, pair forces are not calculated between bonded particles. Pair forces can alternatively be overlaid on top of bond forces using the *overlay/pair* keyword. These settings require specific diff --git a/doc/src/compute_bond_local.rst b/doc/src/compute_bond_local.rst index f3fb752ebe..10e86bbe44 100644 --- a/doc/src/compute_bond_local.rst +++ b/doc/src/compute_bond_local.rst @@ -76,7 +76,10 @@ The value *force* is the magnitude of the force acting between the pair of atoms in the bond. The values *fx*, *fy*, and *fz* are the xyz components of -*force* between the pair of atoms in the bond. +*force* between the pair of atoms in the bond. For bond styles that apply +non-central forces, such as :doc:`bond_style bpm/rotational +`, these values only include the :math:`(x,y,z)` +components of the normal force component. The remaining properties are all computed for motion of the two atoms relative to the center of mass (COM) velocity of the 2 atoms in the diff --git a/doc/src/compute_pair_local.rst b/doc/src/compute_pair_local.rst index dace280dee..31209f63f4 100644 --- a/doc/src/compute_pair_local.rst +++ b/doc/src/compute_pair_local.rst @@ -66,7 +66,9 @@ The value *eng* is the interaction energy for the pair of atoms. The value *force* is the force acting between the pair of atoms, which is positive for a repulsive force and negative for an attractive force. The values *fx*, *fy*, and *fz* are the :math:`(x,y,z)` components of -*force* on atom I. +*force* on atom I. For pair styles that apply non-central forces, +such as :doc:`granular pair styles `, these values only include +the :math:`(x,y,z)` components of the normal force component. A pair style may define additional pairwise quantities which can be accessed as *p1* to *pN*, where :math:`N` is defined by the pair style. From 0dd26189d4e8fb5b5630618687f74cd032d6ad62 Mon Sep 17 00:00:00 2001 From: jtclemm Date: Fri, 19 May 2023 13:52:35 -0600 Subject: [PATCH 230/448] Adding missing factor in bpm/rotational single method --- src/BPM/bond_bpm_rotational.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BPM/bond_bpm_rotational.cpp b/src/BPM/bond_bpm_rotational.cpp index 5c5c0218b6..ffb0d9521d 100644 --- a/src/BPM/bond_bpm_rotational.cpp +++ b/src/BPM/bond_bpm_rotational.cpp @@ -805,7 +805,7 @@ double BondBPMRotational::single(int type, double rsq, int i, int j, double &ffo double breaking = elastic_forces(i, j, type, r_mag, r0_mag, r_mag_inv, rhat, r, r0, force1on2, torque1on2, torque2on1); damping_forces(i, j, type, rhat, r, force1on2, torque1on2, torque2on1); - fforce = MathExtra::dot3(force1on2, r); + fforce = MathExtra::dot3(force1on2, rhat); fforce *= -1; double smooth = 1.0; From b9f01f106e626b518ce019ebfbc5bcb72e4e76d9 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Fri, 19 May 2023 21:20:34 -0400 Subject: [PATCH 231/448] is_typelabel function --- src/variable.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 783ceab832..449efe6d7b 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4040,8 +4040,8 @@ Region *Variable::region_function(char *id, int ivar) return 0 if not a match, 1 if successfully processed customize by adding a special function: sum(x),min(x),max(x),ave(x),trap(x),slope(x), - gmask(x),rmask(x),grmask(x,y),next(x), - is_file(x),is_ox(x),extract_setting(x),label2type(x,y) + gmask(x),rmask(x),grmask(x,y),next(x),is_file(x),is_ox(x), + extract_setting(x),label2type(x,y),is_typelabel(x) ------------------------------------------------------------------------- */ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **treestack, @@ -4056,12 +4056,13 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t strcmp(word,"ave") != 0 && strcmp(word,"trap") != 0 && strcmp(word,"slope") != 0 && strcmp(word,"gmask") != 0 && strcmp(word,"rmask") != 0 && strcmp(word,"grmask") != 0 && strcmp(word,"next") != 0 && strcmp(word,"is_file") != 0 && strcmp(word,"is_os") != 0 && - strcmp(word,"extract_setting") != 0 && strcmp(word,"label2type") != 0) + strcmp(word,"extract_setting") != 0 && strcmp(word,"label2type") != 0 && + strcmp(word,"is_typelabel") != 0) return 0; // process label2type() separately b/c its label arg can have commas in it - if (strcmp(word,"label2type") == 0) { + if (strcmp(word,"label2type") == 0 || strcmp(word,"is_typelabel") == 0) { if (!atom->labelmapflag) print_var_error(FLERR,"Cannot use label2type() function without a labelmap",ivar); @@ -4088,9 +4089,10 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() in variable",kind),ivar); } - if (value == -1) + if (strcmp(word,"label2type") == 0 && value == -1) print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable", kind, typestr), ivar); + else value = (value == -1) ? 0.0 : 1.0; // save value in tree or on argstack From 0a45d1f9ac061b5d9e2920910cd9ebfcc5213431 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Fri, 19 May 2023 21:31:51 -0400 Subject: [PATCH 232/448] Update variable.rst --- doc/src/variable.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/src/variable.rst b/doc/src/variable.rst index afa491e96e..b39fb55caa 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -67,7 +67,7 @@ Syntax bound(group,dir,region), gyration(group,region), ke(group,reigon), angmom(group,dim,region), torque(group,dim,region), inertia(group,dimdim,region), omega(group,dim,region) - special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label) + special functions = sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label), is_typelabel(kind,label) feature functions = is_available(category,feature), is_active(category,feature), is_defined(category,id) atom value = id[i], mass[i], type[i], mol[i], x[i], y[i], z[i], vx[i], vy[i], vz[i], fx[i], fy[i], fz[i], q[i] atom vector = id, mass, type, mol, radius, q, x, y, z, vx, vy, vz, fx, fy, fz @@ -532,7 +532,7 @@ variables. +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Region functions | count(ID,IDR), mass(ID,IDR), charge(ID,IDR), xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), angmom(ID,dim,IDR), torque(ID,dim,IDR), inertia(ID,dimdim,IDR), omega(ID,dim,IDR) | +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Special functions | sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label) | +| Special functions | sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label), is_typelabel(kind,label) | +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Feature functions | is_available(category,feature), is_active(category,feature), is_defined(category,id) | +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -999,7 +999,10 @@ types, using label maps created by the :doc:`labelmap ` or :doc:`read_data ` commands. The first argument is the label map kind (atom, bond, angle, dihedral, or improper) and the second argument is the label. The function returns the corresponding -numeric type. +numeric type. The is_typelabel(kind,label) function has the same +arguments, but returns 1 if the type label has been assigned, otherwise +it returns 0. This function can be used to check if a particular type +label already exists in the simulation. ---------- From ad7b27a67adff911cece12b002b93505961860a1 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Fri, 19 May 2023 22:27:28 -0400 Subject: [PATCH 233/448] correct logic --- src/variable.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 449efe6d7b..6eb483976b 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4089,10 +4089,10 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() in variable",kind),ivar); } - if (strcmp(word,"label2type") == 0 && value == -1) - print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable", - kind, typestr), ivar); - else value = (value == -1) ? 0.0 : 1.0; + if (strcmp(word,"label2type")) == 0) { + if (value == -1) print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable", + kind, typestr), ivar); + } else value = (value == -1) ? 0.0 : 1.0; // save value in tree or on argstack From aaabe41b224254648528d394725793be325755c0 Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Fri, 19 May 2023 22:54:23 -0400 Subject: [PATCH 234/448] typo --- src/variable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variable.cpp b/src/variable.cpp index 6eb483976b..013c08ade0 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4089,7 +4089,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() in variable",kind),ivar); } - if (strcmp(word,"label2type")) == 0) { + if (strcmp(word,"label2type") == 0) { if (value == -1) print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable", kind, typestr), ivar); } else value = (value == -1) ? 0.0 : 1.0; From d7b7d1d32351483a59965bc1ea7d963a99f2db4f Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Fri, 19 May 2023 23:48:41 -0400 Subject: [PATCH 235/448] make sure error messages not wrong --- src/variable.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 013c08ade0..9eed0b8429 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4064,13 +4064,16 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t if (strcmp(word,"label2type") == 0 || strcmp(word,"is_typelabel") == 0) { if (!atom->labelmapflag) - print_var_error(FLERR,"Cannot use label2type() function without a labelmap",ivar); + print_var_error(FLERR,"Cannot use label2type() or is_typelabel() function without a labelmap",ivar); std::string contents_copy(contents); auto pos = contents_copy.find_first_of(','); if (pos == std::string::npos) - print_var_error(FLERR, fmt::format("Invalid label2type({}) function in variable formula", - contents_copy), ivar); + if (strcmp(word,"label2type") == 0) + print_var_error(FLERR, fmt::format("Invalid label2type({}) function in variable formula", + contents_copy), ivar); + else print_var_error(FLERR, fmt::format("Invalid is_typelabel({}) function in variable formula", + contents_copy), ivar); std::string typestr = contents_copy.substr(pos+1); std::string kind = contents_copy.substr(0, pos); @@ -4086,7 +4089,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t } else if (kind == "improper") { value = atom->lmap->find(typestr,Atom::IMPROPER); } else { - print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() in variable",kind),ivar); + print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() or is_typelabel() in variable",kind),ivar); } if (strcmp(word,"label2type") == 0) { From 5fac8f483e2db22726fd815aa4d5476c6525f87c Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Fri, 19 May 2023 23:51:01 -0400 Subject: [PATCH 236/448] last typo --- src/variable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variable.cpp b/src/variable.cpp index 9eed0b8429..4fb6939866 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4041,7 +4041,7 @@ Region *Variable::region_function(char *id, int ivar) customize by adding a special function: sum(x),min(x),max(x),ave(x),trap(x),slope(x), gmask(x),rmask(x),grmask(x,y),next(x),is_file(x),is_ox(x), - extract_setting(x),label2type(x,y),is_typelabel(x) + extract_setting(x),label2type(x,y),is_typelabel(x,y) ------------------------------------------------------------------------- */ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **treestack, From 8d0eb9b1f71c3454d84f5c289d816deea29c5aed Mon Sep 17 00:00:00 2001 From: srtee Date: Tue, 9 May 2023 22:07:48 +1000 Subject: [PATCH 237/448] hook up efield variables to qeq/reaxff --- src/REAXFF/fix_qeq_reaxff.cpp | 41 +++++++++++++++++++--------- src/fix_efield.cpp | 50 +++++++++++++++++++++-------------- src/fix_efield.h | 1 + 3 files changed, 60 insertions(+), 32 deletions(-) diff --git a/src/REAXFF/fix_qeq_reaxff.cpp b/src/REAXFF/fix_qeq_reaxff.cpp index 704b43e642..5dc739d5e8 100644 --- a/src/REAXFF/fix_qeq_reaxff.cpp +++ b/src/REAXFF/fix_qeq_reaxff.cpp @@ -404,8 +404,6 @@ void FixQEqReaxFF::init() efield->init(); if (strcmp(update->unit_style,"real") != 0) error->all(FLERR,"Must use unit_style real with fix {} and external fields", style); - if (efield->varflag != FixEfield::CONSTANT) - error->all(FLERR,"Cannot (yet) use fix {} with variable efield", style); if (((fabs(efield->ex) > SMALL) && domain->xperiodic) || ((fabs(efield->ey) > SMALL) && domain->yperiodic) || @@ -1101,26 +1099,45 @@ void FixQEqReaxFF::get_chi_field() // efield energy is in real units of kcal/mol/angstrom, need to convert to eV - const double factor = -1.0/force->qe2f; + const double qe2f = force->qe2f; + const double factor = -1.0/qe2f; + + + if (efield->varflag != FixEfield::CONSTANT) { + efield->update_efield_variables(); + } - // currently we only support constant efield // atom selection is for the group of fix efield - if (efield->varflag == FixEfield::CONSTANT) { - double unwrap[3]; - const double fx = efield->ex; - const double fy = efield->ey; - const double fz = efield->ez; - const int efgroupbit = efield->groupbit; + double unwrap[3]; + const double ex = efield->ex; + const double ey = efield->ey; + const double ez = efield->ez; + const int efgroupbit = efield->groupbit; // charge interactions // force = qE, potential energy = F dot x in unwrapped coords - + if (efield->varflag != FixEfield::ATOM) { for (int i = 0; i < nlocal; i++) { if (mask[i] & efgroupbit) { if (region && !region->match(x[i][0],x[i][1],x[i][2])) continue; domain->unmap(x[i],image[i],unwrap); - chi_field[i] = factor*(fx*unwrap[0] + fy*unwrap[1] + fz*unwrap[2]); + chi_field[i] = factor*(ex*unwrap[0] + ey*unwrap[1] + ez*unwrap[2]); + } + } + } else { + for (int i = 0; i < nlocal; i++) { + if (mask[i] & efgroupbit) { + if (region && !region->match(x[i][0],x[i][1],x[i][2])) continue; + domain->unmap(x[i],image[i],unwrap); + double edisp = 0; // accumulate E dot displacement + edisp += unwrap[0]*( + (efield->xstyle == FixEfield::ATOM) ? qe2f*efield->efield[i][0] : ex); + edisp += unwrap[1]*( + (efield->ystyle == FixEfield::ATOM) ? qe2f*efield->efield[i][1] : ey); + edisp += unwrap[2]*( + (efield->zstyle == FixEfield::ATOM) ? qe2f*efield->efield[i][2] : ez); + chi_field[i] = factor*edisp; } } } diff --git a/src/fix_efield.cpp b/src/fix_efield.cpp index 7880655973..f1adc722ae 100644 --- a/src/fix_efield.cpp +++ b/src/fix_efield.cpp @@ -346,26 +346,7 @@ void FixEfield::post_force(int vflag) } else { - modify->clearstep_compute(); - - if (xstyle == EQUAL) { - ex = qe2f * input->variable->compute_equal(xvar); - } else if (xstyle == ATOM) { - input->variable->compute_atom(xvar, igroup, &efield[0][0], 4, 0); - } - if (ystyle == EQUAL) { - ey = qe2f * input->variable->compute_equal(yvar); - } else if (ystyle == ATOM) { - input->variable->compute_atom(yvar, igroup, &efield[0][1], 4, 0); - } - if (zstyle == EQUAL) { - ez = qe2f * input->variable->compute_equal(zvar); - } else if (zstyle == ATOM) { - input->variable->compute_atom(zvar, igroup, &efield[0][2], 4, 0); - } - if (estyle == ATOM) input->variable->compute_atom(evar, igroup, &efield[0][3], 4, 0); - - modify->addstep_compute(update->ntimestep + 1); + update_efield_variables(); // charge interactions // force = qE @@ -470,3 +451,32 @@ double FixEfield::compute_vector(int n) } return fsum_all[n + 1]; } + +/* ---------------------------------------------------------------------- + update efield variables without doing anything else + called by fix_qeq_reaxff +------------------------------------------------------------------------- */ + +void FixEfield::update_efield_variables() +{ + modify->clearstep_compute(); + + if (xstyle == EQUAL) { + ex = qe2f * input->variable->compute_equal(xvar); + } else if (xstyle == ATOM) { + input->variable->compute_atom(xvar, igroup, &efield[0][0], 4, 0); + } + if (ystyle == EQUAL) { + ey = qe2f * input->variable->compute_equal(yvar); + } else if (ystyle == ATOM) { + input->variable->compute_atom(yvar, igroup, &efield[0][1], 4, 0); + } + if (zstyle == EQUAL) { + ez = qe2f * input->variable->compute_equal(zvar); + } else if (zstyle == ATOM) { + input->variable->compute_atom(zvar, igroup, &efield[0][2], 4, 0); + } + if (estyle == ATOM) input->variable->compute_atom(evar, igroup, &efield[0][3], 4, 0); + + modify->addstep_compute(update->ntimestep + 1); +} diff --git a/src/fix_efield.h b/src/fix_efield.h index 52c827bb50..2bab26e140 100644 --- a/src/fix_efield.h +++ b/src/fix_efield.h @@ -59,6 +59,7 @@ class FixEfield : public Fix { int force_flag; double fsum[4], fsum_all[4]; + void update_efield_variables(); }; } // namespace LAMMPS_NS #endif From fe7a6fce296846e278233b2572f808d5da4eeb65 Mon Sep 17 00:00:00 2001 From: srtee Date: Wed, 17 May 2023 16:13:27 +1000 Subject: [PATCH 238/448] make QEQ work with atom-style potential --- src/REAXFF/fix_qeq_reaxff.cpp | 15 ++++-------- src/fix_efield.cpp | 45 ++++++++++++++++++++++++++--------- src/fix_efield.h | 5 ++-- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/REAXFF/fix_qeq_reaxff.cpp b/src/REAXFF/fix_qeq_reaxff.cpp index 5dc739d5e8..b25ce479cd 100644 --- a/src/REAXFF/fix_qeq_reaxff.cpp +++ b/src/REAXFF/fix_qeq_reaxff.cpp @@ -405,6 +405,9 @@ void FixQEqReaxFF::init() if (strcmp(update->unit_style,"real") != 0) error->all(FLERR,"Must use unit_style real with fix {} and external fields", style); + if (efield->varflag == FixEfield::ATOM && efield->pstyle != FixEfield::ATOM) + error->all(FLERR,"Atom-style external electric field requires atom-style " + "potential variable when used with fix {}", style); if (((fabs(efield->ex) > SMALL) && domain->xperiodic) || ((fabs(efield->ey) > SMALL) && domain->yperiodic) || ((fabs(efield->ez) > SMALL) && domain->zperiodic)) @@ -1125,19 +1128,11 @@ void FixQEqReaxFF::get_chi_field() chi_field[i] = factor*(ex*unwrap[0] + ey*unwrap[1] + ez*unwrap[2]); } } - } else { + } else { // must use atom-style potential from FixEfield for (int i = 0; i < nlocal; i++) { if (mask[i] & efgroupbit) { if (region && !region->match(x[i][0],x[i][1],x[i][2])) continue; - domain->unmap(x[i],image[i],unwrap); - double edisp = 0; // accumulate E dot displacement - edisp += unwrap[0]*( - (efield->xstyle == FixEfield::ATOM) ? qe2f*efield->efield[i][0] : ex); - edisp += unwrap[1]*( - (efield->ystyle == FixEfield::ATOM) ? qe2f*efield->efield[i][1] : ey); - edisp += unwrap[2]*( - (efield->zstyle == FixEfield::ATOM) ? qe2f*efield->efield[i][2] : ez); - chi_field[i] = factor*edisp; + chi_field[i] = -efield->efield[i][3]; } } } diff --git a/src/fix_efield.cpp b/src/fix_efield.cpp index f1adc722ae..f335d8a765 100644 --- a/src/fix_efield.cpp +++ b/src/fix_efield.cpp @@ -41,7 +41,7 @@ using namespace FixConst; FixEfield::FixEfield(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), xstr(nullptr), ystr(nullptr), zstr(nullptr), estr(nullptr), - idregion(nullptr), region(nullptr), efield(nullptr) + pstr(nullptr), idregion(nullptr), region(nullptr), efield(nullptr) { if (narg < 6) utils::missing_cmd_args(FLERR, std::string("fix ") + style, error); @@ -100,6 +100,14 @@ FixEfield::FixEfield(LAMMPS *lmp, int narg, char **arg) : } else error->all(FLERR, "Unsupported argument for fix {} energy command: {}", style, arg[iarg]); iarg += 2; + } else if (strcmp(arg[iarg], "potential") == 0) { + if (iarg + 2 > narg) + utils::missing_cmd_args(FLERR, std::string("fix ") + style + "potential", error); + if (utils::strmatch(arg[iarg + 1], "^v_")) { + pstr = utils::strdup(arg[iarg + 1] + 2); + } else + error->all(FLERR, "Unsupported argument for fix {} energy command: {}", style, arg[iarg]); + iarg += 2; } else { error->all(FLERR, "Unknown keyword for fix {} command: {}", style, arg[iarg]); } @@ -122,6 +130,7 @@ FixEfield::~FixEfield() delete[] ystr; delete[] zstr; delete[] estr; + delete[] pstr; delete[] idregion; memory->destroy(efield); } @@ -157,43 +166,55 @@ void FixEfield::init() if (xstr) { xvar = input->variable->find(xstr); - if (xvar < 0) error->all(FLERR, "Variable {} for fix {} does not exist", xstr, style); + if (xvar < 0) error->all(FLERR, "Variable {} for x-field in fix {} does not exist", xstr, style); if (input->variable->equalstyle(xvar)) xstyle = EQUAL; else if (input->variable->atomstyle(xvar)) xstyle = ATOM; else - error->all(FLERR, "Variable {} for fix {} is invalid style", xstr, style); + error->all(FLERR, "Variable {} for x-field in fix {} is invalid style", xstr, style); } if (ystr) { yvar = input->variable->find(ystr); - if (yvar < 0) error->all(FLERR, "Variable {} for fix {} does not exist", ystr, style); + if (yvar < 0) error->all(FLERR, "Variable {} for y-field in fix {} does not exist", ystr, style); if (input->variable->equalstyle(yvar)) ystyle = EQUAL; else if (input->variable->atomstyle(yvar)) ystyle = ATOM; else - error->all(FLERR, "Variable {} for fix {} is invalid style", ystr, style); + error->all(FLERR, "Variable {} for y-field in fix {} is invalid style", ystr, style); } if (zstr) { zvar = input->variable->find(zstr); - if (zvar < 0) error->all(FLERR, "Variable {} for fix {} does not exist", zstr, style); + if (zvar < 0) error->all(FLERR, "Variable {} for z-field in fix {} does not exist", zstr, style); if (input->variable->equalstyle(zvar)) zstyle = EQUAL; else if (input->variable->atomstyle(zvar)) zstyle = ATOM; else - error->all(FLERR, "Variable {} for fix {} is invalid style", zstr, style); + error->all(FLERR, "Variable {} for z-field in fix {} is invalid style", zstr, style); } if (estr) { evar = input->variable->find(estr); - if (evar < 0) error->all(FLERR, "Variable {} for fix {} does not exist", estr, style); + if (evar < 0) error->all(FLERR, "Variable {} for energy in fix {} does not exist", estr, style); if (input->variable->atomstyle(evar)) estyle = ATOM; else - error->all(FLERR, "Variable {} for fix {} is invalid style", estr, style); + error->all(FLERR, "Variable {} for energy in fix {} must be atom-style", estr, style); } else estyle = NONE; + if (pstr) { + pvar = input->variable->find(pstr); + if (pvar < 0) error->all(FLERR, "Variable {} for potential in fix {} does not exist", pstr, style); + if (input->variable->atomstyle(pvar)) + pstyle = ATOM; + else + error->all(FLERR, "Variable {} for potential in fix {} must be atom-style", pstr, style); + if (estyle != NONE) + error->warning(FLERR, "fix {} will ignore variable {} for energy " + "because atom-style potential has been specified", estr, style); + } else + pstyle = NONE; // set index and check validity of region @@ -376,7 +397,8 @@ void FixEfield::post_force(int vflag) } f[i][2] += fz; fsum[3] += fz; - if (estyle == ATOM) fsum[0] += efield[i][3]; + if (pstyle == ATOM) fsum[0] += qe2f * q[i] * efield[i][3]; + else if (estyle == ATOM) fsum[0] += efield[i][3]; } } @@ -476,7 +498,8 @@ void FixEfield::update_efield_variables() } else if (zstyle == ATOM) { input->variable->compute_atom(zvar, igroup, &efield[0][2], 4, 0); } - if (estyle == ATOM) input->variable->compute_atom(evar, igroup, &efield[0][3], 4, 0); + if (pstyle == ATOM) input->variable->compute_atom(pvar, igroup, &efield[0][3], 4, 0); + else if (estyle == ATOM) input->variable->compute_atom(evar, igroup, &efield[0][3], 4, 0); modify->addstep_compute(update->ntimestep + 1); } diff --git a/src/fix_efield.h b/src/fix_efield.h index 2bab26e140..72fd204898 100644 --- a/src/fix_efield.h +++ b/src/fix_efield.h @@ -46,10 +46,11 @@ class FixEfield : public Fix { protected: double ex, ey, ez; int varflag; - char *xstr, *ystr, *zstr, *estr; + char *xstr, *ystr, *zstr, *estr, *pstr; char *idregion; class Region *region; - int xvar, yvar, zvar, evar, xstyle, ystyle, zstyle, estyle; + int xvar, yvar, zvar, xstyle, ystyle, zstyle; + int evar, pvar, estyle, pstyle; int ilevel_respa; double qe2f; int qflag, muflag; From 36eb11f499d2ebfa896e14bd0caa8792561788ad Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sat, 20 May 2023 12:59:34 +0300 Subject: [PATCH 239/448] Include method for bond contribution & variables to compute_stress_mop.h --- src/EXTRA-COMPUTE/compute_stress_mop.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.h b/src/EXTRA-COMPUTE/compute_stress_mop.h index 5357d36371..c9f95c1996 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.h +++ b/src/EXTRA-COMPUTE/compute_stress_mop.h @@ -38,11 +38,13 @@ class ComputeStressMop : public Compute { private: void compute_pairs(); + void compute_bonds(); int me, nvalues, dir; int *which; double *values_local, *values_global; + double *bond_local, *bond_global; double pos, pos1, dt, nktv2p, ftm2v; double area; class NeighList *list; From 5da65bbd0a158e89b06e959a17cde3af02474d71 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sat, 20 May 2023 13:06:19 +0300 Subject: [PATCH 240/448] Code for bond contribution to stress/mop --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 137 ++++++++++++++++++++++- 1 file changed, 132 insertions(+), 5 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 60f2d76e06..7900a62bef 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -19,10 +19,13 @@ #include "compute_stress_mop.h" #include "atom.h" +#include "atom_vec.h" +#include "bond.h" #include "domain.h" #include "error.h" #include "force.h" #include "memory.h" +#include "molecule.h" #include "neigh_list.h" #include "neighbor.h" #include "pair.h" @@ -118,12 +121,16 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : // Initialize some variables values_local = values_global = vector = nullptr; + bond_local = nullptr; + bond_global = nullptr; // this fix produces a global vector memory->create(vector,nvalues,"stress/mop:vector"); memory->create(values_local,nvalues,"stress/mop/spatial:values_local"); memory->create(values_global,nvalues,"stress/mop/spatial:values_global"); + memory->create(bond_local,nvalues,"stress/mop/spatial:bond_local"); + memory->create(bond_global,nvalues,"stress/mop/spatial:bond_global"); size_vector = nvalues; vector_flag = 1; @@ -140,6 +147,8 @@ ComputeStressMop::~ComputeStressMop() memory->destroy(values_local); memory->destroy(values_global); + memory->destroy(bond_local); + memory->destroy(bond_global); memory->destroy(vector); } @@ -185,8 +194,8 @@ void ComputeStressMop::init() //Compute stress/mop only accounts for pair interactions. // issue a warning if any intramolecular potential or Kspace is defined. - if (force->bond!=nullptr) - error->warning(FLERR,"compute stress/mop does not account for bond potentials"); + //if (force->bond!=nullptr) + // error->warning(FLERR,"compute stress/mop does not account for bond potentials"); if (force->angle!=nullptr) error->warning(FLERR,"compute stress/mop does not account for angle potentials"); if (force->dihedral!=nullptr) @@ -224,9 +233,14 @@ void ComputeStressMop::compute_vector() MPI_Allreduce(values_local,values_global,nvalues, MPI_DOUBLE,MPI_SUM,world); - int m; - for (m=0; mx; + tagint *tag = atom->tag; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + int *mask = atom->mask; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + int molecular = atom->molecular; + + Bond *bond = force->bond; + + double dx[3] {0}; + double x_bond_1[3] {0}; + double x_bond_2[3] {0}; + double local_contribution[3] {0}; + + // initialization + for (int i {0}; i < nvalues; i++) bond_local[i] = 0.0; + + // loop over all bonded atoms in the current proc + for (atom1 = 0; atom1 < nlocal; atom1++) { + if (!(mask[atom1] & groupbit)) continue; + + if (molecular == 1) + nb = num_bond[atom1]; + else { + if (molindex[atom1] < 0) continue; + imol = molindex[atom1]; + iatom = molatom[atom1]; + nb = onemols[imol]->num_bond[iatom]; + } + + for (i = 0; i < nb; i++) { + if (molecular == 1) { + btype = bond_type[atom1][i]; + atom2 = atom->map(bond_atom[atom1][i]); + } else { + tagprev = tag[atom1] - iatom - 1; + btype = onemols[imol]->bond_type[iatom][i]; + atom2 = atom->map(onemols[imol]->bond_atom[iatom][i] + tagprev); + } + + if (atom2 < 0 || !(mask[atom2] & groupbit)) continue; + if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; + if (btype <= 0) continue; + + // minimum image of atom1 with respect to the plane of interest + dx[0] = x[atom1][0]; + dx[1] = x[atom1][1]; + dx[2] = x[atom1][2]; + dx[dir] -= pos; + domain->minimum_image(dx[0], dx[1], dx[2]); + x_bond_1[0] = dx[0]; + x_bond_1[1] = dx[1]; + x_bond_1[2] = dx[2]; + x_bond_1[dir] += pos; + + // minimum image of atom2 with respect to atom1 + dx[0] = x[atom2][0] - x_bond_1[0]; + dx[1] = x[atom2][1] - x_bond_1[1]; + dx[2] = x[atom2][2] - x_bond_1[2]; + domain->minimum_image(dx[0], dx[1], dx[2]); + x_bond_2[0] = x_bond_1[0] + dx[0]; + x_bond_2[1] = x_bond_1[1] + dx[1]; + x_bond_2[2] = x_bond_1[2] + dx[2]; + + // check if the bond vector crosses the plane of interest + double tau = (x_bond_1[dir] - pos) / (x_bond_1[dir] - x_bond_2[dir]); + if ((tau <= 1) and (tau >= 0)) + { + //std::cout << "I have found one crossing bond " << tau << std::endl; + dx[0] = x_bond_1[0] - x_bond_2[0]; + dx[1] = x_bond_1[1] - x_bond_2[1]; + dx[2] = x_bond_1[2] - x_bond_2[2]; + rsq = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + bond->single(btype, rsq, atom1, atom2, fpair); + + // check the correct contribution with the + or - sign + local_contribution[0] += fpair*dx[0]/area*nktv2p; + local_contribution[1] += fpair*dx[1]/area*nktv2p; + local_contribution[2] += fpair*dx[2]/area*nktv2p; + } + } + } + + // loop over the keywords and if necessary add the bond contribution + int m {0}; + while (m Date: Sat, 20 May 2023 15:12:42 +0300 Subject: [PATCH 241/448] Update compute_stress_mop.cpp --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 7900a62bef..89ef4e8b2b 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -525,16 +525,13 @@ void ComputeStressMop::compute_bonds() // check if the bond vector crosses the plane of interest double tau = (x_bond_1[dir] - pos) / (x_bond_1[dir] - x_bond_2[dir]); - if ((tau <= 1) and (tau >= 0)) - { - //std::cout << "I have found one crossing bond " << tau << std::endl; + if ((tau <= 1) and (tau >= 0)) { dx[0] = x_bond_1[0] - x_bond_2[0]; dx[1] = x_bond_1[1] - x_bond_2[1]; dx[2] = x_bond_1[2] - x_bond_2[2]; rsq = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; bond->single(btype, rsq, atom1, atom2, fpair); - // check the correct contribution with the + or - sign local_contribution[0] += fpair*dx[0]/area*nktv2p; local_contribution[1] += fpair*dx[1]/area*nktv2p; local_contribution[2] += fpair*dx[2]/area*nktv2p; @@ -552,5 +549,4 @@ void ComputeStressMop::compute_bonds() } m += 3; } - return; } From 1d7a6f813bd623ba1d483da70e13d1c40ef24a43 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sat, 20 May 2023 15:14:47 +0300 Subject: [PATCH 242/448] Update compute_stress_mop.cpp --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 89ef4e8b2b..8391622242 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -525,7 +525,7 @@ void ComputeStressMop::compute_bonds() // check if the bond vector crosses the plane of interest double tau = (x_bond_1[dir] - pos) / (x_bond_1[dir] - x_bond_2[dir]); - if ((tau <= 1) and (tau >= 0)) { + if ((tau <= 1) && (tau >= 0)) { dx[0] = x_bond_1[0] - x_bond_2[0]; dx[1] = x_bond_1[1] - x_bond_2[1]; dx[2] = x_bond_1[2] - x_bond_2[2]; From 3822e6ff0f6f9eb500ed0a02d74001bb31da309c Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sun, 21 May 2023 10:29:24 +0800 Subject: [PATCH 243/448] add potential file that parameterized against with DMC reference data --- potentials/COH.DMC.ILP | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100755 potentials/COH.DMC.ILP diff --git a/potentials/COH.DMC.ILP b/potentials/COH.DMC.ILP new file mode 100755 index 0000000000..7235afcdab --- /dev/null +++ b/potentials/COH.DMC.ILP @@ -0,0 +1,28 @@ +# DATE: 2023-05-18 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127, 8704 (2023). +# Interlayer Potential (ILP) for water/graphene heterojunctions +# The parameters below are fitted against the DMC reference data that rescaled from PBE+MBD-NL. +# +# ----------------- Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ +# beta(A) alpha delta(A) epsilon(meV) C(meV) d sR reff(A) C6(meV*A^6) S rcut +# For graphene and hydrocarbons +C C 3.205843 7.511126 1.235334 1.528338E-5 37.530428 15.499947 0.7954443 3.681440 25.714535E3 1.0 2.0 +H H 3.974540 6.53799 1.080633 0.6700556 0.8333833 15.022371 0.7490632 2.767223 1.6159581E3 1.0 1.2 +C H 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 +H C 2.642950 12.91410 1.020257 0.9750012 25.340996 15.222927 0.8115998 3.887324 5.6874617E3 1.0 1.5 + +# For water-graphene +C Ow 4.03686677 15.09817069 1.00000323 1.03838111 0.16372013 9.00010553 1.12057182 2.96484087 21887.14173222 1.0 2.0 +C Hw 3.08246994 6.412090180 1.00000265 2.89390420 -1.85748759 9.00009101 1.04574423 2.21642099 4652.78021666 1.0 2.0 +Ow C 4.03686677 15.09817069 1.00000323 1.03838111 0.16372013 9.00010553 1.12057182 2.96484087 21887.14173222 1.0 1.2 +Hw C 3.08246994 6.412090180 1.00000265 2.89390420 -1.85748759 9.00009101 1.04574423 2.21642099 4652.78021666 1.0 1.2 + +# # The ILPs for other systems are set to zero +H Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +H Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Ow H 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Hw H 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 + +Ow Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Hw Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Ow Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 +Hw Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 \ No newline at end of file From 91ac9ef3fc4c88ddcb7b1356a62c3c927535fb2c Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sun, 21 May 2023 11:29:28 +0800 Subject: [PATCH 244/448] update doc file --- doc/src/pair_ilp_water_2dm.rst | 170 +++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 doc/src/pair_ilp_water_2dm.rst diff --git a/doc/src/pair_ilp_water_2dm.rst b/doc/src/pair_ilp_water_2dm.rst new file mode 100644 index 0000000000..82cf1a6580 --- /dev/null +++ b/doc/src/pair_ilp_water_2dm.rst @@ -0,0 +1,170 @@ +.. index:: pair_style ilp/water/2dm +.. index:: pair_style ilp/water/2dm/opt + +pair_style ilp/tmd command +=================================== + +Accelerator Variant: *ilp/water/2dm/opt* + +Syntax +"""""" + +.. code-block:: LAMMPS + + pair_style [hybrid/overlay ...] ilp/tmd cutoff tap_flag + +* cutoff = global cutoff (distance units) +* tap_flag = 0/1 to turn off/on the taper function + +Examples +"""""""" + +.. code-block:: LAMMPS + + pair_style hybrid/overlay ilp/water/2dm 16.0 1 + pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw + + pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 + pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O + pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H + pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H + pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw + +Description +""""""""""" + +.. versionadded:: xxxx2023 + +The *ilp/water/2dm* style computes the registry-dependent interlayer +potential (ILP) potential for interfaces of water with two-dimensinal (2D) +materials as described in :ref:`(Feng) `. + +.. math:: + + E = & \frac{1}{2} \sum_i \sum_{j \neq i} V_{ij} \\ + V_{ij} = & {\rm Tap}(r_{ij})\left \{ e^{-\alpha (r_{ij}/\beta -1)} + \left [ \epsilon + f(\rho_{ij}) + f(\rho_{ji})\right ] - + \frac{1}{1+e^{-d\left [ \left ( r_{ij}/\left (s_R \cdot r^{eff} \right ) \right )-1 \right ]}} + \cdot \frac{C_6}{r^6_{ij}} \right \}\\ + \rho_{ij}^2 = & r_{ij}^2 - ({\bf r}_{ij} \cdot {\bf n}_i)^2 \\ + \rho_{ji}^2 = & r_{ij}^2 - ({\bf r}_{ij} \cdot {\bf n}_j)^2 \\ + f(\rho) = & C e^{ -( \rho / \delta )^2 } \\ + {\rm Tap}(r_{ij}) = & 20\left ( \frac{r_{ij}}{R_{cut}} \right )^7 - + 70\left ( \frac{r_{ij}}{R_{cut}} \right )^6 + + 84\left ( \frac{r_{ij}}{R_{cut}} \right )^5 - + 35\left ( \frac{r_{ij}}{R_{cut}} \right )^4 + 1 + +Where :math:`\mathrm{Tap}(r_{ij})` is the taper function which provides +a continuous cutoff (up to third derivative) for interatomic separations +larger than :math:`r_c` :doc:`pair_style ilp_graphene_hbn `. + +It is important to include all the pairs to build the neighbor list for +calculating the normals. + +.. note:: + + Since each water molecule contains one oxygen atom and two hydrogen atoms, + a new definition is proposed (see In :ref:`(Feng) `),the atomic + normal vectors of hydrogen atoms are assumed to lie along the corresponding + oxygen-hydrogen bonds and the normal vector of the central oxygen atom + is defined as their average. + +The parameter file (e.g. COH.ILP), is intended for use with *metal* +:doc:`units `, with energies in meV. Two additional parameters, +*S*, and *rcut* are included in the parameter file. *S* is designed to +facilitate scaling of energies. *rcut* is designed to build the neighbor +list for calculating the normals for each atom pair. + +.. note:: + + The parameters presented in the parameter file (e.g. COH.ILP), + are fitted with taper function by setting the cutoff equal to 16.0 + Angstrom. Using different cutoff or taper function should be careful. + These parameters provide a good description in both short- and long-range + interaction regimes. This feature is essential for simulations in high pressure + regime (i.e., the interlayer distance is smaller than the equilibrium + distance). + +This potential must be used in combination with hybrid/overlay. +Other interactions can be set to zero using pair_style *none*\ . + +This pair style tallies a breakdown of the total interlayer potential +energy into sub-categories, which can be accessed via the :doc:`compute pair ` command as a vector of values of length 2. +The 2 values correspond to the following sub-categories: + +1. *E_vdW* = vdW (attractive) energy +2. *E_Rep* = Repulsive energy + +To print these quantities to the log file (with descriptive column +headings) the following commands could be included in an input script: + +.. code-block:: LAMMPS + + compute 0 all pair ilp/water/2dm + variable Evdw equal c_0[1] + variable Erep equal c_0[2] + thermo_style custom step temp epair v_Erep v_Evdw + +---------- + +.. include:: accel_styles.rst + +---------- + +Mixing, shift, table, tail correction, restart, rRESPA info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +This pair style does not support the pair_modify mix, shift, table, and +tail options. + +This pair style does not write their information to binary restart +files, since it is stored in potential files. Thus, you need to +re-specify the pair_style and pair_coeff commands in an input script +that reads a restart file. + +Restrictions +"""""""""""" + +This pair style is part of the INTERLAYER package. It is only enabled +if LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +This pair style requires the newton setting to be *on* for pair +interactions. + +The COH.ILP potential file provided with LAMMPS (see the potentials +directory) are parameterized for *metal* units. You can use this +potential with any LAMMPS units, but you would need to create your +COH.ILP potential file with coefficients listed in the appropriate +units, if your simulation does not use *metal* units. + +Related commands +"""""""""""""""" + +:doc:`pair_coeff `, +:doc:`pair_none `, +:doc:`pair_style hybrid/overlay `, +:doc:`pair_style drip `, +:doc:`pair_style ilp_tmd `, +:doc:`pair_style saip_metal `, +:doc:`pair_style ilp_graphene_hbn `, +:doc:`pair_style pair_kolmogorov_crespi_z `, +:doc:`pair_style pair_kolmogorov_crespi_full `, +:doc:`pair_style pair_lebedeva_z `, +:doc:`pair_style pair_coul_shield `. + +Default +""""""" + +tap_flag = 1 + + +---------- + +.. _Feng: + +<<<<<<< HEAD +**(Feng)** Z. Feng and W. Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023). +======= +**(Feng)** Z. Feng and W. Ouyang et al., J. Phys. Chem. C. 127, 8704-8713 (2023). +>>>>>>> 0334ddb7c69a36b33757694b905820f56d8b90f2 From 685255083efaed1049724351fdfc33193ee493a5 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sun, 21 May 2023 11:43:39 +0800 Subject: [PATCH 245/448] clean the duplicate info --- doc/src/pair_ilp_water_2dm.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/doc/src/pair_ilp_water_2dm.rst b/doc/src/pair_ilp_water_2dm.rst index 82cf1a6580..6a364f38ed 100644 --- a/doc/src/pair_ilp_water_2dm.rst +++ b/doc/src/pair_ilp_water_2dm.rst @@ -162,9 +162,4 @@ tap_flag = 1 ---------- .. _Feng: - -<<<<<<< HEAD -**(Feng)** Z. Feng and W. Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023). -======= **(Feng)** Z. Feng and W. Ouyang et al., J. Phys. Chem. C. 127, 8704-8713 (2023). ->>>>>>> 0334ddb7c69a36b33757694b905820f56d8b90f2 From d190249e98b40e17995d6d96dad06533e6ad28ca Mon Sep 17 00:00:00 2001 From: srtee Date: Mon, 22 May 2023 00:10:01 +1000 Subject: [PATCH 246/448] add documentation and checks --- doc/src/fix_efield.rst | 26 +++++++++++++++++++++++--- doc/src/fix_qeq_reaxff.rst | 10 +++++++--- src/REAXFF/fix_qeq_reaxff.cpp | 5 +++++ src/fix_efield.cpp | 6 ++++-- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/doc/src/fix_efield.rst b/doc/src/fix_efield.rst index e72510e4da..271912097f 100644 --- a/doc/src/fix_efield.rst +++ b/doc/src/fix_efield.rst @@ -19,7 +19,7 @@ Syntax * ex,ey,ez = E-field component values (electric field units) * any of ex,ey,ez can be a variable (see below) * zero or more keyword/value pairs may be appended to args -* keyword = *region* or *energy* +* keyword = *region* or *energy* or *potential* .. parsed-literal:: @@ -27,6 +27,8 @@ Syntax region-ID = ID of region atoms must be in to have added force *energy* value = v_name v_name = variable with name that calculates the potential energy of each atom in the added E-field + *potential* value = v_name + v_name = variable with name that calculates the electric potential of each atom in the added E-field (overrides *energy*) Examples """""""" @@ -112,7 +114,8 @@ one or more variables, and if you are performing dynamics via the :doc:`run ` command. If the keyword is not used, LAMMPS will set the energy to 0.0, which is typically fine for dynamics. -The *energy* keyword is required if the added force is defined with +The *energy* keyword (or *potential* keyword, described below) +is required if the added force is defined with one or more variables, and you are performing energy minimization via the "minimize" command for charged particles. It is not required for point-dipoles, but a warning is issued since the minimizer in LAMMPS @@ -122,7 +125,7 @@ minimize the orientation of dipoles in an applied electric field. The *energy* keyword specifies the name of an atom-style :doc:`variable ` which is used to compute the energy of each atom as function of its position. Like variables used for *ex*, -*ey*, *ez*, the energy variable is specified as v_name, where name +*ey*, *ez*, the energy variable is specified as "v_name", where "name" is the variable name. Note that when the *energy* keyword is used during an energy @@ -133,6 +136,23 @@ due to the electric field were a spring-like F = kx, then the energy formula should be E = -0.5kx\^2. If you don't do this correctly, the minimization will not converge properly. +The *potential* keyword can be used as an alternative to the *energy* +keyword to specify the name of an atom-style variable, which is used to compute +the added electric potential to each atom as a function of its position. +The variable should have units of electric field times distance (that is, +in `units real`, the potential should be in volts). As with the *energy* +keyword, the variable name is specified as "v_name". The energy added by this +fix is then calculated as the electric potential multiplied by charge. + +The *potential* keyword is mainly intended for correct charge equilibration +in simulations with :doc:`fix qeq/reaxff`, since with variable +charges the electric potential can be known beforehand but the energy cannot. +A small additional benefit is that the *energy* keyword requires an additional +conversion to energy units which the *potential* keyword avoids. Thus, when the +*potential* keyword is specified the *energy* keyword is ignored (the simulation +will proceed but with a warning issued). As with *energy*, the *potential* +keyword is not allowed if the added field is a constant vector. + ---------- Restart, fix_modify, output, run start/stop, minimize info diff --git a/doc/src/fix_qeq_reaxff.rst b/doc/src/fix_qeq_reaxff.rst index db9015f187..4422ddc89c 100644 --- a/doc/src/fix_qeq_reaxff.rst +++ b/doc/src/fix_qeq_reaxff.rst @@ -128,9 +128,13 @@ periodic cell dimensions less than 10 Angstroms. This fix may be used in combination with :doc:`fix efield ` and will apply the external electric field during charge equilibration, -but there may be only one fix efield instance used, it may only use a -constant electric field, and the electric field vector may only have -components in non-periodic directions. +but there may be only one fix efield instance used and the electric field +vector may only have components in non-periodic directions. Equal-style +variables can be used for electric field vector components without any further +settings. Atom-style variables can be used for spatially-varying electric field +vector components, but the resulting electric potential must be specified +as an atom-style variable using the (new) *potential* keyword for +`fix efield`. Related commands """""""""""""""" diff --git a/src/REAXFF/fix_qeq_reaxff.cpp b/src/REAXFF/fix_qeq_reaxff.cpp index b25ce479cd..4c0864ac27 100644 --- a/src/REAXFF/fix_qeq_reaxff.cpp +++ b/src/REAXFF/fix_qeq_reaxff.cpp @@ -408,6 +408,11 @@ void FixQEqReaxFF::init() if (efield->varflag == FixEfield::ATOM && efield->pstyle != FixEfield::ATOM) error->all(FLERR,"Atom-style external electric field requires atom-style " "potential variable when used with fix {}", style); + if (((efield->xstyle != FixEfield::CONSTANT) && domain->xperiodic) || + ((efield->ystyle != FixEfield::CONSTANT) && domain->yperiodic) || + ((efield->zstyle != FixEfield::CONSTANT) && domain->zperiodic)) + error->all(FLERR,"Must not have electric field component in direction of periodic " + "boundary when using charge equilibration with ReaxFF."); if (((fabs(efield->ex) > SMALL) && domain->xperiodic) || ((fabs(efield->ey) > SMALL) && domain->yperiodic) || ((fabs(efield->ez) > SMALL) && domain->zperiodic)) diff --git a/src/fix_efield.cpp b/src/fix_efield.cpp index f335d8a765..d2c0dc1ef6 100644 --- a/src/fix_efield.cpp +++ b/src/fix_efield.cpp @@ -238,8 +238,10 @@ void FixEfield::init() if (varflag == CONSTANT && estyle != NONE) error->all(FLERR, "Cannot use variable energy with constant efield in fix {}", style); - if ((varflag == EQUAL || varflag == ATOM) && update->whichflag == 2 && estyle == NONE) - error->all(FLERR, "Must use variable energy with fix {}", style); + if (varflag == CONSTANT && pstyle != NONE) + error->all(FLERR, "Cannot use variable potential with constant efield in fix {}", style); + if ((varflag == EQUAL || varflag == ATOM) && update->whichflag == 2 && estyle == NONE && pstyle == NONE) + error->all(FLERR, "Must use variable energy or potential with fix {} during minimization", style); if (utils::strmatch(update->integrate_style, "^respa")) { ilevel_respa = (dynamic_cast(update->integrate))->nlevels - 1; From 0510ce73727a52b9b07909f5a8aa995365150eb4 Mon Sep 17 00:00:00 2001 From: Jonathan Willman Date: Tue, 23 May 2023 12:29:25 -0400 Subject: [PATCH 247/448] Carbon SNAP potential and example added --- .../C_SNAP_2021.10.15.quadratic.snapcoeff | 1602 +++++++++++++++++ .../C_SNAP_2021.10.15.quadratic.snapparam | 10 + examples/snap/in.C_SNAP | 35 + examples/snap/log.23May23.C_SNAP | 136 ++ examples/snap/pot_C.mod | 12 + .../C_SNAP_2021.10.15.quadratic.snapcoeff | 1602 +++++++++++++++++ .../C_SNAP_2021.10.15.quadratic.snapparam | 10 + 7 files changed, 3407 insertions(+) create mode 100644 examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff create mode 100644 examples/snap/C_SNAP_2021.10.15.quadratic.snapparam create mode 100644 examples/snap/in.C_SNAP create mode 100644 examples/snap/log.23May23.C_SNAP create mode 100644 examples/snap/pot_C.mod create mode 100644 potentials/C_SNAP_2021.10.15.quadratic.snapcoeff create mode 100644 potentials/C_SNAP_2021.10.15.quadratic.snapparam diff --git a/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff b/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff new file mode 100644 index 0000000000..4db83060f7 --- /dev/null +++ b/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff @@ -0,0 +1,1602 @@ +#Carbon SNAP generated on 2021-10-15 08:21:38.396384 +#UNITS: metal CONTRIBUTOR: Ivan Oleynik CITATION: Jonathan T. Willman, Kien Nguyen-Cong, Ashley S. Williams, Anatoly B. Belonoshko, Stan G. Moore, Aidan P. Thompson, Mitchell A. Wood, and Ivan I. Oleynik, "Machine learning interatomic potential for simulations of carbon at extreme conditions" Phys. Rev. B 106, L180101 (2022) +1 1596 +C 0.5 1.0 + -2.7758927591660334 # B[0] + 0.00859216942217639126 # B[1, 0, 0, 0] + 0.16638458601459194 # B[2, 1, 0, 1] + 0.22261822339506554 # B[3, 1, 1, 2] + 0.257355166247009937 # B[4, 2, 0, 2] + 0.802105904460230779 # B[5, 2, 1, 3] + 0.227216469467176801 # B[6, 2, 2, 2] + 0.494646284119575508 # B[7, 2, 2, 4] + 0.276718638025069574 # B[8, 3, 0, 3] + 1.09101782892605392 # B[9, 3, 1, 4] + 0.775283725099378151 # B[10, 3, 2, 3] + -0.232869556477520168 # B[11, 3, 2, 5] + 0.188466708736270222 # B[12, 3, 3, 4] + -0.213463540195325957 # B[13, 3, 3, 6] + 0.285049005401720568 # B[14, 4, 0, 4] + -0.248039138369940321 # B[15, 4, 1, 5] + -0.017694405190132434 # B[16, 4, 2, 4] + -0.513770238875468355 # B[17, 4, 2, 6] + -0.603368424950793791 # B[18, 4, 3, 5] + -0.4245149972360448 # B[19, 4, 3, 7] + -0.149612637312833391 # B[20, 4, 4, 4] + -0.153415086019898006 # B[21, 4, 4, 6] + -0.14513624400298164 # B[22, 4, 4, 8] + -0.0460661393681677661 # B[23, 5, 0, 5] + -0.0512559726916635844 # B[24, 5, 1, 6] + -0.125285455697324882 # B[25, 5, 2, 5] + -0.297464016341802473 # B[26, 5, 2, 7] + -0.219930176940332595 # B[27, 5, 3, 6] + -0.195418601625407001 # B[28, 5, 3, 8] + -0.236454956825408069 # B[29, 5, 4, 5] + -0.247483318285177556 # B[30, 5, 4, 7] + 0.108404148378543994 # B[31, 5, 5, 6] + 0.102786344334006338 # B[32, 5, 5, 8] + -0.0174963987262215619 # B[33, 6, 0, 6] + -0.347663919737827065 # B[34, 6, 1, 7] + -0.308777238806140442 # B[35, 6, 2, 6] + -0.30366671620990171 # B[36, 6, 2, 8] + -0.190992135157848048 # B[37, 6, 3, 7] + -0.212717125362634818 # B[38, 6, 4, 6] + -0.127682310305149815 # B[39, 6, 4, 8] + 0.128955786755968027 # B[40, 6, 5, 7] + 0.108121871413745185 # B[41, 6, 6, 6] + 0.0951564970231452284 # B[42, 6, 6, 8] + -0.0443430969083889667 # B[43, 7, 0, 7] + 0.0394012265947801602 # B[44, 7, 1, 8] + 0.0238287662182333909 # B[45, 7, 2, 7] + -0.0703216614205220136 # B[46, 7, 3, 8] + -0.0229748587995626564 # B[47, 7, 4, 7] + 0.461615758896215367 # B[48, 7, 5, 8] + 0.032037855993324961 # B[49, 7, 6, 7] + 0.105399776101016598 # B[50, 7, 7, 8] + -0.0452778356788145764 # B[51, 8, 0, 8] + -0.0400452652333231421 # B[52, 8, 2, 8] + -0.152415456089667084 # B[53, 8, 4, 8] + 0.0303383368396002995 # B[54, 8, 6, 8] + 0.0660845112300222914 # B[55, 8, 8, 8] + 5.0022584003536763e-06 # B[55, [1, 0, 0, 0], [1, 0, 0, 0]] + 7.12434860521689133e-05 # B[56, [1, 0, 0, 0], [2, 1, 0, 1]] + 0.00410559459459784552 # B[57, [1, 0, 0, 0], [3, 1, 1, 2]] + -0.000152151102822628559 # B[58, [1, 0, 0, 0], [4, 2, 0, 2]] + -0.00104851962847402839 # B[59, [1, 0, 0, 0], [5, 2, 1, 3]] + 0.00174544590749468355 # B[60, [1, 0, 0, 0], [6, 2, 2, 2]] + -0.00039686396723943862 # B[61, [1, 0, 0, 0], [7, 2, 2, 4]] + 0.000344474173032960351 # B[62, [1, 0, 0, 0], [8, 3, 0, 3]] + 5.77832175303926235e-05 # B[63, [1, 0, 0, 0], [9, 3, 1, 4]] + 0.00124014860085090543 # B[64, [1, 0, 0, 0], [10, 3, 2, 3]] + 1.92520730655986946e-05 # B[65, [1, 0, 0, 0], [11, 3, 2, 5]] + -0.000659022869027497959 # B[66, [1, 0, 0, 0], [12, 3, 3, 4]] + -0.000296998157394604001 # B[67, [1, 0, 0, 0], [13, 3, 3, 6]] + 2.13348987737616014e-06 # B[68, [1, 0, 0, 0], [14, 4, 0, 4]] + -0.000377679899824956422 # B[69, [1, 0, 0, 0], [15, 4, 1, 5]] + 0.00045743496488695988 # B[70, [1, 0, 0, 0], [16, 4, 2, 4]] + -0.00047978616167941926 # B[71, [1, 0, 0, 0], [17, 4, 2, 6]] + -0.000346601408372410741 # B[72, [1, 0, 0, 0], [18, 4, 3, 5]] + -0.000216752459512900564 # B[73, [1, 0, 0, 0], [19, 4, 3, 7]] + -0.000153945954064437646 # B[74, [1, 0, 0, 0], [20, 4, 4, 4]] + 0.00029484781857681483 # B[75, [1, 0, 0, 0], [21, 4, 4, 6]] + 1.59236973873017051e-05 # B[76, [1, 0, 0, 0], [22, 4, 4, 8]] + -2.35544935613951623e-05 # B[77, [1, 0, 0, 0], [23, 5, 0, 5]] + 0.000492019807872501325 # B[78, [1, 0, 0, 0], [24, 5, 1, 6]] + 0.000376700986017126233 # B[79, [1, 0, 0, 0], [25, 5, 2, 5]] + -0.000185900021989794662 # B[80, [1, 0, 0, 0], [26, 5, 2, 7]] + 0.000219939447169378507 # B[81, [1, 0, 0, 0], [27, 5, 3, 6]] + -0.000192198129806066265 # B[82, [1, 0, 0, 0], [28, 5, 3, 8]] + 0.000175514531344928004 # B[83, [1, 0, 0, 0], [29, 5, 4, 5]] + 0.000261949015135925535 # B[84, [1, 0, 0, 0], [30, 5, 4, 7]] + 0.00021011408484750832 # B[85, [1, 0, 0, 0], [31, 5, 5, 6]] + -7.47807464450689352e-05 # B[86, [1, 0, 0, 0], [32, 5, 5, 8]] + -1.36809205491805752e-05 # B[87, [1, 0, 0, 0], [33, 6, 0, 6]] + 0.000493576806965066728 # B[88, [1, 0, 0, 0], [34, 6, 1, 7]] + 0.000216301405824667614 # B[89, [1, 0, 0, 0], [35, 6, 2, 6]] + -0.000364540437645548276 # B[90, [1, 0, 0, 0], [36, 6, 2, 8]] + -0.000251411532179113273 # B[91, [1, 0, 0, 0], [37, 6, 3, 7]] + 3.19331690196988927e-05 # B[92, [1, 0, 0, 0], [38, 6, 4, 6]] + -1.56092571080845843e-05 # B[93, [1, 0, 0, 0], [39, 6, 4, 8]] + 2.4859429830464963e-05 # B[94, [1, 0, 0, 0], [40, 6, 5, 7]] + -5.06306418207175257e-05 # B[95, [1, 0, 0, 0], [41, 6, 6, 6]] + -9.75742047871729079e-05 # B[96, [1, 0, 0, 0], [42, 6, 6, 8]] + -4.07774117821002591e-05 # B[97, [1, 0, 0, 0], [43, 7, 0, 7]] + 0.000169705539551909257 # B[98, [1, 0, 0, 0], [44, 7, 1, 8]] + 0.000261792097012429614 # B[99, [1, 0, 0, 0], [45, 7, 2, 7]] + 0.000235813389494382575 # B[100, [1, 0, 0, 0], [46, 7, 3, 8]] + 3.69194385055615637e-05 # B[101, [1, 0, 0, 0], [47, 7, 4, 7]] + 0.000101832840349036502 # B[102, [1, 0, 0, 0], [48, 7, 5, 8]] + 1.87768621704026417e-05 # B[103, [1, 0, 0, 0], [49, 7, 6, 7]] + 6.90123641682582889e-05 # B[104, [1, 0, 0, 0], [50, 7, 7, 8]] + 3.82281861928956967e-05 # B[105, [1, 0, 0, 0], [51, 8, 0, 8]] + 0.00044905358698343889 # B[106, [1, 0, 0, 0], [52, 8, 2, 8]] + 3.83170337754923374e-05 # B[107, [1, 0, 0, 0], [53, 8, 4, 8]] + -4.53472261485315942e-05 # B[108, [1, 0, 0, 0], [54, 8, 6, 8]] + -0.000105793544360549552 # B[109, [1, 0, 0, 0], [55, 8, 8, 8]] + -0.00542851209933992596 # B[110, [2, 1, 0, 1], [2, 1, 0, 1]] + -0.00800035055604917701 # B[111, [2, 1, 0, 1], [3, 1, 1, 2]] + 0.000279580761847972054 # B[112, [2, 1, 0, 1], [4, 2, 0, 2]] + -0.0132643544617690821 # B[113, [2, 1, 0, 1], [5, 2, 1, 3]] + -0.00300637860380324968 # B[114, [2, 1, 0, 1], [6, 2, 2, 2]] + 0.00343216933390476549 # B[115, [2, 1, 0, 1], [7, 2, 2, 4]] + 6.39026040622058672e-05 # B[116, [2, 1, 0, 1], [8, 3, 0, 3]] + -0.0124005148347727506 # B[117, [2, 1, 0, 1], [9, 3, 1, 4]] + -0.0036690465725984691 # B[118, [2, 1, 0, 1], [10, 3, 2, 3]] + -0.0066468850826254932 # B[119, [2, 1, 0, 1], [11, 3, 2, 5]] + -0.00518212543330048934 # B[120, [2, 1, 0, 1], [12, 3, 3, 4]] + -0.00269613907034030407 # B[121, [2, 1, 0, 1], [13, 3, 3, 6]] + -0.000330193583102013615 # B[122, [2, 1, 0, 1], [14, 4, 0, 4]] + -0.000429062486184235686 # B[123, [2, 1, 0, 1], [15, 4, 1, 5]] + -0.000991704717453613382 # B[124, [2, 1, 0, 1], [16, 4, 2, 4]] + 0.00152944521177345071 # B[125, [2, 1, 0, 1], [17, 4, 2, 6]] + -0.00660856033628089406 # B[126, [2, 1, 0, 1], [18, 4, 3, 5]] + 0.00146758746394204951 # B[127, [2, 1, 0, 1], [19, 4, 3, 7]] + -0.00161093753941019967 # B[128, [2, 1, 0, 1], [20, 4, 4, 4]] + -0.00101484284665418574 # B[129, [2, 1, 0, 1], [21, 4, 4, 6]] + 0.00150269420364470413 # B[130, [2, 1, 0, 1], [22, 4, 4, 8]] + -0.000251279508914979688 # B[131, [2, 1, 0, 1], [23, 5, 0, 5]] + 0.00427791921512100763 # B[132, [2, 1, 0, 1], [24, 5, 1, 6]] + -0.00312327633171666707 # B[133, [2, 1, 0, 1], [25, 5, 2, 5]] + 0.00145518956483171066 # B[134, [2, 1, 0, 1], [26, 5, 2, 7]] + -0.00296392629706135422 # B[135, [2, 1, 0, 1], [27, 5, 3, 6]] + 0.00106990236696331148 # B[136, [2, 1, 0, 1], [28, 5, 3, 8]] + 0.000140740776400729824 # B[137, [2, 1, 0, 1], [29, 5, 4, 5]] + -0.000704484148092703912 # B[138, [2, 1, 0, 1], [30, 5, 4, 7]] + 0.000555926138942124939 # B[139, [2, 1, 0, 1], [31, 5, 5, 6]] + 0.000749361142656781065 # B[140, [2, 1, 0, 1], [32, 5, 5, 8]] + -0.000275563231062828096 # B[141, [2, 1, 0, 1], [33, 6, 0, 6]] + 0.00404287546990938183 # B[142, [2, 1, 0, 1], [34, 6, 1, 7]] + -0.00329083016295819491 # B[143, [2, 1, 0, 1], [35, 6, 2, 6]] + 0.00374648670440783874 # B[144, [2, 1, 0, 1], [36, 6, 2, 8]] + -0.000931584323738718183 # B[145, [2, 1, 0, 1], [37, 6, 3, 7]] + 0.001545987588966576 # B[146, [2, 1, 0, 1], [38, 6, 4, 6]] + 0.000136630337825366203 # B[147, [2, 1, 0, 1], [39, 6, 4, 8]] + -0.000338191518470186761 # B[148, [2, 1, 0, 1], [40, 6, 5, 7]] + 0.000383732900037425575 # B[149, [2, 1, 0, 1], [41, 6, 6, 6]] + 0.000891911333988446714 # B[150, [2, 1, 0, 1], [42, 6, 6, 8]] + 0.000372325777048820861 # B[151, [2, 1, 0, 1], [43, 7, 0, 7]] + 0.00203975899324063559 # B[152, [2, 1, 0, 1], [44, 7, 1, 8]] + -0.00366168906366426058 # B[153, [2, 1, 0, 1], [45, 7, 2, 7]] + -0.00217927110231279971 # B[154, [2, 1, 0, 1], [46, 7, 3, 8]] + -0.000355180731966526532 # B[155, [2, 1, 0, 1], [47, 7, 4, 7]] + -0.00190295940654904624 # B[156, [2, 1, 0, 1], [48, 7, 5, 8]] + -0.00045640385432905474 # B[157, [2, 1, 0, 1], [49, 7, 6, 7]] + -0.00123273230096131864 # B[158, [2, 1, 0, 1], [50, 7, 7, 8]] + 2.61749541232737803e-06 # B[159, [2, 1, 0, 1], [51, 8, 0, 8]] + -0.00188736987570012403 # B[160, [2, 1, 0, 1], [52, 8, 2, 8]] + 0.000127235145614493401 # B[161, [2, 1, 0, 1], [53, 8, 4, 8]] + -0.000446185446234578786 # B[162, [2, 1, 0, 1], [54, 8, 6, 8]] + 3.06626149019382718e-05 # B[163, [2, 1, 0, 1], [55, 8, 8, 8]] + 0.00500803145405033512 # B[164, [3, 1, 1, 2], [3, 1, 1, 2]] + 0.0136537265129433767 # B[165, [3, 1, 1, 2], [4, 2, 0, 2]] + 0.00586793418015095231 # B[166, [3, 1, 1, 2], [5, 2, 1, 3]] + 0.0108897828563872673 # B[167, [3, 1, 1, 2], [6, 2, 2, 2]] + 0.000782326392446437181 # B[168, [3, 1, 1, 2], [7, 2, 2, 4]] + -0.00196905235294965193 # B[169, [3, 1, 1, 2], [8, 3, 0, 3]] + -0.00575620599927615263 # B[170, [3, 1, 1, 2], [9, 3, 1, 4]] + -0.0395084171352078836 # B[171, [3, 1, 1, 2], [10, 3, 2, 3]] + -0.0402914809330097226 # B[172, [3, 1, 1, 2], [11, 3, 2, 5]] + -0.031380925125560552 # B[173, [3, 1, 1, 2], [12, 3, 3, 4]] + 0.0074098991236085333 # B[174, [3, 1, 1, 2], [13, 3, 3, 6]] + -0.00144234945688183152 # B[175, [3, 1, 1, 2], [14, 4, 0, 4]] + -0.00715563010950572616 # B[176, [3, 1, 1, 2], [15, 4, 1, 5]] + -0.0068004389765142035 # B[177, [3, 1, 1, 2], [16, 4, 2, 4]] + -0.0397838555572563451 # B[178, [3, 1, 1, 2], [17, 4, 2, 6]] + 0.00335672059516798228 # B[179, [3, 1, 1, 2], [18, 4, 3, 5]] + 0.0148934683418572647 # B[180, [3, 1, 1, 2], [19, 4, 3, 7]] + -0.000967980016249102011 # B[181, [3, 1, 1, 2], [20, 4, 4, 4]] + 0.00772576295059950596 # B[182, [3, 1, 1, 2], [21, 4, 4, 6]] + -0.00450662666899595381 # B[183, [3, 1, 1, 2], [22, 4, 4, 8]] + -0.00395807515027411967 # B[184, [3, 1, 1, 2], [23, 5, 0, 5]] + 0.010414612350238486 # B[185, [3, 1, 1, 2], [24, 5, 1, 6]] + -0.00513372683983254804 # B[186, [3, 1, 1, 2], [25, 5, 2, 5]] + -0.0265398819124704963 # B[187, [3, 1, 1, 2], [26, 5, 2, 7]] + 0.00742434172938952544 # B[188, [3, 1, 1, 2], [27, 5, 3, 6]] + -0.00256386423704287481 # B[189, [3, 1, 1, 2], [28, 5, 3, 8]] + 0.00841179553194743718 # B[190, [3, 1, 1, 2], [29, 5, 4, 5]] + 0.00668617729586690451 # B[191, [3, 1, 1, 2], [30, 5, 4, 7]] + 0.000484464094046739568 # B[192, [3, 1, 1, 2], [31, 5, 5, 6]] + 0.00458460314168420216 # B[193, [3, 1, 1, 2], [32, 5, 5, 8]] + -0.00235318401641824212 # B[194, [3, 1, 1, 2], [33, 6, 0, 6]] + -0.000804392064641467762 # B[195, [3, 1, 1, 2], [34, 6, 1, 7]] + -0.000974349018272668323 # B[196, [3, 1, 1, 2], [35, 6, 2, 6]] + -0.0186467861443154748 # B[197, [3, 1, 1, 2], [36, 6, 2, 8]] + 0.0149394908128317495 # B[198, [3, 1, 1, 2], [37, 6, 3, 7]] + -0.001417773975968062 # B[199, [3, 1, 1, 2], [38, 6, 4, 6]] + 0.00708801668305296916 # B[200, [3, 1, 1, 2], [39, 6, 4, 8]] + 0.00422029817457212405 # B[201, [3, 1, 1, 2], [40, 6, 5, 7]] + 0.00110117813016081525 # B[202, [3, 1, 1, 2], [41, 6, 6, 6]] + -0.00187490884044745794 # B[203, [3, 1, 1, 2], [42, 6, 6, 8]] + -0.00530063898164105998 # B[204, [3, 1, 1, 2], [43, 7, 0, 7]] + 0.0156639815207892212 # B[205, [3, 1, 1, 2], [44, 7, 1, 8]] + 0.0118519420103458811 # B[206, [3, 1, 1, 2], [45, 7, 2, 7]] + 0.00375057568532275679 # B[207, [3, 1, 1, 2], [46, 7, 3, 8]] + 0.00757584350406629962 # B[208, [3, 1, 1, 2], [47, 7, 4, 7]] + 0.0106601777099339986 # B[209, [3, 1, 1, 2], [48, 7, 5, 8]] + -0.0041075690062942552 # B[210, [3, 1, 1, 2], [49, 7, 6, 7]] + 0.00248707997936048041 # B[211, [3, 1, 1, 2], [50, 7, 7, 8]] + -0.0025390217113529746 # B[212, [3, 1, 1, 2], [51, 8, 0, 8]] + 0.00498354453902482165 # B[213, [3, 1, 1, 2], [52, 8, 2, 8]] + 0.00383782774054214912 # B[214, [3, 1, 1, 2], [53, 8, 4, 8]] + 0.00318870204625110783 # B[215, [3, 1, 1, 2], [54, 8, 6, 8]] + -0.00078409267383599678 # B[216, [3, 1, 1, 2], [55, 8, 8, 8]] + 0.00411479420703600093 # B[217, [4, 2, 0, 2], [4, 2, 0, 2]] + -0.00352482696278418658 # B[218, [4, 2, 0, 2], [5, 2, 1, 3]] + 0.00293296373222708129 # B[219, [4, 2, 0, 2], [6, 2, 2, 2]] + -0.00169108240942662173 # B[220, [4, 2, 0, 2], [7, 2, 2, 4]] + -0.00166875839344953099 # B[221, [4, 2, 0, 2], [8, 3, 0, 3]] + -0.00303743189373234653 # B[222, [4, 2, 0, 2], [9, 3, 1, 4]] + -0.00360352002032471395 # B[223, [4, 2, 0, 2], [10, 3, 2, 3]] + -0.00844475258400314774 # B[224, [4, 2, 0, 2], [11, 3, 2, 5]] + -0.00267861760564082688 # B[225, [4, 2, 0, 2], [12, 3, 3, 4]] + 0.00249373694942188646 # B[226, [4, 2, 0, 2], [13, 3, 3, 6]] + 0.00129518789575956 # B[227, [4, 2, 0, 2], [14, 4, 0, 4]] + -0.000616706097657935626 # B[228, [4, 2, 0, 2], [15, 4, 1, 5]] + -0.00374793183827557257 # B[229, [4, 2, 0, 2], [16, 4, 2, 4]] + -0.00725453590077526286 # B[230, [4, 2, 0, 2], [17, 4, 2, 6]] + -0.00328165463874066426 # B[231, [4, 2, 0, 2], [18, 4, 3, 5]] + -0.00387910875571249565 # B[232, [4, 2, 0, 2], [19, 4, 3, 7]] + -0.000691443248665482221 # B[233, [4, 2, 0, 2], [20, 4, 4, 4]] + -0.00364575524119575139 # B[234, [4, 2, 0, 2], [21, 4, 4, 6]] + 0.000579213613942424974 # B[235, [4, 2, 0, 2], [22, 4, 4, 8]] + 0.000382530088889220486 # B[236, [4, 2, 0, 2], [23, 5, 0, 5]] + 0.000700082663528700608 # B[237, [4, 2, 0, 2], [24, 5, 1, 6]] + -0.00303645662419470708 # B[238, [4, 2, 0, 2], [25, 5, 2, 5]] + -0.00412449214914962191 # B[239, [4, 2, 0, 2], [26, 5, 2, 7]] + -0.000863747946010486305 # B[240, [4, 2, 0, 2], [27, 5, 3, 6]] + 0.000597171151136822748 # B[241, [4, 2, 0, 2], [28, 5, 3, 8]] + -0.00290482182317059953 # B[242, [4, 2, 0, 2], [29, 5, 4, 5]] + -0.00218615594313117554 # B[243, [4, 2, 0, 2], [30, 5, 4, 7]] + 0.00120270898159113111 # B[244, [4, 2, 0, 2], [31, 5, 5, 6]] + -0.000439562436330729364 # B[245, [4, 2, 0, 2], [32, 5, 5, 8]] + -0.000155002689849706443 # B[246, [4, 2, 0, 2], [33, 6, 0, 6]] + -0.00203784613220199399 # B[247, [4, 2, 0, 2], [34, 6, 1, 7]] + -0.00251933129878168221 # B[248, [4, 2, 0, 2], [35, 6, 2, 6]] + -0.00227857345941180406 # B[249, [4, 2, 0, 2], [36, 6, 2, 8]] + 0.00307391827986236085 # B[250, [4, 2, 0, 2], [37, 6, 3, 7]] + -0.000435707916552085118 # B[251, [4, 2, 0, 2], [38, 6, 4, 6]] + -0.00141960729594133419 # B[252, [4, 2, 0, 2], [39, 6, 4, 8]] + -0.000275734648504752638 # B[253, [4, 2, 0, 2], [40, 6, 5, 7]] + 0.000703286595409794617 # B[254, [4, 2, 0, 2], [41, 6, 6, 6]] + -5.55751922647368824e-05 # B[255, [4, 2, 0, 2], [42, 6, 6, 8]] + -0.000401816924228297345 # B[256, [4, 2, 0, 2], [43, 7, 0, 7]] + -0.000554714661495172429 # B[257, [4, 2, 0, 2], [44, 7, 1, 8]] + 0.00088244559527147267 # B[258, [4, 2, 0, 2], [45, 7, 2, 7]] + 0.000429487284537406104 # B[259, [4, 2, 0, 2], [46, 7, 3, 8]] + 0.000160720016534536374 # B[260, [4, 2, 0, 2], [47, 7, 4, 7]] + -0.000116046064898544729 # B[261, [4, 2, 0, 2], [48, 7, 5, 8]] + 0.00077812424584384446 # B[262, [4, 2, 0, 2], [49, 7, 6, 7]] + 0.0014223009786123353 # B[263, [4, 2, 0, 2], [50, 7, 7, 8]] + 5.45987148103492526e-05 # B[264, [4, 2, 0, 2], [51, 8, 0, 8]] + -0.00229888217343966316 # B[265, [4, 2, 0, 2], [52, 8, 2, 8]] + -0.00144376280980788169 # B[266, [4, 2, 0, 2], [53, 8, 4, 8]] + 0.000240138800657541986 # B[267, [4, 2, 0, 2], [54, 8, 6, 8]] + -4.09764373741731969e-05 # B[268, [4, 2, 0, 2], [55, 8, 8, 8]] + 0.0453826120189535706 # B[269, [5, 2, 1, 3], [5, 2, 1, 3]] + 0.00337080799390409615 # B[270, [5, 2, 1, 3], [6, 2, 2, 2]] + 0.0339316309546992961 # B[271, [5, 2, 1, 3], [7, 2, 2, 4]] + 0.00483677443671226039 # B[272, [5, 2, 1, 3], [8, 3, 0, 3]] + 0.00174954019608989774 # B[273, [5, 2, 1, 3], [9, 3, 1, 4]] + 0.00420306320210527603 # B[274, [5, 2, 1, 3], [10, 3, 2, 3]] + -0.0179939258962366969 # B[275, [5, 2, 1, 3], [11, 3, 2, 5]] + -0.01997198698308544 # B[276, [5, 2, 1, 3], [12, 3, 3, 4]] + -0.0136471344704570501 # B[277, [5, 2, 1, 3], [13, 3, 3, 6]] + -0.00203572867299816902 # B[278, [5, 2, 1, 3], [14, 4, 0, 4]] + 0.0113893698593142377 # B[279, [5, 2, 1, 3], [15, 4, 1, 5]] + -0.00283495847488346529 # B[280, [5, 2, 1, 3], [16, 4, 2, 4]] + -0.0209899506178404249 # B[281, [5, 2, 1, 3], [17, 4, 2, 6]] + 0.00307893999573658839 # B[282, [5, 2, 1, 3], [18, 4, 3, 5]] + 0.00625880909518397067 # B[283, [5, 2, 1, 3], [19, 4, 3, 7]] + 0.00109461945578659598 # B[284, [5, 2, 1, 3], [20, 4, 4, 4]] + 0.00213752786441095705 # B[285, [5, 2, 1, 3], [21, 4, 4, 6]] + -0.00379774849562602296 # B[286, [5, 2, 1, 3], [22, 4, 4, 8]] + -0.0013508169978871552 # B[287, [5, 2, 1, 3], [23, 5, 0, 5]] + 0.00921730935112183292 # B[288, [5, 2, 1, 3], [24, 5, 1, 6]] + -0.0029427132897584694 # B[289, [5, 2, 1, 3], [25, 5, 2, 5]] + 0.0013497580216050211 # B[290, [5, 2, 1, 3], [26, 5, 2, 7]] + -0.0130362734683665445 # B[291, [5, 2, 1, 3], [27, 5, 3, 6]] + 0.000858369129835153365 # B[292, [5, 2, 1, 3], [28, 5, 3, 8]] + 0.0129288669947052737 # B[293, [5, 2, 1, 3], [29, 5, 4, 5]] + -0.00373719468786774291 # B[294, [5, 2, 1, 3], [30, 5, 4, 7]] + -0.00885030928727506203 # B[295, [5, 2, 1, 3], [31, 5, 5, 6]] + 0.00285083482960970039 # B[296, [5, 2, 1, 3], [32, 5, 5, 8]] + 0.00351819863542377799 # B[297, [5, 2, 1, 3], [33, 6, 0, 6]] + -0.00783526064954031404 # B[298, [5, 2, 1, 3], [34, 6, 1, 7]] + -0.00257460837433342703 # B[299, [5, 2, 1, 3], [35, 6, 2, 6]] + -0.00421680657028429638 # B[300, [5, 2, 1, 3], [36, 6, 2, 8]] + -0.00918753516813325399 # B[301, [5, 2, 1, 3], [37, 6, 3, 7]] + -0.00316878171100497871 # B[302, [5, 2, 1, 3], [38, 6, 4, 6]] + 0.000939804682159322766 # B[303, [5, 2, 1, 3], [39, 6, 4, 8]] + -0.00618801787900946643 # B[304, [5, 2, 1, 3], [40, 6, 5, 7]] + -0.00623545765495540482 # B[305, [5, 2, 1, 3], [41, 6, 6, 6]] + 0.00519552954815065936 # B[306, [5, 2, 1, 3], [42, 6, 6, 8]] + 0.0042213652228506697 # B[307, [5, 2, 1, 3], [43, 7, 0, 7]] + 0.0113944611011103838 # B[308, [5, 2, 1, 3], [44, 7, 1, 8]] + -0.00104197865751114085 # B[309, [5, 2, 1, 3], [45, 7, 2, 7]] + -0.0087446191630695079 # B[310, [5, 2, 1, 3], [46, 7, 3, 8]] + -0.00196327596558909696 # B[311, [5, 2, 1, 3], [47, 7, 4, 7]] + -0.00447686867642808298 # B[312, [5, 2, 1, 3], [48, 7, 5, 8]] + -0.00474469665733750351 # B[313, [5, 2, 1, 3], [49, 7, 6, 7]] + -0.0059004868061462868 # B[314, [5, 2, 1, 3], [50, 7, 7, 8]] + 2.22874717926892923e-05 # B[315, [5, 2, 1, 3], [51, 8, 0, 8]] + -0.00154741089157206784 # B[316, [5, 2, 1, 3], [52, 8, 2, 8]] + 0.00417852330669051582 # B[317, [5, 2, 1, 3], [53, 8, 4, 8]] + 0.00134060860138395356 # B[318, [5, 2, 1, 3], [54, 8, 6, 8]] + -4.29219459423162489e-05 # B[319, [5, 2, 1, 3], [55, 8, 8, 8]] + 0.000319124100064731785 # B[320, [6, 2, 2, 2], [6, 2, 2, 2]] + -0.00839561599135440172 # B[321, [6, 2, 2, 2], [7, 2, 2, 4]] + -0.00326195850510992494 # B[322, [6, 2, 2, 2], [8, 3, 0, 3]] + 0.0194547426296311776 # B[323, [6, 2, 2, 2], [9, 3, 1, 4]] + -0.020516093722439413 # B[324, [6, 2, 2, 2], [10, 3, 2, 3]] + -0.00901624473884381043 # B[325, [6, 2, 2, 2], [11, 3, 2, 5]] + 0.0129026669830971837 # B[326, [6, 2, 2, 2], [12, 3, 3, 4]] + 0.00463182910296210636 # B[327, [6, 2, 2, 2], [13, 3, 3, 6]] + -0.00261498466108737743 # B[328, [6, 2, 2, 2], [14, 4, 0, 4]] + 0.0215819608660451426 # B[329, [6, 2, 2, 2], [15, 4, 1, 5]] + 0.000767688854520869957 # B[330, [6, 2, 2, 2], [16, 4, 2, 4]] + -0.00666111439578009716 # B[331, [6, 2, 2, 2], [17, 4, 2, 6]] + 0.0112705725443772303 # B[332, [6, 2, 2, 2], [18, 4, 3, 5]] + 0.00228839615631495127 # B[333, [6, 2, 2, 2], [19, 4, 3, 7]] + 0.00124148748415313414 # B[334, [6, 2, 2, 2], [20, 4, 4, 4]] + 0.00353391028977510834 # B[335, [6, 2, 2, 2], [21, 4, 4, 6]] + -0.00310464569903003834 # B[336, [6, 2, 2, 2], [22, 4, 4, 8]] + -0.001770681064288395 # B[337, [6, 2, 2, 2], [23, 5, 0, 5]] + 0.000554784469018851215 # B[338, [6, 2, 2, 2], [24, 5, 1, 6]] + -0.000102008183116791319 # B[339, [6, 2, 2, 2], [25, 5, 2, 5]] + -0.00128750706249572758 # B[340, [6, 2, 2, 2], [26, 5, 2, 7]] + 0.0046490656013451568 # B[341, [6, 2, 2, 2], [27, 5, 3, 6]] + 0.0034506831073765681 # B[342, [6, 2, 2, 2], [28, 5, 3, 8]] + 0.00501652811902741046 # B[343, [6, 2, 2, 2], [29, 5, 4, 5]] + -1.88389891915279224e-05 # B[344, [6, 2, 2, 2], [30, 5, 4, 7]] + -0.00246586719805504942 # B[345, [6, 2, 2, 2], [31, 5, 5, 6]] + -0.00339629261051872756 # B[346, [6, 2, 2, 2], [32, 5, 5, 8]] + -1.22729584505151552e-05 # B[347, [6, 2, 2, 2], [33, 6, 0, 6]] + -0.0055646406349652653 # B[348, [6, 2, 2, 2], [34, 6, 1, 7]] + 0.00216606634250279383 # B[349, [6, 2, 2, 2], [35, 6, 2, 6]] + -0.000140725603696151627 # B[350, [6, 2, 2, 2], [36, 6, 2, 8]] + -0.01190136261487338 # B[351, [6, 2, 2, 2], [37, 6, 3, 7]] + -0.000996588010308921109 # B[352, [6, 2, 2, 2], [38, 6, 4, 6]] + -0.0040124728576705895 # B[353, [6, 2, 2, 2], [39, 6, 4, 8]] + 0.000422679331586792552 # B[354, [6, 2, 2, 2], [40, 6, 5, 7]] + 0.000548939662545001959 # B[355, [6, 2, 2, 2], [41, 6, 6, 6]] + 0.00256895119228900404 # B[356, [6, 2, 2, 2], [42, 6, 6, 8]] + -0.000615139781019174688 # B[357, [6, 2, 2, 2], [43, 7, 0, 7]] + -0.00404941774617198578 # B[358, [6, 2, 2, 2], [44, 7, 1, 8]] + 0.00466754848324051064 # B[359, [6, 2, 2, 2], [45, 7, 2, 7]] + 0.00150461796185176488 # B[360, [6, 2, 2, 2], [46, 7, 3, 8]] + 0.0037489054114537468 # B[361, [6, 2, 2, 2], [47, 7, 4, 7]] + 0.00285804436398595782 # B[362, [6, 2, 2, 2], [48, 7, 5, 8]] + -0.00287521518361254919 # B[363, [6, 2, 2, 2], [49, 7, 6, 7]] + 0.000969520968104660755 # B[364, [6, 2, 2, 2], [50, 7, 7, 8]] + -0.000716125857042927043 # B[365, [6, 2, 2, 2], [51, 8, 0, 8]] + -0.00157385185114507437 # B[366, [6, 2, 2, 2], [52, 8, 2, 8]] + 0.002689243736875038 # B[367, [6, 2, 2, 2], [53, 8, 4, 8]] + -0.000661038690452418623 # B[368, [6, 2, 2, 2], [54, 8, 6, 8]] + 0.00157186481624649321 # B[369, [6, 2, 2, 2], [55, 8, 8, 8]] + -0.0134601349926017494 # B[370, [7, 2, 2, 4], [7, 2, 2, 4]] + -0.000918558149715113011 # B[371, [7, 2, 2, 4], [8, 3, 0, 3]] + -0.00377418701166061087 # B[372, [7, 2, 2, 4], [9, 3, 1, 4]] + 0.0148168734486278948 # B[373, [7, 2, 2, 4], [10, 3, 2, 3]] + -0.00535328606426562371 # B[374, [7, 2, 2, 4], [11, 3, 2, 5]] + 0.00804271469408427385 # B[375, [7, 2, 2, 4], [12, 3, 3, 4]] + 0.00136329663181449737 # B[376, [7, 2, 2, 4], [13, 3, 3, 6]] + 0.000218608555253111195 # B[377, [7, 2, 2, 4], [14, 4, 0, 4]] + 0.00767165886258287799 # B[378, [7, 2, 2, 4], [15, 4, 1, 5]] + -0.0022580429604385833 # B[379, [7, 2, 2, 4], [16, 4, 2, 4]] + -0.0050991924246220309 # B[380, [7, 2, 2, 4], [17, 4, 2, 6]] + -0.00308509180848093572 # B[381, [7, 2, 2, 4], [18, 4, 3, 5]] + -0.000900097231895549623 # B[382, [7, 2, 2, 4], [19, 4, 3, 7]] + -0.0063557020842957869 # B[383, [7, 2, 2, 4], [20, 4, 4, 4]] + -0.000409569358807882096 # B[384, [7, 2, 2, 4], [21, 4, 4, 6]] + 0.00254581400782049119 # B[385, [7, 2, 2, 4], [22, 4, 4, 8]] + 0.000657951401298526029 # B[386, [7, 2, 2, 4], [23, 5, 0, 5]] + -0.00940269729352927013 # B[387, [7, 2, 2, 4], [24, 5, 1, 6]] + 0.00333566383730494239 # B[388, [7, 2, 2, 4], [25, 5, 2, 5]] + 0.00896493308698088215 # B[389, [7, 2, 2, 4], [26, 5, 2, 7]] + 0.00132812590751918685 # B[390, [7, 2, 2, 4], [27, 5, 3, 6]] + -0.00127282140780485189 # B[391, [7, 2, 2, 4], [28, 5, 3, 8]] + -0.00435358176352772068 # B[392, [7, 2, 2, 4], [29, 5, 4, 5]] + -0.00226566527245459885 # B[393, [7, 2, 2, 4], [30, 5, 4, 7]] + 0.00326597657188156627 # B[394, [7, 2, 2, 4], [31, 5, 5, 6]] + -0.00247993076825692074 # B[395, [7, 2, 2, 4], [32, 5, 5, 8]] + -0.00138012806761597748 # B[396, [7, 2, 2, 4], [33, 6, 0, 6]] + -0.00296559266178312566 # B[397, [7, 2, 2, 4], [34, 6, 1, 7]] + -0.00345134318647404535 # B[398, [7, 2, 2, 4], [35, 6, 2, 6]] + 0.00604122282441024554 # B[399, [7, 2, 2, 4], [36, 6, 2, 8]] + -0.00602530276328681197 # B[400, [7, 2, 2, 4], [37, 6, 3, 7]] + 0.00113230868581531974 # B[401, [7, 2, 2, 4], [38, 6, 4, 6]] + 0.00132069580529702024 # B[402, [7, 2, 2, 4], [39, 6, 4, 8]] + -0.00355708848499901743 # B[403, [7, 2, 2, 4], [40, 6, 5, 7]] + 0.00103954578232134899 # B[404, [7, 2, 2, 4], [41, 6, 6, 6]] + 0.00138660655783935638 # B[405, [7, 2, 2, 4], [42, 6, 6, 8]] + 0.00122312383058832339 # B[406, [7, 2, 2, 4], [43, 7, 0, 7]] + 0.00122422070912251465 # B[407, [7, 2, 2, 4], [44, 7, 1, 8]] + -0.00497379521097694472 # B[408, [7, 2, 2, 4], [45, 7, 2, 7]] + -0.00811974704425355749 # B[409, [7, 2, 2, 4], [46, 7, 3, 8]] + 0.00114732010903773659 # B[410, [7, 2, 2, 4], [47, 7, 4, 7]] + -0.00569074628354063975 # B[411, [7, 2, 2, 4], [48, 7, 5, 8]] + 0.00235624642317577588 # B[412, [7, 2, 2, 4], [49, 7, 6, 7]] + 7.98437182146268919e-05 # B[413, [7, 2, 2, 4], [50, 7, 7, 8]] + 0.00113891921332402897 # B[414, [7, 2, 2, 4], [51, 8, 0, 8]] + -0.00492469555442132112 # B[415, [7, 2, 2, 4], [52, 8, 2, 8]] + 0.000792980352556455804 # B[416, [7, 2, 2, 4], [53, 8, 4, 8]] + 0.00153854887229367375 # B[417, [7, 2, 2, 4], [54, 8, 6, 8]] + -0.000881221748445243022 # B[418, [7, 2, 2, 4], [55, 8, 8, 8]] + -0.00136471788502227735 # B[419, [8, 3, 0, 3], [8, 3, 0, 3]] + 0.00246251727263488776 # B[420, [8, 3, 0, 3], [9, 3, 1, 4]] + 0.000996613519267240677 # B[421, [8, 3, 0, 3], [10, 3, 2, 3]] + -0.00207976146372090831 # B[422, [8, 3, 0, 3], [11, 3, 2, 5]] + -9.97509064182486305e-05 # B[423, [8, 3, 0, 3], [12, 3, 3, 4]] + 0.000656935135924852087 # B[424, [8, 3, 0, 3], [13, 3, 3, 6]] + -0.000492474229225159377 # B[425, [8, 3, 0, 3], [14, 4, 0, 4]] + 0.0032189163248994351 # B[426, [8, 3, 0, 3], [15, 4, 1, 5]] + -0.00115555104609991501 # B[427, [8, 3, 0, 3], [16, 4, 2, 4]] + -0.000101151026370576574 # B[428, [8, 3, 0, 3], [17, 4, 2, 6]] + 0.00020301152740384229 # B[429, [8, 3, 0, 3], [18, 4, 3, 5]] + -0.000285445107860462371 # B[430, [8, 3, 0, 3], [19, 4, 3, 7]] + 0.000462665925556146607 # B[431, [8, 3, 0, 3], [20, 4, 4, 4]] + -2.75652763320703015e-05 # B[432, [8, 3, 0, 3], [21, 4, 4, 6]] + -0.000358778647317398169 # B[433, [8, 3, 0, 3], [22, 4, 4, 8]] + -0.000397176131748222527 # B[434, [8, 3, 0, 3], [23, 5, 0, 5]] + -0.00026950177456114624 # B[435, [8, 3, 0, 3], [24, 5, 1, 6]] + 0.00119424632084062527 # B[436, [8, 3, 0, 3], [25, 5, 2, 5]] + 0.000922347152199163439 # B[437, [8, 3, 0, 3], [26, 5, 2, 7]] + -0.000340838509282952173 # B[438, [8, 3, 0, 3], [27, 5, 3, 6]] + 0.00128847730890532808 # B[439, [8, 3, 0, 3], [28, 5, 3, 8]] + -0.00044582191494569115 # B[440, [8, 3, 0, 3], [29, 5, 4, 5]] + -0.00114898350718379422 # B[441, [8, 3, 0, 3], [30, 5, 4, 7]] + -0.000530499767100067743 # B[442, [8, 3, 0, 3], [31, 5, 5, 6]] + 1.68864176486992895e-05 # B[443, [8, 3, 0, 3], [32, 5, 5, 8]] + -0.000312292146951373417 # B[444, [8, 3, 0, 3], [33, 6, 0, 6]] + -0.00186273440079770883 # B[445, [8, 3, 0, 3], [34, 6, 1, 7]] + -0.000475625961442131123 # B[446, [8, 3, 0, 3], [35, 6, 2, 6]] + 0.000505090975521763769 # B[447, [8, 3, 0, 3], [36, 6, 2, 8]] + 0.000128630083375533277 # B[448, [8, 3, 0, 3], [37, 6, 3, 7]] + -0.000431369283499544176 # B[449, [8, 3, 0, 3], [38, 6, 4, 6]] + 0.000461881443708941908 # B[450, [8, 3, 0, 3], [39, 6, 4, 8]] + 0.000867550860200114182 # B[451, [8, 3, 0, 3], [40, 6, 5, 7]] + 0.000179604539903628624 # B[452, [8, 3, 0, 3], [41, 6, 6, 6]] + -0.000405383988192370426 # B[453, [8, 3, 0, 3], [42, 6, 6, 8]] + -0.000305572243426546764 # B[454, [8, 3, 0, 3], [43, 7, 0, 7]] + -0.0010766931736053021 # B[455, [8, 3, 0, 3], [44, 7, 1, 8]] + 0.000701859051866787764 # B[456, [8, 3, 0, 3], [45, 7, 2, 7]] + -1.5413662061584954e-05 # B[457, [8, 3, 0, 3], [46, 7, 3, 8]] + 0.000428834666348756888 # B[458, [8, 3, 0, 3], [47, 7, 4, 7]] + 0.000468098667731533385 # B[459, [8, 3, 0, 3], [48, 7, 5, 8]] + 0.000158467988956009775 # B[460, [8, 3, 0, 3], [49, 7, 6, 7]] + 2.77948419442784408e-05 # B[461, [8, 3, 0, 3], [50, 7, 7, 8]] + -0.000282655955044820717 # B[462, [8, 3, 0, 3], [51, 8, 0, 8]] + 0.000100300940760145348 # B[463, [8, 3, 0, 3], [52, 8, 2, 8]] + 0.000314947671131902973 # B[464, [8, 3, 0, 3], [53, 8, 4, 8]] + 0.000144842823919437078 # B[465, [8, 3, 0, 3], [54, 8, 6, 8]] + 7.00050428864840146e-05 # B[466, [8, 3, 0, 3], [55, 8, 8, 8]] + 0.0118411448561217512 # B[467, [9, 3, 1, 4], [9, 3, 1, 4]] + 0.0158809314732707603 # B[468, [9, 3, 1, 4], [10, 3, 2, 3]] + -0.00690506493475962109 # B[469, [9, 3, 1, 4], [11, 3, 2, 5]] + 0.0085626937099196887 # B[470, [9, 3, 1, 4], [12, 3, 3, 4]] + -0.00387686964925252654 # B[471, [9, 3, 1, 4], [13, 3, 3, 6]] + 0.00015029200549142481 # B[472, [9, 3, 1, 4], [14, 4, 0, 4]] + -0.000142532963490632015 # B[473, [9, 3, 1, 4], [15, 4, 1, 5]] + 0.00921427022949583042 # B[474, [9, 3, 1, 4], [16, 4, 2, 4]] + -0.0112717231196791407 # B[475, [9, 3, 1, 4], [17, 4, 2, 6]] + -0.0122014182952103704 # B[476, [9, 3, 1, 4], [18, 4, 3, 5]] + -0.0111571557686284996 # B[477, [9, 3, 1, 4], [19, 4, 3, 7]] + -0.00276180055211498916 # B[478, [9, 3, 1, 4], [20, 4, 4, 4]] + -0.00444456405006457382 # B[479, [9, 3, 1, 4], [21, 4, 4, 6]] + -0.00248162623330630983 # B[480, [9, 3, 1, 4], [22, 4, 4, 8]] + 0.000238830840202226575 # B[481, [9, 3, 1, 4], [23, 5, 0, 5]] + 0.0106883008114137777 # B[482, [9, 3, 1, 4], [24, 5, 1, 6]] + -0.00176293319638371826 # B[483, [9, 3, 1, 4], [25, 5, 2, 5]] + -0.000706186990249144109 # B[484, [9, 3, 1, 4], [26, 5, 2, 7]] + -0.000957413082652629373 # B[485, [9, 3, 1, 4], [27, 5, 3, 6]] + -0.00485998335666546887 # B[486, [9, 3, 1, 4], [28, 5, 3, 8]] + -0.000739967956913101287 # B[487, [9, 3, 1, 4], [29, 5, 4, 5]] + -0.00656002591947351353 # B[488, [9, 3, 1, 4], [30, 5, 4, 7]] + -0.00191607250770065712 # B[489, [9, 3, 1, 4], [31, 5, 5, 6]] + -0.000375150046930213714 # B[490, [9, 3, 1, 4], [32, 5, 5, 8]] + 0.000379540253919751804 # B[491, [9, 3, 1, 4], [33, 6, 0, 6]] + 0.0103809997405371179 # B[492, [9, 3, 1, 4], [34, 6, 1, 7]] + -0.00167937900508645203 # B[493, [9, 3, 1, 4], [35, 6, 2, 6]] + -0.000942453027264282192 # B[494, [9, 3, 1, 4], [36, 6, 2, 8]] + -0.00358794660355351257 # B[495, [9, 3, 1, 4], [37, 6, 3, 7]] + 0.00367542903060237222 # B[496, [9, 3, 1, 4], [38, 6, 4, 6]] + -0.00605874518215254298 # B[497, [9, 3, 1, 4], [39, 6, 4, 8]] + -0.0053364107721741022 # B[498, [9, 3, 1, 4], [40, 6, 5, 7]] + -0.00220303686176452889 # B[499, [9, 3, 1, 4], [41, 6, 6, 6]] + 0.000240224733534942676 # B[500, [9, 3, 1, 4], [42, 6, 6, 8]] + 0.00118204722287629585 # B[501, [9, 3, 1, 4], [43, 7, 0, 7]] + 0.00391606544218769514 # B[502, [9, 3, 1, 4], [44, 7, 1, 8]] + -0.00190557542057654024 # B[503, [9, 3, 1, 4], [45, 7, 2, 7]] + -0.0010749256928406746 # B[504, [9, 3, 1, 4], [46, 7, 3, 8]] + 6.24186835188134462e-05 # B[505, [9, 3, 1, 4], [47, 7, 4, 7]] + -0.00250872188348977114 # B[506, [9, 3, 1, 4], [48, 7, 5, 8]] + -0.00164710314956706405 # B[507, [9, 3, 1, 4], [49, 7, 6, 7]] + -0.0029144992153610676 # B[508, [9, 3, 1, 4], [50, 7, 7, 8]] + 0.000712015267242259442 # B[509, [9, 3, 1, 4], [51, 8, 0, 8]] + -0.00179539873092394715 # B[510, [9, 3, 1, 4], [52, 8, 2, 8]] + 0.00203000698298521493 # B[511, [9, 3, 1, 4], [53, 8, 4, 8]] + -0.00103477100047664442 # B[512, [9, 3, 1, 4], [54, 8, 6, 8]] + -0.000727628763147338854 # B[513, [9, 3, 1, 4], [55, 8, 8, 8]] + 0.0163451466486591972 # B[514, [10, 3, 2, 3], [10, 3, 2, 3]] + -0.00145259448176927441 # B[515, [10, 3, 2, 3], [11, 3, 2, 5]] + -0.00808947571520425568 # B[516, [10, 3, 2, 3], [12, 3, 3, 4]] + -0.00693599935022420205 # B[517, [10, 3, 2, 3], [13, 3, 3, 6]] + -0.00419683318703741731 # B[518, [10, 3, 2, 3], [14, 4, 0, 4]] + 0.00927666204585274323 # B[519, [10, 3, 2, 3], [15, 4, 1, 5]] + -0.0138962541759877663 # B[520, [10, 3, 2, 3], [16, 4, 2, 4]] + 0.0115061801390417759 # B[521, [10, 3, 2, 3], [17, 4, 2, 6]] + 0.0118559077356181798 # B[522, [10, 3, 2, 3], [18, 4, 3, 5]] + 0.00193270595871023604 # B[523, [10, 3, 2, 3], [19, 4, 3, 7]] + 0.00156708209719190472 # B[524, [10, 3, 2, 3], [20, 4, 4, 4]] + 0.0030286948486105119 # B[525, [10, 3, 2, 3], [21, 4, 4, 6]] + -6.03736466163237034e-05 # B[526, [10, 3, 2, 3], [22, 4, 4, 8]] + -0.00147218391304548835 # B[527, [10, 3, 2, 3], [23, 5, 0, 5]] + 0.000931966019926808685 # B[528, [10, 3, 2, 3], [24, 5, 1, 6]] + 0.0153667638164197012 # B[529, [10, 3, 2, 3], [25, 5, 2, 5]] + -0.0023105273691670326 # B[530, [10, 3, 2, 3], [26, 5, 2, 7]] + 0.0018873267014898696 # B[531, [10, 3, 2, 3], [27, 5, 3, 6]] + -0.00221592978134090707 # B[532, [10, 3, 2, 3], [28, 5, 3, 8]] + 0.00175823978838723916 # B[533, [10, 3, 2, 3], [29, 5, 4, 5]] + 0.00134986143361107494 # B[534, [10, 3, 2, 3], [30, 5, 4, 7]] + -0.00280444330034939227 # B[535, [10, 3, 2, 3], [31, 5, 5, 6]] + -0.000446159575940244073 # B[536, [10, 3, 2, 3], [32, 5, 5, 8]] + 0.000126573802730074736 # B[537, [10, 3, 2, 3], [33, 6, 0, 6]] + 7.95217271451070795e-05 # B[538, [10, 3, 2, 3], [34, 6, 1, 7]] + -0.000615992203402992468 # B[539, [10, 3, 2, 3], [35, 6, 2, 6]] + -0.0106304231235931409 # B[540, [10, 3, 2, 3], [36, 6, 2, 8]] + -0.00513102234934090934 # B[541, [10, 3, 2, 3], [37, 6, 3, 7]] + 0.00086364506858761271 # B[542, [10, 3, 2, 3], [38, 6, 4, 6]] + -0.00427816275089007263 # B[543, [10, 3, 2, 3], [39, 6, 4, 8]] + -0.00709876751806875171 # B[544, [10, 3, 2, 3], [40, 6, 5, 7]] + -0.00107679083671011894 # B[545, [10, 3, 2, 3], [41, 6, 6, 6]] + -0.0014022801302571164 # B[546, [10, 3, 2, 3], [42, 6, 6, 8]] + 0.00032001340322446864 # B[547, [10, 3, 2, 3], [43, 7, 0, 7]] + 0.0099494513037338677 # B[548, [10, 3, 2, 3], [44, 7, 1, 8]] + 0.00657164457459321564 # B[549, [10, 3, 2, 3], [45, 7, 2, 7]] + -0.00193909086513409032 # B[550, [10, 3, 2, 3], [46, 7, 3, 8]] + -0.000661327911070458407 # B[551, [10, 3, 2, 3], [47, 7, 4, 7]] + -0.00236609840279333045 # B[552, [10, 3, 2, 3], [48, 7, 5, 8]] + 0.000323126961361372422 # B[553, [10, 3, 2, 3], [49, 7, 6, 7]] + 0.00156411007472663857 # B[554, [10, 3, 2, 3], [50, 7, 7, 8]] + -0.000413410696562647312 # B[555, [10, 3, 2, 3], [51, 8, 0, 8]] + 0.00151556635054790959 # B[556, [10, 3, 2, 3], [52, 8, 2, 8]] + 0.0032252808357782943 # B[557, [10, 3, 2, 3], [53, 8, 4, 8]] + 0.00431814581620697767 # B[558, [10, 3, 2, 3], [54, 8, 6, 8]] + 0.000198535493268348594 # B[559, [10, 3, 2, 3], [55, 8, 8, 8]] + 0.0156540432654675432 # B[560, [11, 3, 2, 5], [11, 3, 2, 5]] + 0.00979845476873780416 # B[561, [11, 3, 2, 5], [12, 3, 3, 4]] + 0.00873265456764509701 # B[562, [11, 3, 2, 5], [13, 3, 3, 6]] + -0.00355250352643814854 # B[563, [11, 3, 2, 5], [14, 4, 0, 4]] + 0.0197388975583387243 # B[564, [11, 3, 2, 5], [15, 4, 1, 5]] + 0.0158965586216084157 # B[565, [11, 3, 2, 5], [16, 4, 2, 4]] + 0.0126440348146513917 # B[566, [11, 3, 2, 5], [17, 4, 2, 6]] + 0.00588822462217037865 # B[567, [11, 3, 2, 5], [18, 4, 3, 5]] + 0.00465829809814364074 # B[568, [11, 3, 2, 5], [19, 4, 3, 7]] + 0.00460100330976275125 # B[569, [11, 3, 2, 5], [20, 4, 4, 4]] + 0.00507979510261629894 # B[570, [11, 3, 2, 5], [21, 4, 4, 6]] + -0.000978147842247499566 # B[571, [11, 3, 2, 5], [22, 4, 4, 8]] + 0.000175648698607325238 # B[572, [11, 3, 2, 5], [23, 5, 0, 5]] + 0.00701365729786882983 # B[573, [11, 3, 2, 5], [24, 5, 1, 6]] + 0.0124121871279893672 # B[574, [11, 3, 2, 5], [25, 5, 2, 5]] + 0.0133268604743271169 # B[575, [11, 3, 2, 5], [26, 5, 2, 7]] + -0.00306906262974302943 # B[576, [11, 3, 2, 5], [27, 5, 3, 6]] + 0.00411586711144847073 # B[577, [11, 3, 2, 5], [28, 5, 3, 8]] + -0.00483702208096517539 # B[578, [11, 3, 2, 5], [29, 5, 4, 5]] + 0.000232830853394127776 # B[579, [11, 3, 2, 5], [30, 5, 4, 7]] + -0.00500644765401524715 # B[580, [11, 3, 2, 5], [31, 5, 5, 6]] + -0.000732991087538808345 # B[581, [11, 3, 2, 5], [32, 5, 5, 8]] + 0.0028290195015726223 # B[582, [11, 3, 2, 5], [33, 6, 0, 6]] + 0.000660043236562475252 # B[583, [11, 3, 2, 5], [34, 6, 1, 7]] + 0.00858014820620479901 # B[584, [11, 3, 2, 5], [35, 6, 2, 6]] + 0.00979420830127970127 # B[585, [11, 3, 2, 5], [36, 6, 2, 8]] + -0.00276929529868128257 # B[586, [11, 3, 2, 5], [37, 6, 3, 7]] + -0.00462592209123751513 # B[587, [11, 3, 2, 5], [38, 6, 4, 6]] + 0.000957159367659247626 # B[588, [11, 3, 2, 5], [39, 6, 4, 8]] + -0.00289923459154850169 # B[589, [11, 3, 2, 5], [40, 6, 5, 7]] + -0.00605668820795574915 # B[590, [11, 3, 2, 5], [41, 6, 6, 6]] + -0.00571070540762017888 # B[591, [11, 3, 2, 5], [42, 6, 6, 8]] + 0.00247733408975375075 # B[592, [11, 3, 2, 5], [43, 7, 0, 7]] + 0.00452000165177812024 # B[593, [11, 3, 2, 5], [44, 7, 1, 8]] + 0.00267833963693382693 # B[594, [11, 3, 2, 5], [45, 7, 2, 7]] + -0.00558917145621175976 # B[595, [11, 3, 2, 5], [46, 7, 3, 8]] + -0.00228097422335522999 # B[596, [11, 3, 2, 5], [47, 7, 4, 7]] + -0.00366604043706369575 # B[597, [11, 3, 2, 5], [48, 7, 5, 8]] + -0.00340088281218112534 # B[598, [11, 3, 2, 5], [49, 7, 6, 7]] + -0.00355022426643257852 # B[599, [11, 3, 2, 5], [50, 7, 7, 8]] + 0.00124080314205340242 # B[600, [11, 3, 2, 5], [51, 8, 0, 8]] + 0.00287261267197001097 # B[601, [11, 3, 2, 5], [52, 8, 2, 8]] + 0.000744815191487350516 # B[602, [11, 3, 2, 5], [53, 8, 4, 8]] + -0.000112288931147085103 # B[603, [11, 3, 2, 5], [54, 8, 6, 8]] + -0.000128712309023326903 # B[604, [11, 3, 2, 5], [55, 8, 8, 8]] + -0.00238666366477884723 # B[605, [12, 3, 3, 4], [12, 3, 3, 4]] + 0.000248696286071804773 # B[606, [12, 3, 3, 4], [13, 3, 3, 6]] + -0.000479775127143412111 # B[607, [12, 3, 3, 4], [14, 4, 0, 4]] + 0.00175952173341571141 # B[608, [12, 3, 3, 4], [15, 4, 1, 5]] + 0.000197368498788095745 # B[609, [12, 3, 3, 4], [16, 4, 2, 4]] + 0.00726401135600521306 # B[610, [12, 3, 3, 4], [17, 4, 2, 6]] + -0.00118096336629036625 # B[611, [12, 3, 3, 4], [18, 4, 3, 5]] + 0.00702896514440041337 # B[612, [12, 3, 3, 4], [19, 4, 3, 7]] + -0.00236026619914155369 # B[613, [12, 3, 3, 4], [20, 4, 4, 4]] + -0.00341152672753146672 # B[614, [12, 3, 3, 4], [21, 4, 4, 6]] + 0.00348613231611557411 # B[615, [12, 3, 3, 4], [22, 4, 4, 8]] + 0.00244457707345889508 # B[616, [12, 3, 3, 4], [23, 5, 0, 5]] + -0.000822727235681003019 # B[617, [12, 3, 3, 4], [24, 5, 1, 6]] + -0.00248763810919495551 # B[618, [12, 3, 3, 4], [25, 5, 2, 5]] + 0.00796413115978647848 # B[619, [12, 3, 3, 4], [26, 5, 2, 7]] + -0.00179317048488774472 # B[620, [12, 3, 3, 4], [27, 5, 3, 6]] + 0.00454384820995466787 # B[621, [12, 3, 3, 4], [28, 5, 3, 8]] + -0.00425365149530766012 # B[622, [12, 3, 3, 4], [29, 5, 4, 5]] + -0.000569152560526600682 # B[623, [12, 3, 3, 4], [30, 5, 4, 7]] + -0.00506501220127485163 # B[624, [12, 3, 3, 4], [31, 5, 5, 6]] + -0.00142637122228714969 # B[625, [12, 3, 3, 4], [32, 5, 5, 8]] + 0.00190739239349446005 # B[626, [12, 3, 3, 4], [33, 6, 0, 6]] + 0.00215429853006474104 # B[627, [12, 3, 3, 4], [34, 6, 1, 7]] + 0.00512135793044871807 # B[628, [12, 3, 3, 4], [35, 6, 2, 6]] + 0.00479344551680733165 # B[629, [12, 3, 3, 4], [36, 6, 2, 8]] + -0.000813733007282164966 # B[630, [12, 3, 3, 4], [37, 6, 3, 7]] + -0.00162747725274282884 # B[631, [12, 3, 3, 4], [38, 6, 4, 6]] + -0.00440004969635155417 # B[632, [12, 3, 3, 4], [39, 6, 4, 8]] + -0.00939941153506137356 # B[633, [12, 3, 3, 4], [40, 6, 5, 7]] + -0.00314893787689287524 # B[634, [12, 3, 3, 4], [41, 6, 6, 6]] + -0.00125776748984993136 # B[635, [12, 3, 3, 4], [42, 6, 6, 8]] + 0.00129112127843685615 # B[636, [12, 3, 3, 4], [43, 7, 0, 7]] + 0.00564724346615860621 # B[637, [12, 3, 3, 4], [44, 7, 1, 8]] + -0.0018460571659526942 # B[638, [12, 3, 3, 4], [45, 7, 2, 7]] + -0.000300525523225368685 # B[639, [12, 3, 3, 4], [46, 7, 3, 8]] + -0.00277157581435865698 # B[640, [12, 3, 3, 4], [47, 7, 4, 7]] + -0.00975210406554173105 # B[641, [12, 3, 3, 4], [48, 7, 5, 8]] + -0.00233845213984289896 # B[642, [12, 3, 3, 4], [49, 7, 6, 7]] + -0.00138723239922117561 # B[643, [12, 3, 3, 4], [50, 7, 7, 8]] + 0.000864866797073243071 # B[644, [12, 3, 3, 4], [51, 8, 0, 8]] + -0.000747563068773752452 # B[645, [12, 3, 3, 4], [52, 8, 2, 8]] + 0.000965474694725087373 # B[646, [12, 3, 3, 4], [53, 8, 4, 8]] + -0.00140612646390263218 # B[647, [12, 3, 3, 4], [54, 8, 6, 8]] + -0.00149643617894318522 # B[648, [12, 3, 3, 4], [55, 8, 8, 8]] + 0.00149153681612450295 # B[649, [13, 3, 3, 6], [13, 3, 3, 6]] + -0.000954556711257832646 # B[650, [13, 3, 3, 6], [14, 4, 0, 4]] + 0.00120983585813713799 # B[651, [13, 3, 3, 6], [15, 4, 1, 5]] + 0.00300317867570911888 # B[652, [13, 3, 3, 6], [16, 4, 2, 4]] + 0.00236443796053106663 # B[653, [13, 3, 3, 6], [17, 4, 2, 6]] + 0.00415524139600132597 # B[654, [13, 3, 3, 6], [18, 4, 3, 5]] + -0.000123573851697839077 # B[655, [13, 3, 3, 6], [19, 4, 3, 7]] + 0.000470359195248265527 # B[656, [13, 3, 3, 6], [20, 4, 4, 4]] + 0.000635927641249957321 # B[657, [13, 3, 3, 6], [21, 4, 4, 6]] + 0.000747673754939660613 # B[658, [13, 3, 3, 6], [22, 4, 4, 8]] + 0.00074188846631736971 # B[659, [13, 3, 3, 6], [23, 5, 0, 5]] + 0.00463957097737913854 # B[660, [13, 3, 3, 6], [24, 5, 1, 6]] + -0.00271105182543343939 # B[661, [13, 3, 3, 6], [25, 5, 2, 5]] + 6.90411348413036419e-06 # B[662, [13, 3, 3, 6], [26, 5, 2, 7]] + 0.000911354980270381865 # B[663, [13, 3, 3, 6], [27, 5, 3, 6]] + -0.0028545746938972022 # B[664, [13, 3, 3, 6], [28, 5, 3, 8]] + -1.76062828863947363e-05 # B[665, [13, 3, 3, 6], [29, 5, 4, 5]] + -1.51206672011107435e-05 # B[666, [13, 3, 3, 6], [30, 5, 4, 7]] + -0.000798318879555708766 # B[667, [13, 3, 3, 6], [31, 5, 5, 6]] + -0.0015978026047660434 # B[668, [13, 3, 3, 6], [32, 5, 5, 8]] + 0.00034244751324807865 # B[669, [13, 3, 3, 6], [33, 6, 0, 6]] + 0.00338996797689858353 # B[670, [13, 3, 3, 6], [34, 6, 1, 7]] + 0.000289281476490772793 # B[671, [13, 3, 3, 6], [35, 6, 2, 6]] + -0.000559772151149058594 # B[672, [13, 3, 3, 6], [36, 6, 2, 8]] + -0.000650724286175463629 # B[673, [13, 3, 3, 6], [37, 6, 3, 7]] + 0.00148244897292096334 # B[674, [13, 3, 3, 6], [38, 6, 4, 6]] + 0.000183404639618602733 # B[675, [13, 3, 3, 6], [39, 6, 4, 8]] + -0.00185779692530890772 # B[676, [13, 3, 3, 6], [40, 6, 5, 7]] + -0.000708322215432564961 # B[677, [13, 3, 3, 6], [41, 6, 6, 6]] + -0.000491831969715535167 # B[678, [13, 3, 3, 6], [42, 6, 6, 8]] + 0.000833818016036214082 # B[679, [13, 3, 3, 6], [43, 7, 0, 7]] + -0.00256922900730601443 # B[680, [13, 3, 3, 6], [44, 7, 1, 8]] + -0.00112433206588518839 # B[681, [13, 3, 3, 6], [45, 7, 2, 7]] + 6.43716101358243753e-05 # B[682, [13, 3, 3, 6], [46, 7, 3, 8]] + -0.00126304972485289518 # B[683, [13, 3, 3, 6], [47, 7, 4, 7]] + -0.00210937996313975001 # B[684, [13, 3, 3, 6], [48, 7, 5, 8]] + -0.00126022676030809744 # B[685, [13, 3, 3, 6], [49, 7, 6, 7]] + -0.000555039709846411045 # B[686, [13, 3, 3, 6], [50, 7, 7, 8]] + 0.000790824100586496465 # B[687, [13, 3, 3, 6], [51, 8, 0, 8]] + -0.000844206812343649936 # B[688, [13, 3, 3, 6], [52, 8, 2, 8]] + 0.000195900027714517901 # B[689, [13, 3, 3, 6], [53, 8, 4, 8]] + -0.000823274415849936658 # B[690, [13, 3, 3, 6], [54, 8, 6, 8]] + -0.000330474595809105917 # B[691, [13, 3, 3, 6], [55, 8, 8, 8]] + -3.04835503155357485e-05 # B[692, [14, 4, 0, 4], [14, 4, 0, 4]] + -0.000825475145007361147 # B[693, [14, 4, 0, 4], [15, 4, 1, 5]] + -0.00244887111925138484 # B[694, [14, 4, 0, 4], [16, 4, 2, 4]] + -0.00122050568127611732 # B[695, [14, 4, 0, 4], [17, 4, 2, 6]] + -0.00226655265247485693 # B[696, [14, 4, 0, 4], [18, 4, 3, 5]] + -0.000767631950688907327 # B[697, [14, 4, 0, 4], [19, 4, 3, 7]] + -0.000547575812124723171 # B[698, [14, 4, 0, 4], [20, 4, 4, 4]] + -0.00121783548699544442 # B[699, [14, 4, 0, 4], [21, 4, 4, 6]] + 6.68947985199286332e-05 # B[700, [14, 4, 0, 4], [22, 4, 4, 8]] + -9.6030771921717939e-05 # B[701, [14, 4, 0, 4], [23, 5, 0, 5]] + -0.000544408900336967871 # B[702, [14, 4, 0, 4], [24, 5, 1, 6]] + -0.00139019051437529293 # B[703, [14, 4, 0, 4], [25, 5, 2, 5]] + -0.000281919324988699413 # B[704, [14, 4, 0, 4], [26, 5, 2, 7]] + -0.00125721115437776171 # B[705, [14, 4, 0, 4], [27, 5, 3, 6]] + -0.000282797770993010317 # B[706, [14, 4, 0, 4], [28, 5, 3, 8]] + -0.00139320549871079641 # B[707, [14, 4, 0, 4], [29, 5, 4, 5]] + -0.000628813518841068401 # B[708, [14, 4, 0, 4], [30, 5, 4, 7]] + -0.000607292163329276047 # B[709, [14, 4, 0, 4], [31, 5, 5, 6]] + 0.000242807689929189566 # B[710, [14, 4, 0, 4], [32, 5, 5, 8]] + -0.000100536983796830487 # B[711, [14, 4, 0, 4], [33, 6, 0, 6]] + 0.00111838401982674706 # B[712, [14, 4, 0, 4], [34, 6, 1, 7]] + -0.0012014113032742873 # B[713, [14, 4, 0, 4], [35, 6, 2, 6]] + -1.32311363260466386e-05 # B[714, [14, 4, 0, 4], [36, 6, 2, 8]] + 0.000753146180409180327 # B[715, [14, 4, 0, 4], [37, 6, 3, 7]] + -0.000270332227596856156 # B[716, [14, 4, 0, 4], [38, 6, 4, 6]] + -0.000293750660311472775 # B[717, [14, 4, 0, 4], [39, 6, 4, 8]] + 6.52480591955099942e-05 # B[718, [14, 4, 0, 4], [40, 6, 5, 7]] + -4.70588815947581285e-05 # B[719, [14, 4, 0, 4], [41, 6, 6, 6]] + 0.000244731448919628669 # B[720, [14, 4, 0, 4], [42, 6, 6, 8]] + -9.3149326930830334e-05 # B[721, [14, 4, 0, 4], [43, 7, 0, 7]] + 0.000731947904616598796 # B[722, [14, 4, 0, 4], [44, 7, 1, 8]] + -0.00107463735030771668 # B[723, [14, 4, 0, 4], [45, 7, 2, 7]] + 0.000139861959076940934 # B[724, [14, 4, 0, 4], [46, 7, 3, 8]] + 0.000101877532936889281 # B[725, [14, 4, 0, 4], [47, 7, 4, 7]] + -0.000196888502333611437 # B[726, [14, 4, 0, 4], [48, 7, 5, 8]] + 6.12030178565765859e-05 # B[727, [14, 4, 0, 4], [49, 7, 6, 7]] + -0.000223986590912481076 # B[728, [14, 4, 0, 4], [50, 7, 7, 8]] + -6.56819431667232667e-05 # B[729, [14, 4, 0, 4], [51, 8, 0, 8]] + -0.000970632773483491584 # B[730, [14, 4, 0, 4], [52, 8, 2, 8]] + -0.000182189294658170395 # B[731, [14, 4, 0, 4], [53, 8, 4, 8]] + -3.45215935849477185e-05 # B[732, [14, 4, 0, 4], [54, 8, 6, 8]] + 6.19739521221795986e-05 # B[733, [14, 4, 0, 4], [55, 8, 8, 8]] + 0.000242753902013392972 # B[734, [15, 4, 1, 5], [15, 4, 1, 5]] + 0.00729727211034517358 # B[735, [15, 4, 1, 5], [16, 4, 2, 4]] + -0.0024545495000649507 # B[736, [15, 4, 1, 5], [17, 4, 2, 6]] + -0.00265559618939786597 # B[737, [15, 4, 1, 5], [18, 4, 3, 5]] + 0.00473045463551583639 # B[738, [15, 4, 1, 5], [19, 4, 3, 7]] + -0.000140785797905494323 # B[739, [15, 4, 1, 5], [20, 4, 4, 4]] + 0.00179841698526277474 # B[740, [15, 4, 1, 5], [21, 4, 4, 6]] + 0.00129773534161339073 # B[741, [15, 4, 1, 5], [22, 4, 4, 8]] + 0.00172905697138841467 # B[742, [15, 4, 1, 5], [23, 5, 0, 5]] + -0.00408304027381215483 # B[743, [15, 4, 1, 5], [24, 5, 1, 6]] + -0.00205043992851699228 # B[744, [15, 4, 1, 5], [25, 5, 2, 5]] + 0.000756591579123801249 # B[745, [15, 4, 1, 5], [26, 5, 2, 7]] + -0.00421238291006168549 # B[746, [15, 4, 1, 5], [27, 5, 3, 6]] + -0.00196911327032830725 # B[747, [15, 4, 1, 5], [28, 5, 3, 8]] + 0.000729488918071528446 # B[748, [15, 4, 1, 5], [29, 5, 4, 5]] + -0.00177843604064341788 # B[749, [15, 4, 1, 5], [30, 5, 4, 7]] + -0.00130376966915328159 # B[750, [15, 4, 1, 5], [31, 5, 5, 6]] + -0.00198695656227435707 # B[751, [15, 4, 1, 5], [32, 5, 5, 8]] + 0.000608914142072050635 # B[752, [15, 4, 1, 5], [33, 6, 0, 6]] + -0.00109469344681823767 # B[753, [15, 4, 1, 5], [34, 6, 1, 7]] + -0.00451953523789613495 # B[754, [15, 4, 1, 5], [35, 6, 2, 6]] + 0.00279449892877900279 # B[755, [15, 4, 1, 5], [36, 6, 2, 8]] + -0.00435984465194903283 # B[756, [15, 4, 1, 5], [37, 6, 3, 7]] + 0.00275969130186590542 # B[757, [15, 4, 1, 5], [38, 6, 4, 6]] + 0.00154021904971430755 # B[758, [15, 4, 1, 5], [39, 6, 4, 8]] + -0.00146163413862035289 # B[759, [15, 4, 1, 5], [40, 6, 5, 7]] + -0.000333421796264918996 # B[760, [15, 4, 1, 5], [41, 6, 6, 6]] + -0.00139958818201657261 # B[761, [15, 4, 1, 5], [42, 6, 6, 8]] + 0.000750502250600797172 # B[762, [15, 4, 1, 5], [43, 7, 0, 7]] + 0.00476052216726493421 # B[763, [15, 4, 1, 5], [44, 7, 1, 8]] + -0.00155321215408361565 # B[764, [15, 4, 1, 5], [45, 7, 2, 7]] + -0.00351167160511536933 # B[765, [15, 4, 1, 5], [46, 7, 3, 8]] + 0.00268907735535169144 # B[766, [15, 4, 1, 5], [47, 7, 4, 7]] + -0.00296394481906553462 # B[767, [15, 4, 1, 5], [48, 7, 5, 8]] + -0.00115945739998543369 # B[768, [15, 4, 1, 5], [49, 7, 6, 7]] + -0.0011498694923236445 # B[769, [15, 4, 1, 5], [50, 7, 7, 8]] + 0.000691127444573572114 # B[770, [15, 4, 1, 5], [51, 8, 0, 8]] + 0.00149148321917135169 # B[771, [15, 4, 1, 5], [52, 8, 2, 8]] + 0.00226549729687968923 # B[772, [15, 4, 1, 5], [53, 8, 4, 8]] + -0.00127955154911817224 # B[773, [15, 4, 1, 5], [54, 8, 6, 8]] + -0.0006680598304007173 # B[774, [15, 4, 1, 5], [55, 8, 8, 8]] + 0.00773393138113156846 # B[775, [16, 4, 2, 4], [16, 4, 2, 4]] + 0.00481567776445743917 # B[776, [16, 4, 2, 4], [17, 4, 2, 6]] + 0.00646602315581837339 # B[777, [16, 4, 2, 4], [18, 4, 3, 5]] + 0.00401373256364237051 # B[778, [16, 4, 2, 4], [19, 4, 3, 7]] + -0.000224833927917125753 # B[779, [16, 4, 2, 4], [20, 4, 4, 4]] + 0.0030532060451974926 # B[780, [16, 4, 2, 4], [21, 4, 4, 6]] + -0.000126777823410560014 # B[781, [16, 4, 2, 4], [22, 4, 4, 8]] + 0.00109512376860463863 # B[782, [16, 4, 2, 4], [23, 5, 0, 5]] + 0.0014906978453806609 # B[783, [16, 4, 2, 4], [24, 5, 1, 6]] + 0.00278609484035531206 # B[784, [16, 4, 2, 4], [25, 5, 2, 5]] + 0.00720611209490516682 # B[785, [16, 4, 2, 4], [26, 5, 2, 7]] + 0.00230880055683394415 # B[786, [16, 4, 2, 4], [27, 5, 3, 6]] + 0.00492114792718315389 # B[787, [16, 4, 2, 4], [28, 5, 3, 8]] + 0.00102265649585190407 # B[788, [16, 4, 2, 4], [29, 5, 4, 5]] + -0.000348239317084679881 # B[789, [16, 4, 2, 4], [30, 5, 4, 7]] + -0.00394431438420023671 # B[790, [16, 4, 2, 4], [31, 5, 5, 6]] + -0.00362914461095884553 # B[791, [16, 4, 2, 4], [32, 5, 5, 8]] + 0.000172019923347470349 # B[792, [16, 4, 2, 4], [33, 6, 0, 6]] + -0.000316455135754767445 # B[793, [16, 4, 2, 4], [34, 6, 1, 7]] + 0.00107098215861984453 # B[794, [16, 4, 2, 4], [35, 6, 2, 6]] + -0.000907131668137324478 # B[795, [16, 4, 2, 4], [36, 6, 2, 8]] + -0.000367695081353409058 # B[796, [16, 4, 2, 4], [37, 6, 3, 7]] + 0.00181370580350630889 # B[797, [16, 4, 2, 4], [38, 6, 4, 6]] + 0.000820930060826967692 # B[798, [16, 4, 2, 4], [39, 6, 4, 8]] + -0.00466238776474962348 # B[799, [16, 4, 2, 4], [40, 6, 5, 7]] + -0.0024305728850557008 # B[800, [16, 4, 2, 4], [41, 6, 6, 6]] + -0.00165013696151081928 # B[801, [16, 4, 2, 4], [42, 6, 6, 8]] + 0.000760058338755045804 # B[802, [16, 4, 2, 4], [43, 7, 0, 7]] + -0.00203289214112462729 # B[803, [16, 4, 2, 4], [44, 7, 1, 8]] + -0.00103057221789182719 # B[804, [16, 4, 2, 4], [45, 7, 2, 7]] + 0.00188720556649034019 # B[805, [16, 4, 2, 4], [46, 7, 3, 8]] + -0.000348979964538542048 # B[806, [16, 4, 2, 4], [47, 7, 4, 7]] + -0.00595514004121479486 # B[807, [16, 4, 2, 4], [48, 7, 5, 8]] + -0.00122307692783891336 # B[808, [16, 4, 2, 4], [49, 7, 6, 7]] + -0.00161626528708522232 # B[809, [16, 4, 2, 4], [50, 7, 7, 8]] + 0.000683658453003721522 # B[810, [16, 4, 2, 4], [51, 8, 0, 8]] + 0.000169503544911074264 # B[811, [16, 4, 2, 4], [52, 8, 2, 8]] + 0.00163132840171071117 # B[812, [16, 4, 2, 4], [53, 8, 4, 8]] + -0.000633742642666999118 # B[813, [16, 4, 2, 4], [54, 8, 6, 8]] + -0.000861029784191980584 # B[814, [16, 4, 2, 4], [55, 8, 8, 8]] + 0.0101724317893582689 # B[815, [17, 4, 2, 6], [17, 4, 2, 6]] + 0.00963074903115390332 # B[816, [17, 4, 2, 6], [18, 4, 3, 5]] + 0.00792776812488414986 # B[817, [17, 4, 2, 6], [19, 4, 3, 7]] + 0.00129789596639547263 # B[818, [17, 4, 2, 6], [20, 4, 4, 4]] + 0.0025280260724625768 # B[819, [17, 4, 2, 6], [21, 4, 4, 6]] + -0.00130604081814601758 # B[820, [17, 4, 2, 6], [22, 4, 4, 8]] + 0.00061656245411057832 # B[821, [17, 4, 2, 6], [23, 5, 0, 5]] + 0.00256026791937838134 # B[822, [17, 4, 2, 6], [24, 5, 1, 6]] + 0.00833728674660196879 # B[823, [17, 4, 2, 6], [25, 5, 2, 5]] + 0.00819332084025456604 # B[824, [17, 4, 2, 6], [26, 5, 2, 7]] + 0.00199258058679730159 # B[825, [17, 4, 2, 6], [27, 5, 3, 6]] + -0.00235687406293394464 # B[826, [17, 4, 2, 6], [28, 5, 3, 8]] + 0.00172306590551023903 # B[827, [17, 4, 2, 6], [29, 5, 4, 5]] + 0.00273320921325834404 # B[828, [17, 4, 2, 6], [30, 5, 4, 7]] + 0.00124490813870011289 # B[829, [17, 4, 2, 6], [31, 5, 5, 6]] + -0.00239829497882970916 # B[830, [17, 4, 2, 6], [32, 5, 5, 8]] + 0.000403489881901454572 # B[831, [17, 4, 2, 6], [33, 6, 0, 6]] + 0.0115977289566935714 # B[832, [17, 4, 2, 6], [34, 6, 1, 7]] + 0.00631330244272786285 # B[833, [17, 4, 2, 6], [35, 6, 2, 6]] + 0.00745951676374975552 # B[834, [17, 4, 2, 6], [36, 6, 2, 8]] + 0.00129555462014044158 # B[835, [17, 4, 2, 6], [37, 6, 3, 7]] + 0.0031708889242759988 # B[836, [17, 4, 2, 6], [38, 6, 4, 6]] + 0.00314059501950873093 # B[837, [17, 4, 2, 6], [39, 6, 4, 8]] + -0.00157311519106628078 # B[838, [17, 4, 2, 6], [40, 6, 5, 7]] + -0.000535633835711041804 # B[839, [17, 4, 2, 6], [41, 6, 6, 6]] + -0.00106218347026977491 # B[840, [17, 4, 2, 6], [42, 6, 6, 8]] + 0.00171130648037900839 # B[841, [17, 4, 2, 6], [43, 7, 0, 7]] + 0.00318381348777509654 # B[842, [17, 4, 2, 6], [44, 7, 1, 8]] + 0.00121186975917000981 # B[843, [17, 4, 2, 6], [45, 7, 2, 7]] + -0.00505226933268299559 # B[844, [17, 4, 2, 6], [46, 7, 3, 8]] + 0.000505489038324865442 # B[845, [17, 4, 2, 6], [47, 7, 4, 7]] + -0.00260650572816220009 # B[846, [17, 4, 2, 6], [48, 7, 5, 8]] + -0.00458388666826989831 # B[847, [17, 4, 2, 6], [49, 7, 6, 7]] + -0.0030323259618317824 # B[848, [17, 4, 2, 6], [50, 7, 7, 8]] + 0.000919810997489799165 # B[849, [17, 4, 2, 6], [51, 8, 0, 8]] + 0.00153843620323466154 # B[850, [17, 4, 2, 6], [52, 8, 2, 8]] + 0.00177452104337356975 # B[851, [17, 4, 2, 6], [53, 8, 4, 8]] + -0.00133363365246129796 # B[852, [17, 4, 2, 6], [54, 8, 6, 8]] + 0.000497168699576265929 # B[853, [17, 4, 2, 6], [55, 8, 8, 8]] + 0.00916493227652732945 # B[854, [18, 4, 3, 5], [18, 4, 3, 5]] + 0.00662893191875722591 # B[855, [18, 4, 3, 5], [19, 4, 3, 7]] + 0.00102473567933248147 # B[856, [18, 4, 3, 5], [20, 4, 4, 4]] + 0.000661293664462594619 # B[857, [18, 4, 3, 5], [21, 4, 4, 6]] + 0.00302383517430961438 # B[858, [18, 4, 3, 5], [22, 4, 4, 8]] + 0.00182134236384280147 # B[859, [18, 4, 3, 5], [23, 5, 0, 5]] + 0.00481003527044247467 # B[860, [18, 4, 3, 5], [24, 5, 1, 6]] + 0.00472221587821478311 # B[861, [18, 4, 3, 5], [25, 5, 2, 5]] + 0.00204855894682247092 # B[862, [18, 4, 3, 5], [26, 5, 2, 7]] + 0.00108437129165206425 # B[863, [18, 4, 3, 5], [27, 5, 3, 6]] + 0.000188071259560827417 # B[864, [18, 4, 3, 5], [28, 5, 3, 8]] + 0.000402244806083140727 # B[865, [18, 4, 3, 5], [29, 5, 4, 5]] + 0.00350511561101824257 # B[866, [18, 4, 3, 5], [30, 5, 4, 7]] + -0.00196731170271619883 # B[867, [18, 4, 3, 5], [31, 5, 5, 6]] + -0.000854471064769226317 # B[868, [18, 4, 3, 5], [32, 5, 5, 8]] + 0.00163753590726098495 # B[869, [18, 4, 3, 5], [33, 6, 0, 6]] + 0.00678767470498069323 # B[870, [18, 4, 3, 5], [34, 6, 1, 7]] + 0.00671898362129526739 # B[871, [18, 4, 3, 5], [35, 6, 2, 6]] + 0.00504150139406711259 # B[872, [18, 4, 3, 5], [36, 6, 2, 8]] + -0.00150058947564556469 # B[873, [18, 4, 3, 5], [37, 6, 3, 7]] + 0.00126561580055304518 # B[874, [18, 4, 3, 5], [38, 6, 4, 6]] + -0.000556565865268397481 # B[875, [18, 4, 3, 5], [39, 6, 4, 8]] + -0.00527488386402661519 # B[876, [18, 4, 3, 5], [40, 6, 5, 7]] + -0.00214157468754809163 # B[877, [18, 4, 3, 5], [41, 6, 6, 6]] + -0.0020431148178264337 # B[878, [18, 4, 3, 5], [42, 6, 6, 8]] + 0.00142704628054338232 # B[879, [18, 4, 3, 5], [43, 7, 0, 7]] + 0.00368882624306161085 # B[880, [18, 4, 3, 5], [44, 7, 1, 8]] + -0.000742447358153045661 # B[881, [18, 4, 3, 5], [45, 7, 2, 7]] + -0.00158678830901623838 # B[882, [18, 4, 3, 5], [46, 7, 3, 8]] + -0.00107876302160130055 # B[883, [18, 4, 3, 5], [47, 7, 4, 7]] + -0.00701537311445033646 # B[884, [18, 4, 3, 5], [48, 7, 5, 8]] + -0.00184801443295596127 # B[885, [18, 4, 3, 5], [49, 7, 6, 7]] + -0.00127678697871524667 # B[886, [18, 4, 3, 5], [50, 7, 7, 8]] + 0.00105641109188138113 # B[887, [18, 4, 3, 5], [51, 8, 0, 8]] + 0.000718098622203026428 # B[888, [18, 4, 3, 5], [52, 8, 2, 8]] + 0.00219486004289275692 # B[889, [18, 4, 3, 5], [53, 8, 4, 8]] + -0.00158748993130468905 # B[890, [18, 4, 3, 5], [54, 8, 6, 8]] + -0.00105128398142791644 # B[891, [18, 4, 3, 5], [55, 8, 8, 8]] + -0.00705876763301777586 # B[892, [19, 4, 3, 7], [19, 4, 3, 7]] + 0.00377186011578763136 # B[893, [19, 4, 3, 7], [20, 4, 4, 4]] + 0.00351225097737749986 # B[894, [19, 4, 3, 7], [21, 4, 4, 6]] + -0.00323798036048509805 # B[895, [19, 4, 3, 7], [22, 4, 4, 8]] + 0.00126225430824061444 # B[896, [19, 4, 3, 7], [23, 5, 0, 5]] + -0.00132900767543010258 # B[897, [19, 4, 3, 7], [24, 5, 1, 6]] + 0.000212743875668733318 # B[898, [19, 4, 3, 7], [25, 5, 2, 5]] + -8.93559293989563963e-05 # B[899, [19, 4, 3, 7], [26, 5, 2, 7]] + 0.00401415269432878544 # B[900, [19, 4, 3, 7], [27, 5, 3, 6]] + -0.00422923196125859352 # B[901, [19, 4, 3, 7], [28, 5, 3, 8]] + 0.00252733635050122335 # B[902, [19, 4, 3, 7], [29, 5, 4, 5]] + -0.00020969110581340808 # B[903, [19, 4, 3, 7], [30, 5, 4, 7]] + -0.000969147769818896193 # B[904, [19, 4, 3, 7], [31, 5, 5, 6]] + -0.00249817386761041864 # B[905, [19, 4, 3, 7], [32, 5, 5, 8]] + 7.71120512828363247e-05 # B[906, [19, 4, 3, 7], [33, 6, 0, 6]] + 0.00560302176075209817 # B[907, [19, 4, 3, 7], [34, 6, 1, 7]] + 0.00342833731167378752 # B[908, [19, 4, 3, 7], [35, 6, 2, 6]] + 0.00116548365936076578 # B[909, [19, 4, 3, 7], [36, 6, 2, 8]] + 0.00499590856190199745 # B[910, [19, 4, 3, 7], [37, 6, 3, 7]] + 0.00391644837067879614 # B[911, [19, 4, 3, 7], [38, 6, 4, 6]] + 0.00116606811408420229 # B[912, [19, 4, 3, 7], [39, 6, 4, 8]] + -0.000563820914290556058 # B[913, [19, 4, 3, 7], [40, 6, 5, 7]] + -0.000251464925992161276 # B[914, [19, 4, 3, 7], [41, 6, 6, 6]] + -0.000718753250305587815 # B[915, [19, 4, 3, 7], [42, 6, 6, 8]] + 0.000453024387943248494 # B[916, [19, 4, 3, 7], [43, 7, 0, 7]] + -0.00146422451962339994 # B[917, [19, 4, 3, 7], [44, 7, 1, 8]] + 0.00271974781140060795 # B[918, [19, 4, 3, 7], [45, 7, 2, 7]] + 0.00151707017829591159 # B[919, [19, 4, 3, 7], [46, 7, 3, 8]] + 0.00202377896423465691 # B[920, [19, 4, 3, 7], [47, 7, 4, 7]] + -0.00131185948123999779 # B[921, [19, 4, 3, 7], [48, 7, 5, 8]] + 0.000239464941185672797 # B[922, [19, 4, 3, 7], [49, 7, 6, 7]] + -0.000667571478871501964 # B[923, [19, 4, 3, 7], [50, 7, 7, 8]] + 0.000666789360176615192 # B[924, [19, 4, 3, 7], [51, 8, 0, 8]] + 0.00179543252151156355 # B[925, [19, 4, 3, 7], [52, 8, 2, 8]] + 0.000954396542852647967 # B[926, [19, 4, 3, 7], [53, 8, 4, 8]] + 0.000593331439814590023 # B[927, [19, 4, 3, 7], [54, 8, 6, 8]] + -0.000292670120459602445 # B[928, [19, 4, 3, 7], [55, 8, 8, 8]] + -0.000303353861178074294 # B[929, [20, 4, 4, 4], [20, 4, 4, 4]] + -6.41585335468541906e-05 # B[930, [20, 4, 4, 4], [21, 4, 4, 6]] + 0.00145464895340288725 # B[931, [20, 4, 4, 4], [22, 4, 4, 8]] + 0.000557677559397141802 # B[932, [20, 4, 4, 4], [23, 5, 0, 5]] + 0.00214733001664968188 # B[933, [20, 4, 4, 4], [24, 5, 1, 6]] + 0.000196804226194771757 # B[934, [20, 4, 4, 4], [25, 5, 2, 5]] + 0.00169621771662652795 # B[935, [20, 4, 4, 4], [26, 5, 2, 7]] + -0.00126951106424718924 # B[936, [20, 4, 4, 4], [27, 5, 3, 6]] + 0.00156201190059711802 # B[937, [20, 4, 4, 4], [28, 5, 3, 8]] + -0.000188505112089858498 # B[938, [20, 4, 4, 4], [29, 5, 4, 5]] + 0.00101485096974841295 # B[939, [20, 4, 4, 4], [30, 5, 4, 7]] + -0.000254023094278113288 # B[940, [20, 4, 4, 4], [31, 5, 5, 6]] + -0.000332430225508446864 # B[941, [20, 4, 4, 4], [32, 5, 5, 8]] + 0.000393172799404761797 # B[942, [20, 4, 4, 4], [33, 6, 0, 6]] + -0.000945851456653874594 # B[943, [20, 4, 4, 4], [34, 6, 1, 7]] + 0.000937118523093692299 # B[944, [20, 4, 4, 4], [35, 6, 2, 6]] + 0.00108463610451345858 # B[945, [20, 4, 4, 4], [36, 6, 2, 8]] + -0.00167878968186336089 # B[946, [20, 4, 4, 4], [37, 6, 3, 7]] + 0.000109649976457827647 # B[947, [20, 4, 4, 4], [38, 6, 4, 6]] + 0.000205908523746248934 # B[948, [20, 4, 4, 4], [39, 6, 4, 8]] + -0.000952641271225448949 # B[949, [20, 4, 4, 4], [40, 6, 5, 7]] + -0.000386842165161269298 # B[950, [20, 4, 4, 4], [41, 6, 6, 6]] + -0.000662992329463731739 # B[951, [20, 4, 4, 4], [42, 6, 6, 8]] + 0.000368522676488847178 # B[952, [20, 4, 4, 4], [43, 7, 0, 7]] + -0.000181924614212486402 # B[953, [20, 4, 4, 4], [44, 7, 1, 8]] + -0.00119374010493299761 # B[954, [20, 4, 4, 4], [45, 7, 2, 7]] + -0.000775398926021152179 # B[955, [20, 4, 4, 4], [46, 7, 3, 8]] + -0.000670782103704289923 # B[956, [20, 4, 4, 4], [47, 7, 4, 7]] + -0.00192682764111087456 # B[957, [20, 4, 4, 4], [48, 7, 5, 8]] + -0.000648663865567958298 # B[958, [20, 4, 4, 4], [49, 7, 6, 7]] + -0.000387954189232417312 # B[959, [20, 4, 4, 4], [50, 7, 7, 8]] + 0.000302370648048068055 # B[960, [20, 4, 4, 4], [51, 8, 0, 8]] + -0.00085980088667597307 # B[961, [20, 4, 4, 4], [52, 8, 2, 8]] + 0.000568399123124077588 # B[962, [20, 4, 4, 4], [53, 8, 4, 8]] + -0.000482151590861096269 # B[963, [20, 4, 4, 4], [54, 8, 6, 8]] + -0.000405828455879983507 # B[964, [20, 4, 4, 4], [55, 8, 8, 8]] + 0.00165997230068267755 # B[965, [21, 4, 4, 6], [21, 4, 4, 6]] + 0.000963896255597472551 # B[966, [21, 4, 4, 6], [22, 4, 4, 8]] + 0.0002094521100325826 # B[967, [21, 4, 4, 6], [23, 5, 0, 5]] + 0.000534879644705995444 # B[968, [21, 4, 4, 6], [24, 5, 1, 6]] + 0.00292236533791157905 # B[969, [21, 4, 4, 6], [25, 5, 2, 5]] + 0.00151524368635043427 # B[970, [21, 4, 4, 6], [26, 5, 2, 7]] + -0.00101689007388491501 # B[971, [21, 4, 4, 6], [27, 5, 3, 6]] + 0.000738459806183821427 # B[972, [21, 4, 4, 6], [28, 5, 3, 8]] + 0.00148643764242684627 # B[973, [21, 4, 4, 6], [29, 5, 4, 5]] + 0.0011556877894129472 # B[974, [21, 4, 4, 6], [30, 5, 4, 7]] + -0.000208381440186615127 # B[975, [21, 4, 4, 6], [31, 5, 5, 6]] + -0.00143743030752817389 # B[976, [21, 4, 4, 6], [32, 5, 5, 8]] + -0.00016600302639456152 # B[977, [21, 4, 4, 6], [33, 6, 0, 6]] + 0.00172160125073629253 # B[978, [21, 4, 4, 6], [34, 6, 1, 7]] + 0.00344812165058533751 # B[979, [21, 4, 4, 6], [35, 6, 2, 6]] + 0.000544104512334869089 # B[980, [21, 4, 4, 6], [36, 6, 2, 8]] + -0.00182558144376257503 # B[981, [21, 4, 4, 6], [37, 6, 3, 7]] + 0.00101065848983370246 # B[982, [21, 4, 4, 6], [38, 6, 4, 6]] + 0.00103400096073465869 # B[983, [21, 4, 4, 6], [39, 6, 4, 8]] + -0.000235944095127582111 # B[984, [21, 4, 4, 6], [40, 6, 5, 7]] + 0.000154580830205655606 # B[985, [21, 4, 4, 6], [41, 6, 6, 6]] + -0.000488680460493023505 # B[986, [21, 4, 4, 6], [42, 6, 6, 8]] + 3.83739714257189113e-05 # B[987, [21, 4, 4, 6], [43, 7, 0, 7]] + -0.000275037336268196993 # B[988, [21, 4, 4, 6], [44, 7, 1, 8]] + 0.0017878021157122859 # B[989, [21, 4, 4, 6], [45, 7, 2, 7]] + -0.00110857713686632331 # B[990, [21, 4, 4, 6], [46, 7, 3, 8]] + -0.000126074852562767237 # B[991, [21, 4, 4, 6], [47, 7, 4, 7]] + -0.00125862858469075189 # B[992, [21, 4, 4, 6], [48, 7, 5, 8]] + -0.000277638160776805254 # B[993, [21, 4, 4, 6], [49, 7, 6, 7]] + 0.000163335859971639602 # B[994, [21, 4, 4, 6], [50, 7, 7, 8]] + 0.000151747507838979889 # B[995, [21, 4, 4, 6], [51, 8, 0, 8]] + 0.00156180455186682998 # B[996, [21, 4, 4, 6], [52, 8, 2, 8]] + 0.00112614353705531994 # B[997, [21, 4, 4, 6], [53, 8, 4, 8]] + -0.000376140365477903652 # B[998, [21, 4, 4, 6], [54, 8, 6, 8]] + -0.000378786757414536351 # B[999, [21, 4, 4, 6], [55, 8, 8, 8]] + -0.00186381195965971969 # B[1000, [22, 4, 4, 8], [22, 4, 4, 8]] + 0.000334060235611270684 # B[1001, [22, 4, 4, 8], [23, 5, 0, 5]] + -0.000182139490643212255 # B[1002, [22, 4, 4, 8], [24, 5, 1, 6]] + -0.000866414678376911532 # B[1003, [22, 4, 4, 8], [25, 5, 2, 5]] + -0.000713836573909394211 # B[1004, [22, 4, 4, 8], [26, 5, 2, 7]] + 0.00340359387460056721 # B[1005, [22, 4, 4, 8], [27, 5, 3, 6]] + -0.0025631762232975969 # B[1006, [22, 4, 4, 8], [28, 5, 3, 8]] + 0.00154837338005092001 # B[1007, [22, 4, 4, 8], [29, 5, 4, 5]] + -0.000713785025005329171 # B[1008, [22, 4, 4, 8], [30, 5, 4, 7]] + -6.17852167664190155e-06 # B[1009, [22, 4, 4, 8], [31, 5, 5, 6]] + -0.000925788250245492385 # B[1010, [22, 4, 4, 8], [32, 5, 5, 8]] + -0.000220618203180443506 # B[1011, [22, 4, 4, 8], [33, 6, 0, 6]] + 0.00158760304062654546 # B[1012, [22, 4, 4, 8], [34, 6, 1, 7]] + -0.00201296543384867077 # B[1013, [22, 4, 4, 8], [35, 6, 2, 6]] + -0.000153111573438037551 # B[1014, [22, 4, 4, 8], [36, 6, 2, 8]] + 0.001936342943994784 # B[1015, [22, 4, 4, 8], [37, 6, 3, 7]] + 0.0014724303902098404 # B[1016, [22, 4, 4, 8], [38, 6, 4, 6]] + 0.000412977919829218137 # B[1017, [22, 4, 4, 8], [39, 6, 4, 8]] + 0.000243129124011996767 # B[1018, [22, 4, 4, 8], [40, 6, 5, 7]] + 0.000433542078585167322 # B[1019, [22, 4, 4, 8], [41, 6, 6, 6]] + 5.87712210821707964e-05 # B[1020, [22, 4, 4, 8], [42, 6, 6, 8]] + -2.13873587015245281e-05 # B[1021, [22, 4, 4, 8], [43, 7, 0, 7]] + -0.00121671500578664389 # B[1022, [22, 4, 4, 8], [44, 7, 1, 8]] + 0.00185443425860575776 # B[1023, [22, 4, 4, 8], [45, 7, 2, 7]] + 0.00153976874095648406 # B[1024, [22, 4, 4, 8], [46, 7, 3, 8]] + 0.00100585852984078766 # B[1025, [22, 4, 4, 8], [47, 7, 4, 7]] + 0.000146502145157426621 # B[1026, [22, 4, 4, 8], [48, 7, 5, 8]] + 0.00026572798098887726 # B[1027, [22, 4, 4, 8], [49, 7, 6, 7]] + 0.000239744529446223043 # B[1028, [22, 4, 4, 8], [50, 7, 7, 8]] + 3.13331575558552233e-05 # B[1029, [22, 4, 4, 8], [51, 8, 0, 8]] + 0.0005761629631739415 # B[1030, [22, 4, 4, 8], [52, 8, 2, 8]] + 0.00020451472183747807 # B[1031, [22, 4, 4, 8], [53, 8, 4, 8]] + 0.000761501707699011737 # B[1032, [22, 4, 4, 8], [54, 8, 6, 8]] + 4.7608269104475881e-05 # B[1033, [22, 4, 4, 8], [55, 8, 8, 8]] + 0.00010288893231941848 # B[1034, [23, 5, 0, 5], [23, 5, 0, 5]] + -0.000598160679614365143 # B[1035, [23, 5, 0, 5], [24, 5, 1, 6]] + -0.000125600887517359969 # B[1036, [23, 5, 0, 5], [25, 5, 2, 5]] + -0.000541602347577959872 # B[1037, [23, 5, 0, 5], [26, 5, 2, 7]] + 0.000138742295315047448 # B[1038, [23, 5, 0, 5], [27, 5, 3, 6]] + 0.000320496112291311641 # B[1039, [23, 5, 0, 5], [28, 5, 3, 8]] + 9.77076363189860464e-05 # B[1040, [23, 5, 0, 5], [29, 5, 4, 5]] + -0.00018519393057754574 # B[1041, [23, 5, 0, 5], [30, 5, 4, 7]] + -0.000314308790209320843 # B[1042, [23, 5, 0, 5], [31, 5, 5, 6]] + -2.03507196530547385e-05 # B[1043, [23, 5, 0, 5], [32, 5, 5, 8]] + -8.76692912155085935e-08 # B[1044, [23, 5, 0, 5], [33, 6, 0, 6]] + -0.000208914241663854874 # B[1045, [23, 5, 0, 5], [34, 6, 1, 7]] + 0.000289191305925793653 # B[1046, [23, 5, 0, 5], [35, 6, 2, 6]] + 0.000292827060287376498 # B[1047, [23, 5, 0, 5], [36, 6, 2, 8]] + -0.000195999965143696386 # B[1048, [23, 5, 0, 5], [37, 6, 3, 7]] + 0.000122837407081860615 # B[1049, [23, 5, 0, 5], [38, 6, 4, 6]] + 0.000238061673948679331 # B[1050, [23, 5, 0, 5], [39, 6, 4, 8]] + 6.23458911314621333e-06 # B[1051, [23, 5, 0, 5], [40, 6, 5, 7]] + 0.000153645644536796327 # B[1052, [23, 5, 0, 5], [41, 6, 6, 6]] + 0.000208144485879115104 # B[1053, [23, 5, 0, 5], [42, 6, 6, 8]] + 0.000107382317423423967 # B[1054, [23, 5, 0, 5], [43, 7, 0, 7]] + -3.16437877474207152e-05 # B[1055, [23, 5, 0, 5], [44, 7, 1, 8]] + 5.2567890411161361e-05 # B[1056, [23, 5, 0, 5], [45, 7, 2, 7]] + -0.000407365287815795313 # B[1057, [23, 5, 0, 5], [46, 7, 3, 8]] + -0.000277007442936893014 # B[1058, [23, 5, 0, 5], [47, 7, 4, 7]] + -0.000163960409271388802 # B[1059, [23, 5, 0, 5], [48, 7, 5, 8]] + -0.00018222236229294142 # B[1060, [23, 5, 0, 5], [49, 7, 6, 7]] + -8.93725149996096868e-05 # B[1061, [23, 5, 0, 5], [50, 7, 7, 8]] + -4.59835267753172516e-05 # B[1062, [23, 5, 0, 5], [51, 8, 0, 8]] + -3.00980967951527262e-05 # B[1063, [23, 5, 0, 5], [52, 8, 2, 8]] + -0.00011786089545340328 # B[1064, [23, 5, 0, 5], [53, 8, 4, 8]] + 6.24840877215676604e-05 # B[1065, [23, 5, 0, 5], [54, 8, 6, 8]] + 0.000151333518371397913 # B[1066, [23, 5, 0, 5], [55, 8, 8, 8]] + -0.00373509601310103353 # B[1067, [24, 5, 1, 6], [24, 5, 1, 6]] + 0.00250350668234289742 # B[1068, [24, 5, 1, 6], [25, 5, 2, 5]] + -0.00141763987470412255 # B[1069, [24, 5, 1, 6], [26, 5, 2, 7]] + -0.000458490741576836162 # B[1070, [24, 5, 1, 6], [27, 5, 3, 6]] + 0.000169432811229417585 # B[1071, [24, 5, 1, 6], [28, 5, 3, 8]] + -0.000531768848310092699 # B[1072, [24, 5, 1, 6], [29, 5, 4, 5]] + 0.0019269207337581605 # B[1073, [24, 5, 1, 6], [30, 5, 4, 7]] + 0.000623468915929115824 # B[1074, [24, 5, 1, 6], [31, 5, 5, 6]] + 0.000262459747020924762 # B[1075, [24, 5, 1, 6], [32, 5, 5, 8]] + 0.000319464830252011445 # B[1076, [24, 5, 1, 6], [33, 6, 0, 6]] + 0.00250974732963905444 # B[1077, [24, 5, 1, 6], [34, 6, 1, 7]] + 0.00423653007687384807 # B[1078, [24, 5, 1, 6], [35, 6, 2, 6]] + 0.00144771358428595707 # B[1079, [24, 5, 1, 6], [36, 6, 2, 8]] + 0.00255496505633429419 # B[1080, [24, 5, 1, 6], [37, 6, 3, 7]] + -0.000923899857380450218 # B[1081, [24, 5, 1, 6], [38, 6, 4, 6]] + -0.000308666389289608337 # B[1082, [24, 5, 1, 6], [39, 6, 4, 8]] + 0.00222537659577300671 # B[1083, [24, 5, 1, 6], [40, 6, 5, 7]] + -0.00107541311587263343 # B[1084, [24, 5, 1, 6], [41, 6, 6, 6]] + -0.00278767944085371068 # B[1085, [24, 5, 1, 6], [42, 6, 6, 8]] + -0.000867530969177243705 # B[1086, [24, 5, 1, 6], [43, 7, 0, 7]] + 0.00357297895621819196 # B[1087, [24, 5, 1, 6], [44, 7, 1, 8]] + 0.00383976572090019216 # B[1088, [24, 5, 1, 6], [45, 7, 2, 7]] + -0.000580234942856992786 # B[1089, [24, 5, 1, 6], [46, 7, 3, 8]] + 0.00102888910081111798 # B[1090, [24, 5, 1, 6], [47, 7, 4, 7]] + 0.00132107614311613355 # B[1091, [24, 5, 1, 6], [48, 7, 5, 8]] + 0.00101848252621374036 # B[1092, [24, 5, 1, 6], [49, 7, 6, 7]] + 0.00160018234143227862 # B[1093, [24, 5, 1, 6], [50, 7, 7, 8]] + -5.52824024903572631e-05 # B[1094, [24, 5, 1, 6], [51, 8, 0, 8]] + 4.59186780197786033e-05 # B[1095, [24, 5, 1, 6], [52, 8, 2, 8]] + -0.000153436254581188554 # B[1096, [24, 5, 1, 6], [53, 8, 4, 8]] + -0.000546750998621967597 # B[1097, [24, 5, 1, 6], [54, 8, 6, 8]] + 0.000595956738118895348 # B[1098, [24, 5, 1, 6], [55, 8, 8, 8]] + 0.0083807047595118693 # B[1099, [25, 5, 2, 5], [25, 5, 2, 5]] + -0.000170544318645505719 # B[1100, [25, 5, 2, 5], [26, 5, 2, 7]] + 0.00235544441902155004 # B[1101, [25, 5, 2, 5], [27, 5, 3, 6]] + -0.00340197827063909962 # B[1102, [25, 5, 2, 5], [28, 5, 3, 8]] + 0.00311335525578198104 # B[1103, [25, 5, 2, 5], [29, 5, 4, 5]] + 0.00185214714164834123 # B[1104, [25, 5, 2, 5], [30, 5, 4, 7]] + -0.00328905913600528992 # B[1105, [25, 5, 2, 5], [31, 5, 5, 6]] + -0.00141866010082636025 # B[1106, [25, 5, 2, 5], [32, 5, 5, 8]] + 0.000176317033907393006 # B[1107, [25, 5, 2, 5], [33, 6, 0, 6]] + 0.00648328973805229608 # B[1108, [25, 5, 2, 5], [34, 6, 1, 7]] + 4.8980528358618259e-05 # B[1109, [25, 5, 2, 5], [35, 6, 2, 6]] + -0.00616971046300731144 # B[1110, [25, 5, 2, 5], [36, 6, 2, 8]] + -0.00135942372726050205 # B[1111, [25, 5, 2, 5], [37, 6, 3, 7]] + 0.000572735024796908881 # B[1112, [25, 5, 2, 5], [38, 6, 4, 6]] + -0.00229752149848994405 # B[1113, [25, 5, 2, 5], [39, 6, 4, 8]] + 0.0003485310815041524 # B[1114, [25, 5, 2, 5], [40, 6, 5, 7]] + -0.0011437361439647427 # B[1115, [25, 5, 2, 5], [41, 6, 6, 6]] + -0.000604819873822432311 # B[1116, [25, 5, 2, 5], [42, 6, 6, 8]] + 9.06237770597643696e-05 # B[1117, [25, 5, 2, 5], [43, 7, 0, 7]] + -0.000382141545017884894 # B[1118, [25, 5, 2, 5], [44, 7, 1, 8]] + -0.000842464094047663554 # B[1119, [25, 5, 2, 5], [45, 7, 2, 7]] + 0.000461973830441065811 # B[1120, [25, 5, 2, 5], [46, 7, 3, 8]] + 2.86192620363814355e-06 # B[1121, [25, 5, 2, 5], [47, 7, 4, 7]] + -0.0023436531447123838 # B[1122, [25, 5, 2, 5], [48, 7, 5, 8]] + 0.00134025173860287308 # B[1123, [25, 5, 2, 5], [49, 7, 6, 7]] + -0.000520013981518205846 # B[1124, [25, 5, 2, 5], [50, 7, 7, 8]] + 0.000515782740310496285 # B[1125, [25, 5, 2, 5], [51, 8, 0, 8]] + 0.00421651313615256564 # B[1126, [25, 5, 2, 5], [52, 8, 2, 8]] + 0.000755327719218409519 # B[1127, [25, 5, 2, 5], [53, 8, 4, 8]] + 0.000182937308412391315 # B[1128, [25, 5, 2, 5], [54, 8, 6, 8]] + 8.10383680097163071e-05 # B[1129, [25, 5, 2, 5], [55, 8, 8, 8]] + 0.000177735296666065024 # B[1130, [26, 5, 2, 7], [26, 5, 2, 7]] + -0.000642334677407747565 # B[1131, [26, 5, 2, 7], [27, 5, 3, 6]] + 0.000205172894139061396 # B[1132, [26, 5, 2, 7], [28, 5, 3, 8]] + -0.000537004220752698019 # B[1133, [26, 5, 2, 7], [29, 5, 4, 5]] + 5.14115941491347442e-05 # B[1134, [26, 5, 2, 7], [30, 5, 4, 7]] + 0.000417673445165051005 # B[1135, [26, 5, 2, 7], [31, 5, 5, 6]] + 0.00158446769775330391 # B[1136, [26, 5, 2, 7], [32, 5, 5, 8]] + 0.00121383407410429606 # B[1137, [26, 5, 2, 7], [33, 6, 0, 6]] + -0.00111992976945914785 # B[1138, [26, 5, 2, 7], [34, 6, 1, 7]] + 0.00398972286341117699 # B[1139, [26, 5, 2, 7], [35, 6, 2, 6]] + 0.00454565411209783762 # B[1140, [26, 5, 2, 7], [36, 6, 2, 8]] + -0.00300928796618537761 # B[1141, [26, 5, 2, 7], [37, 6, 3, 7]] + -0.00280024702462813163 # B[1142, [26, 5, 2, 7], [38, 6, 4, 6]] + 0.00182097597359056305 # B[1143, [26, 5, 2, 7], [39, 6, 4, 8]] + 0.00247143387165752772 # B[1144, [26, 5, 2, 7], [40, 6, 5, 7]] + -0.00143698477566456435 # B[1145, [26, 5, 2, 7], [41, 6, 6, 6]] + -0.00105878554545993375 # B[1146, [26, 5, 2, 7], [42, 6, 6, 8]] + 0.000650619036842032747 # B[1147, [26, 5, 2, 7], [43, 7, 0, 7]] + 8.72947879012740853e-05 # B[1148, [26, 5, 2, 7], [44, 7, 1, 8]] + -0.0002084941102769855 # B[1149, [26, 5, 2, 7], [45, 7, 2, 7]] + -0.000924608969529588931 # B[1150, [26, 5, 2, 7], [46, 7, 3, 8]] + -0.000320719808114693777 # B[1151, [26, 5, 2, 7], [47, 7, 4, 7]] + 0.00241998856780361801 # B[1152, [26, 5, 2, 7], [48, 7, 5, 8]] + -0.00171923440812344827 # B[1153, [26, 5, 2, 7], [49, 7, 6, 7]] + -0.000301390241580377569 # B[1154, [26, 5, 2, 7], [50, 7, 7, 8]] + -6.37461557401481499e-05 # B[1155, [26, 5, 2, 7], [51, 8, 0, 8]] + 0.00161644303684405446 # B[1156, [26, 5, 2, 7], [52, 8, 2, 8]] + 0.00104379414920739667 # B[1157, [26, 5, 2, 7], [53, 8, 4, 8]] + -0.00119795702190159808 # B[1158, [26, 5, 2, 7], [54, 8, 6, 8]] + 0.000604059138156293803 # B[1159, [26, 5, 2, 7], [55, 8, 8, 8]] + 0.000513459633959805622 # B[1160, [27, 5, 3, 6], [27, 5, 3, 6]] + -0.000172334638360790993 # B[1161, [27, 5, 3, 6], [28, 5, 3, 8]] + 1.60719061511648345e-05 # B[1162, [27, 5, 3, 6], [29, 5, 4, 5]] + 0.00440279299288983371 # B[1163, [27, 5, 3, 6], [30, 5, 4, 7]] + 0.000549761981236742206 # B[1164, [27, 5, 3, 6], [31, 5, 5, 6]] + 0.000424619689378998542 # B[1165, [27, 5, 3, 6], [32, 5, 5, 8]] + 0.000247367934895610653 # B[1166, [27, 5, 3, 6], [33, 6, 0, 6]] + 0.00400569055534595944 # B[1167, [27, 5, 3, 6], [34, 6, 1, 7]] + 0.00274378194299987679 # B[1168, [27, 5, 3, 6], [35, 6, 2, 6]] + 0.00368141326251353665 # B[1169, [27, 5, 3, 6], [36, 6, 2, 8]] + 0.00160469169395054817 # B[1170, [27, 5, 3, 6], [37, 6, 3, 7]] + 0.000105807739550402985 # B[1171, [27, 5, 3, 6], [38, 6, 4, 6]] + -0.000682801438033796976 # B[1172, [27, 5, 3, 6], [39, 6, 4, 8]] + -0.00121964915110857504 # B[1173, [27, 5, 3, 6], [40, 6, 5, 7]] + -0.000817665263990522556 # B[1174, [27, 5, 3, 6], [41, 6, 6, 6]] + 0.000534593784435832137 # B[1175, [27, 5, 3, 6], [42, 6, 6, 8]] + 0.000116542343021167755 # B[1176, [27, 5, 3, 6], [43, 7, 0, 7]] + 0.00351267154418699948 # B[1177, [27, 5, 3, 6], [44, 7, 1, 8]] + -0.00189934642995405814 # B[1178, [27, 5, 3, 6], [45, 7, 2, 7]] + 0.000751906974843792597 # B[1179, [27, 5, 3, 6], [46, 7, 3, 8]] + -0.000446808189773967301 # B[1180, [27, 5, 3, 6], [47, 7, 4, 7]] + -0.00324699511848197502 # B[1181, [27, 5, 3, 6], [48, 7, 5, 8]] + 2.53540837371335481e-05 # B[1182, [27, 5, 3, 6], [49, 7, 6, 7]] + 7.5273388360289073e-07 # B[1183, [27, 5, 3, 6], [50, 7, 7, 8]] + 0.00023346363571073725 # B[1184, [27, 5, 3, 6], [51, 8, 0, 8]] + 0.000490008984593369619 # B[1185, [27, 5, 3, 6], [52, 8, 2, 8]] + 0.000205260233742234413 # B[1186, [27, 5, 3, 6], [53, 8, 4, 8]] + -7.84984665939646165e-05 # B[1187, [27, 5, 3, 6], [54, 8, 6, 8]] + -0.000299454037036409743 # B[1188, [27, 5, 3, 6], [55, 8, 8, 8]] + -0.00411961786705090406 # B[1189, [28, 5, 3, 8], [28, 5, 3, 8]] + 0.00256764268592788759 # B[1190, [28, 5, 3, 8], [29, 5, 4, 5]] + -0.000267820435572239945 # B[1191, [28, 5, 3, 8], [30, 5, 4, 7]] + 0.000545048575291992229 # B[1192, [28, 5, 3, 8], [31, 5, 5, 6]] + -0.000141236037433873154 # B[1193, [28, 5, 3, 8], [32, 5, 5, 8]] + -8.17647193563642016e-05 # B[1194, [28, 5, 3, 8], [33, 6, 0, 6]] + 0.00184594470809960887 # B[1195, [28, 5, 3, 8], [34, 6, 1, 7]] + 0.000715653691449843685 # B[1196, [28, 5, 3, 8], [35, 6, 2, 6]] + -0.000371782729873919304 # B[1197, [28, 5, 3, 8], [36, 6, 2, 8]] + 0.00184451560473704312 # B[1198, [28, 5, 3, 8], [37, 6, 3, 7]] + 0.00298992898894900189 # B[1199, [28, 5, 3, 8], [38, 6, 4, 6]] + 0.00087474408278464047 # B[1200, [28, 5, 3, 8], [39, 6, 4, 8]] + 0.00115889056554823421 # B[1201, [28, 5, 3, 8], [40, 6, 5, 7]] + -0.000209440071593354482 # B[1202, [28, 5, 3, 8], [41, 6, 6, 6]] + 0.000707847416081031772 # B[1203, [28, 5, 3, 8], [42, 6, 6, 8]] + 0.00025922895119332573 # B[1204, [28, 5, 3, 8], [43, 7, 0, 7]] + -0.00210744601505012327 # B[1205, [28, 5, 3, 8], [44, 7, 1, 8]] + -0.00187401632149015486 # B[1206, [28, 5, 3, 8], [45, 7, 2, 7]] + 0.000616682247583759391 # B[1207, [28, 5, 3, 8], [46, 7, 3, 8]] + 0.00142526179781785924 # B[1208, [28, 5, 3, 8], [47, 7, 4, 7]] + -9.1619163886703936e-06 # B[1209, [28, 5, 3, 8], [48, 7, 5, 8]] + -0.000300978843055903222 # B[1210, [28, 5, 3, 8], [49, 7, 6, 7]] + -0.000124034381208077554 # B[1211, [28, 5, 3, 8], [50, 7, 7, 8]] + 0.000249158311162858692 # B[1212, [28, 5, 3, 8], [51, 8, 0, 8]] + -0.000970252220622513538 # B[1213, [28, 5, 3, 8], [52, 8, 2, 8]] + 0.000840312328335843066 # B[1214, [28, 5, 3, 8], [53, 8, 4, 8]] + 0.000145361901756495965 # B[1215, [28, 5, 3, 8], [54, 8, 6, 8]] + 0.00013163551986085896 # B[1216, [28, 5, 3, 8], [55, 8, 8, 8]] + 0.00265810885844912576 # B[1217, [29, 5, 4, 5], [29, 5, 4, 5]] + 0.00191793603428468823 # B[1218, [29, 5, 4, 5], [30, 5, 4, 7]] + 0.000446118694394436605 # B[1219, [29, 5, 4, 5], [31, 5, 5, 6]] + -9.59445098255573559e-05 # B[1220, [29, 5, 4, 5], [32, 5, 5, 8]] + 0.000369255428727587043 # B[1221, [29, 5, 4, 5], [33, 6, 0, 6]] + -0.000553149628059141762 # B[1222, [29, 5, 4, 5], [34, 6, 1, 7]] + 0.00315275275750991242 # B[1223, [29, 5, 4, 5], [35, 6, 2, 6]] + 0.00138540352181828336 # B[1224, [29, 5, 4, 5], [36, 6, 2, 8]] + 0.000776256233303879162 # B[1225, [29, 5, 4, 5], [37, 6, 3, 7]] + 0.000594477884906325672 # B[1226, [29, 5, 4, 5], [38, 6, 4, 6]] + 0.000757712543509288586 # B[1227, [29, 5, 4, 5], [39, 6, 4, 8]] + -0.000917903532807641184 # B[1228, [29, 5, 4, 5], [40, 6, 5, 7]] + -0.000915313398456763742 # B[1229, [29, 5, 4, 5], [41, 6, 6, 6]] + -0.00116732293566375843 # B[1230, [29, 5, 4, 5], [42, 6, 6, 8]] + 0.000172432189541951719 # B[1231, [29, 5, 4, 5], [43, 7, 0, 7]] + 0.000845370011774060912 # B[1232, [29, 5, 4, 5], [44, 7, 1, 8]] + 0.00178029205661471915 # B[1233, [29, 5, 4, 5], [45, 7, 2, 7]] + 0.00129739636685697463 # B[1234, [29, 5, 4, 5], [46, 7, 3, 8]] + 0.000282865369400489564 # B[1235, [29, 5, 4, 5], [47, 7, 4, 7]] + -0.00178988233479955398 # B[1236, [29, 5, 4, 5], [48, 7, 5, 8]] + 0.00023603474784275949 # B[1237, [29, 5, 4, 5], [49, 7, 6, 7]] + -0.000461436431325358207 # B[1238, [29, 5, 4, 5], [50, 7, 7, 8]] + 0.000234131705926524103 # B[1239, [29, 5, 4, 5], [51, 8, 0, 8]] + 0.00216254821351878363 # B[1240, [29, 5, 4, 5], [52, 8, 2, 8]] + 0.000831658742681578439 # B[1241, [29, 5, 4, 5], [53, 8, 4, 8]] + -0.00046318901257626742 # B[1242, [29, 5, 4, 5], [54, 8, 6, 8]] + -0.000607580535321294163 # B[1243, [29, 5, 4, 5], [55, 8, 8, 8]] + 0.00158347719827001653 # B[1244, [30, 5, 4, 7], [30, 5, 4, 7]] + 0.00120733638068271261 # B[1245, [30, 5, 4, 7], [31, 5, 5, 6]] + -0.000191610125195333311 # B[1246, [30, 5, 4, 7], [32, 5, 5, 8]] + -0.000363280761575070915 # B[1247, [30, 5, 4, 7], [33, 6, 0, 6]] + 0.0015080393447339897 # B[1248, [30, 5, 4, 7], [34, 6, 1, 7]] + 0.00144737958774105498 # B[1249, [30, 5, 4, 7], [35, 6, 2, 6]] + -0.000191256340607337365 # B[1250, [30, 5, 4, 7], [36, 6, 2, 8]] + 0.00324542123326504103 # B[1251, [30, 5, 4, 7], [37, 6, 3, 7]] + 0.00135369467391198949 # B[1252, [30, 5, 4, 7], [38, 6, 4, 6]] + 0.00077393986417062131 # B[1253, [30, 5, 4, 7], [39, 6, 4, 8]] + 0.00187057819081324836 # B[1254, [30, 5, 4, 7], [40, 6, 5, 7]] + 4.06728949024891956e-05 # B[1255, [30, 5, 4, 7], [41, 6, 6, 6]] + -0.000100060243024913467 # B[1256, [30, 5, 4, 7], [42, 6, 6, 8]] + -0.000170624797097965186 # B[1257, [30, 5, 4, 7], [43, 7, 0, 7]] + -0.00157200294852092963 # B[1258, [30, 5, 4, 7], [44, 7, 1, 8]] + -5.099465391029262e-05 # B[1259, [30, 5, 4, 7], [45, 7, 2, 7]] + 0.00166973065524506255 # B[1260, [30, 5, 4, 7], [46, 7, 3, 8]] + 0.000976468235486894175 # B[1261, [30, 5, 4, 7], [47, 7, 4, 7]] + -0.000570830124590235299 # B[1262, [30, 5, 4, 7], [48, 7, 5, 8]] + 0.000667250794893839427 # B[1263, [30, 5, 4, 7], [49, 7, 6, 7]] + -0.000273376565753529832 # B[1264, [30, 5, 4, 7], [50, 7, 7, 8]] + 0.000206233716860107844 # B[1265, [30, 5, 4, 7], [51, 8, 0, 8]] + 0.00260342927157033218 # B[1266, [30, 5, 4, 7], [52, 8, 2, 8]] + 0.000943954042545826558 # B[1267, [30, 5, 4, 7], [53, 8, 4, 8]] + -0.00022781927635321525 # B[1268, [30, 5, 4, 7], [54, 8, 6, 8]] + -0.000448456045604168733 # B[1269, [30, 5, 4, 7], [55, 8, 8, 8]] + 0.00102985782764508475 # B[1270, [31, 5, 5, 6], [31, 5, 5, 6]] + -8.89908688742153606e-05 # B[1271, [31, 5, 5, 6], [32, 5, 5, 8]] + -0.000162481274467801695 # B[1272, [31, 5, 5, 6], [33, 6, 0, 6]] + 0.00263772603538907271 # B[1273, [31, 5, 5, 6], [34, 6, 1, 7]] + -0.00223528099165903275 # B[1274, [31, 5, 5, 6], [35, 6, 2, 6]] + 0.000441657599119526373 # B[1275, [31, 5, 5, 6], [36, 6, 2, 8]] + 0.00165514785004864176 # B[1276, [31, 5, 5, 6], [37, 6, 3, 7]] + 0.000898928585103351413 # B[1277, [31, 5, 5, 6], [38, 6, 4, 6]] + -0.00026071204606309753 # B[1278, [31, 5, 5, 6], [39, 6, 4, 8]] + -0.000251612913047311385 # B[1279, [31, 5, 5, 6], [40, 6, 5, 7]] + -0.00022773870089292346 # B[1280, [31, 5, 5, 6], [41, 6, 6, 6]] + -0.000449951686975022525 # B[1281, [31, 5, 5, 6], [42, 6, 6, 8]] + -0.000252400784021909741 # B[1282, [31, 5, 5, 6], [43, 7, 0, 7]] + 0.000574433272355396977 # B[1283, [31, 5, 5, 6], [44, 7, 1, 8]] + -0.0014040949400035245 # B[1284, [31, 5, 5, 6], [45, 7, 2, 7]] + 0.00124516802775002586 # B[1285, [31, 5, 5, 6], [46, 7, 3, 8]] + 0.000875572292146320832 # B[1286, [31, 5, 5, 6], [47, 7, 4, 7]] + -0.000509730931921630048 # B[1287, [31, 5, 5, 6], [48, 7, 5, 8]] + 0.000422266146488117777 # B[1288, [31, 5, 5, 6], [49, 7, 6, 7]] + -0.000239146684560266956 # B[1289, [31, 5, 5, 6], [50, 7, 7, 8]] + 9.95899703990707486e-05 # B[1290, [31, 5, 5, 6], [51, 8, 0, 8]] + -0.0020784147827535588 # B[1291, [31, 5, 5, 6], [52, 8, 2, 8]] + 0.000735684723224858811 # B[1292, [31, 5, 5, 6], [53, 8, 4, 8]] + -0.000248804810033285279 # B[1293, [31, 5, 5, 6], [54, 8, 6, 8]] + -0.000598263607047986451 # B[1294, [31, 5, 5, 6], [55, 8, 8, 8]] + 0.000131065920905359436 # B[1295, [32, 5, 5, 8], [32, 5, 5, 8]] + 0.000100196796943449913 # B[1296, [32, 5, 5, 8], [33, 6, 0, 6]] + -0.00173991171955805834 # B[1297, [32, 5, 5, 8], [34, 6, 1, 7]] + -0.000490539010579770906 # B[1298, [32, 5, 5, 8], [35, 6, 2, 6]] + 0.000676191083650941674 # B[1299, [32, 5, 5, 8], [36, 6, 2, 8]] + 0.000446932761165407325 # B[1300, [32, 5, 5, 8], [37, 6, 3, 7]] + -0.000153107558622965576 # B[1301, [32, 5, 5, 8], [38, 6, 4, 6]] + 1.67752859932734574e-05 # B[1302, [32, 5, 5, 8], [39, 6, 4, 8]] + 0.000215146896189506113 # B[1303, [32, 5, 5, 8], [40, 6, 5, 7]] + -0.000188466441880926362 # B[1304, [32, 5, 5, 8], [41, 6, 6, 6]] + -4.80917708388720055e-06 # B[1305, [32, 5, 5, 8], [42, 6, 6, 8]] + -5.04429979448911547e-05 # B[1306, [32, 5, 5, 8], [43, 7, 0, 7]] + -0.000494944862407609067 # B[1307, [32, 5, 5, 8], [44, 7, 1, 8]] + -0.000424473825928651724 # B[1308, [32, 5, 5, 8], [45, 7, 2, 7]] + 0.000417544384337296959 # B[1309, [32, 5, 5, 8], [46, 7, 3, 8]] + 0.000431586591455488614 # B[1310, [32, 5, 5, 8], [47, 7, 4, 7]] + 0.000187341827588022357 # B[1311, [32, 5, 5, 8], [48, 7, 5, 8]] + -6.87669988055673864e-05 # B[1312, [32, 5, 5, 8], [49, 7, 6, 7]] + 0.000147867669408649482 # B[1313, [32, 5, 5, 8], [50, 7, 7, 8]] + -7.32201679551347517e-06 # B[1314, [32, 5, 5, 8], [51, 8, 0, 8]] + -0.000392519615947300787 # B[1315, [32, 5, 5, 8], [52, 8, 2, 8]] + 8.78465325612771269e-05 # B[1316, [32, 5, 5, 8], [53, 8, 4, 8]] + -6.3960070015590606e-05 # B[1317, [32, 5, 5, 8], [54, 8, 6, 8]] + -7.97839909379757101e-06 # B[1318, [32, 5, 5, 8], [55, 8, 8, 8]] + 3.95695067041609838e-05 # B[1319, [33, 6, 0, 6], [33, 6, 0, 6]] + -0.000611658005184461534 # B[1320, [33, 6, 0, 6], [34, 6, 1, 7]] + -0.000277914808470863806 # B[1321, [33, 6, 0, 6], [35, 6, 2, 6]] + 0.000987938388973043716 # B[1322, [33, 6, 0, 6], [36, 6, 2, 8]] + 0.000198558948919527745 # B[1323, [33, 6, 0, 6], [37, 6, 3, 7]] + 9.76274805398642809e-05 # B[1324, [33, 6, 0, 6], [38, 6, 4, 6]] + 9.92197766131464043e-05 # B[1325, [33, 6, 0, 6], [39, 6, 4, 8]] + -4.16996931875308896e-05 # B[1326, [33, 6, 0, 6], [40, 6, 5, 7]] + -5.3495059095630057e-05 # B[1327, [33, 6, 0, 6], [41, 6, 6, 6]] + 1.0720822351671655e-05 # B[1328, [33, 6, 0, 6], [42, 6, 6, 8]] + 0.000114464898537391946 # B[1329, [33, 6, 0, 6], [43, 7, 0, 7]] + -0.00033593422820483651 # B[1330, [33, 6, 0, 6], [44, 7, 1, 8]] + -0.00061665800523461739 # B[1331, [33, 6, 0, 6], [45, 7, 2, 7]] + -0.000258302532232180387 # B[1332, [33, 6, 0, 6], [46, 7, 3, 8]] + 3.78181072490033077e-05 # B[1333, [33, 6, 0, 6], [47, 7, 4, 7]] + -0.000326273283142861775 # B[1334, [33, 6, 0, 6], [48, 7, 5, 8]] + 1.74277156155672186e-05 # B[1335, [33, 6, 0, 6], [49, 7, 6, 7]] + -0.000206600107910874173 # B[1336, [33, 6, 0, 6], [50, 7, 7, 8]] + 2.12855018918572947e-05 # B[1337, [33, 6, 0, 6], [51, 8, 0, 8]] + -0.000696835386532819456 # B[1338, [33, 6, 0, 6], [52, 8, 2, 8]] + 8.06841007746916805e-05 # B[1339, [33, 6, 0, 6], [53, 8, 4, 8]] + 1.96129469472779844e-05 # B[1340, [33, 6, 0, 6], [54, 8, 6, 8]] + 7.35114191380559223e-05 # B[1341, [33, 6, 0, 6], [55, 8, 8, 8]] + 0.00360109138862139185 # B[1342, [34, 6, 1, 7], [34, 6, 1, 7]] + 0.00304872474261531218 # B[1343, [34, 6, 1, 7], [35, 6, 2, 6]] + -0.00546316824530662139 # B[1344, [34, 6, 1, 7], [36, 6, 2, 8]] + 0.000721988419001898946 # B[1345, [34, 6, 1, 7], [37, 6, 3, 7]] + -0.00254968694435141717 # B[1346, [34, 6, 1, 7], [38, 6, 4, 6]] + -0.00102187793811427596 # B[1347, [34, 6, 1, 7], [39, 6, 4, 8]] + 0.000977866285507509106 # B[1348, [34, 6, 1, 7], [40, 6, 5, 7]] + 0.00129156024637028417 # B[1349, [34, 6, 1, 7], [41, 6, 6, 6]] + 8.43980229575398005e-05 # B[1350, [34, 6, 1, 7], [42, 6, 6, 8]] + -0.000854491821273548058 # B[1351, [34, 6, 1, 7], [43, 7, 0, 7]] + -0.00229655360277009144 # B[1352, [34, 6, 1, 7], [44, 7, 1, 8]] + 0.00392740594657482126 # B[1353, [34, 6, 1, 7], [45, 7, 2, 7]] + 0.00282086313880587115 # B[1354, [34, 6, 1, 7], [46, 7, 3, 8]] + -0.00269367822401865922 # B[1355, [34, 6, 1, 7], [47, 7, 4, 7]] + 0.00120544917432826269 # B[1356, [34, 6, 1, 7], [48, 7, 5, 8]] + 0.00137213082032611872 # B[1357, [34, 6, 1, 7], [49, 7, 6, 7]] + 0.00278774897747785522 # B[1358, [34, 6, 1, 7], [50, 7, 7, 8]] + -1.00075929411755707e-05 # B[1359, [34, 6, 1, 7], [51, 8, 0, 8]] + 0.00331402709384703321 # B[1360, [34, 6, 1, 7], [52, 8, 2, 8]] + -0.00220016465090739841 # B[1361, [34, 6, 1, 7], [53, 8, 4, 8]] + 0.000794479619849004434 # B[1362, [34, 6, 1, 7], [54, 8, 6, 8]] + 0.000207117210070053084 # B[1363, [34, 6, 1, 7], [55, 8, 8, 8]] + 0.000547206364960122621 # B[1364, [35, 6, 2, 6], [35, 6, 2, 6]] + 0.00243529980905243717 # B[1365, [35, 6, 2, 6], [36, 6, 2, 8]] + 0.000346076245330416421 # B[1366, [35, 6, 2, 6], [37, 6, 3, 7]] + 0.00220550296989585788 # B[1367, [35, 6, 2, 6], [38, 6, 4, 6]] + 0.00101934408216735467 # B[1368, [35, 6, 2, 6], [39, 6, 4, 8]] + 6.76995447894471192e-05 # B[1369, [35, 6, 2, 6], [40, 6, 5, 7]] + -4.61734905116591154e-05 # B[1370, [35, 6, 2, 6], [41, 6, 6, 6]] + 0.000809543629624515093 # B[1371, [35, 6, 2, 6], [42, 6, 6, 8]] + 0.000219078295465409238 # B[1372, [35, 6, 2, 6], [43, 7, 0, 7]] + -0.00316872925249137884 # B[1373, [35, 6, 2, 6], [44, 7, 1, 8]] + 0.000676713636760976206 # B[1374, [35, 6, 2, 6], [45, 7, 2, 7]] + -0.00100477918211841141 # B[1375, [35, 6, 2, 6], [46, 7, 3, 8]] + 0.000400524978896980161 # B[1376, [35, 6, 2, 6], [47, 7, 4, 7]] + -0.00197634098305848622 # B[1377, [35, 6, 2, 6], [48, 7, 5, 8]] + 0.000367979983554051621 # B[1378, [35, 6, 2, 6], [49, 7, 6, 7]] + -0.00126672502130457942 # B[1379, [35, 6, 2, 6], [50, 7, 7, 8]] + 0.000161373464169148675 # B[1380, [35, 6, 2, 6], [51, 8, 0, 8]] + 0.00258770627559228462 # B[1381, [35, 6, 2, 6], [52, 8, 2, 8]] + 0.000816135012742828661 # B[1382, [35, 6, 2, 6], [53, 8, 4, 8]] + -3.28991122771973843e-05 # B[1383, [35, 6, 2, 6], [54, 8, 6, 8]] + -4.18127338362338707e-05 # B[1384, [35, 6, 2, 6], [55, 8, 8, 8]] + 0.00658745572292138409 # B[1385, [36, 6, 2, 8], [36, 6, 2, 8]] + -0.00238764687643479301 # B[1386, [36, 6, 2, 8], [37, 6, 3, 7]] + -0.000831950910425274803 # B[1387, [36, 6, 2, 8], [38, 6, 4, 6]] + 0.00351737364404769177 # B[1388, [36, 6, 2, 8], [39, 6, 4, 8]] + -0.00276293358095670936 # B[1389, [36, 6, 2, 8], [40, 6, 5, 7]] + -0.00115031008308692437 # B[1390, [36, 6, 2, 8], [41, 6, 6, 6]] + -0.000921624256609663434 # B[1391, [36, 6, 2, 8], [42, 6, 6, 8]] + 0.000810924380859275734 # B[1392, [36, 6, 2, 8], [43, 7, 0, 7]] + -0.00488922361819911239 # B[1393, [36, 6, 2, 8], [44, 7, 1, 8]] + 0.00170426259508682162 # B[1394, [36, 6, 2, 8], [45, 7, 2, 7]] + -0.000698037236981145087 # B[1395, [36, 6, 2, 8], [46, 7, 3, 8]] + -0.00159293071425275958 # B[1396, [36, 6, 2, 8], [47, 7, 4, 7]] + 0.00145526568566858513 # B[1397, [36, 6, 2, 8], [48, 7, 5, 8]] + -0.0034526631911915729 # B[1398, [36, 6, 2, 8], [49, 7, 6, 7]] + 0.00136118079841816148 # B[1399, [36, 6, 2, 8], [50, 7, 7, 8]] + -0.000519558666561149851 # B[1400, [36, 6, 2, 8], [51, 8, 0, 8]] + -0.00125430728243427136 # B[1401, [36, 6, 2, 8], [52, 8, 2, 8]] + 0.000225746730173992209 # B[1402, [36, 6, 2, 8], [53, 8, 4, 8]] + 0.000144081610870761424 # B[1403, [36, 6, 2, 8], [54, 8, 6, 8]] + 0.000848192939185923693 # B[1404, [36, 6, 2, 8], [55, 8, 8, 8]] + 0.00209760366601450393 # B[1405, [37, 6, 3, 7], [37, 6, 3, 7]] + -0.00114098142783233825 # B[1406, [37, 6, 3, 7], [38, 6, 4, 6]] + -0.00012482798433224862 # B[1407, [37, 6, 3, 7], [39, 6, 4, 8]] + 0.000414303981445450498 # B[1408, [37, 6, 3, 7], [40, 6, 5, 7]] + -2.06949976952613968e-05 # B[1409, [37, 6, 3, 7], [41, 6, 6, 6]] + 0.000986658381613915447 # B[1410, [37, 6, 3, 7], [42, 6, 6, 8]] + 0.000196361012595618056 # B[1411, [37, 6, 3, 7], [43, 7, 0, 7]] + 0.000421620511108736218 # B[1412, [37, 6, 3, 7], [44, 7, 1, 8]] + -0.00121366957406692996 # B[1413, [37, 6, 3, 7], [45, 7, 2, 7]] + 0.000319772245183778947 # B[1414, [37, 6, 3, 7], [46, 7, 3, 8]] + -0.00189440310525268441 # B[1415, [37, 6, 3, 7], [47, 7, 4, 7]] + -0.000420808921505540223 # B[1416, [37, 6, 3, 7], [48, 7, 5, 8]] + -0.000833056882638676111 # B[1417, [37, 6, 3, 7], [49, 7, 6, 7]] + -0.000210394181928773294 # B[1418, [37, 6, 3, 7], [50, 7, 7, 8]] + 4.67415997983874898e-05 # B[1419, [37, 6, 3, 7], [51, 8, 0, 8]] + -0.000629437221263145228 # B[1420, [37, 6, 3, 7], [52, 8, 2, 8]] + -0.000561739301858470846 # B[1421, [37, 6, 3, 7], [53, 8, 4, 8]] + -0.000244403089656959616 # B[1422, [37, 6, 3, 7], [54, 8, 6, 8]] + 0.000170058213410727299 # B[1423, [37, 6, 3, 7], [55, 8, 8, 8]] + 0.000190580820336867102 # B[1424, [38, 6, 4, 6], [38, 6, 4, 6]] + -5.17086422710446442e-05 # B[1425, [38, 6, 4, 6], [39, 6, 4, 8]] + -0.000870479233908965505 # B[1426, [38, 6, 4, 6], [40, 6, 5, 7]] + 8.56431173592298034e-05 # B[1427, [38, 6, 4, 6], [41, 6, 6, 6]] + -0.000219028113680014638 # B[1428, [38, 6, 4, 6], [42, 6, 6, 8]] + 6.99094597341239771e-05 # B[1429, [38, 6, 4, 6], [43, 7, 0, 7]] + -0.00217214753267054063 # B[1430, [38, 6, 4, 6], [44, 7, 1, 8]] + 0.00103452950595812193 # B[1431, [38, 6, 4, 6], [45, 7, 2, 7]] + 0.000131158053198399821 # B[1432, [38, 6, 4, 6], [46, 7, 3, 8]] + -0.000991288929959081421 # B[1433, [38, 6, 4, 6], [47, 7, 4, 7]] + -0.000321058899826150157 # B[1434, [38, 6, 4, 6], [48, 7, 5, 8]] + -0.000126379357764709599 # B[1435, [38, 6, 4, 6], [49, 7, 6, 7]] + 0.000513859397020456632 # B[1436, [38, 6, 4, 6], [50, 7, 7, 8]] + -2.72482190626921472e-05 # B[1437, [38, 6, 4, 6], [51, 8, 0, 8]] + 0.000742781076179950886 # B[1438, [38, 6, 4, 6], [52, 8, 2, 8]] + -9.17701606060090935e-05 # B[1439, [38, 6, 4, 6], [53, 8, 4, 8]] + 1.49768390447675703e-05 # B[1440, [38, 6, 4, 6], [54, 8, 6, 8]] + -5.94521118466549703e-05 # B[1441, [38, 6, 4, 6], [55, 8, 8, 8]] + 0.00161400415689978271 # B[1442, [39, 6, 4, 8], [39, 6, 4, 8]] + -0.000149892220376375129 # B[1443, [39, 6, 4, 8], [40, 6, 5, 7]] + -0.000242832088631229209 # B[1444, [39, 6, 4, 8], [41, 6, 6, 6]] + -4.23223006292567511e-05 # B[1445, [39, 6, 4, 8], [42, 6, 6, 8]] + 0.000145544599928226076 # B[1446, [39, 6, 4, 8], [43, 7, 0, 7]] + -0.000846976149028450323 # B[1447, [39, 6, 4, 8], [44, 7, 1, 8]] + 0.000313402576083809947 # B[1448, [39, 6, 4, 8], [45, 7, 2, 7]] + -0.00105304559168569421 # B[1449, [39, 6, 4, 8], [46, 7, 3, 8]] + -0.000563622717067245593 # B[1450, [39, 6, 4, 8], [47, 7, 4, 7]] + -0.000176248327800098206 # B[1451, [39, 6, 4, 8], [48, 7, 5, 8]] + -0.000523005481859822874 # B[1452, [39, 6, 4, 8], [49, 7, 6, 7]] + 0.000327425878709725754 # B[1453, [39, 6, 4, 8], [50, 7, 7, 8]] + -0.000214075091648432969 # B[1454, [39, 6, 4, 8], [51, 8, 0, 8]] + 0.000892962890338189208 # B[1455, [39, 6, 4, 8], [52, 8, 2, 8]] + 0.000483016760753301674 # B[1456, [39, 6, 4, 8], [53, 8, 4, 8]] + 0.000385986009520520711 # B[1457, [39, 6, 4, 8], [54, 8, 6, 8]] + 0.000210387221014841225 # B[1458, [39, 6, 4, 8], [55, 8, 8, 8]] + 0.000423894835630976054 # B[1459, [40, 6, 5, 7], [40, 6, 5, 7]] + 2.52152593651043533e-05 # B[1460, [40, 6, 5, 7], [41, 6, 6, 6]] + 0.0001406783760301792 # B[1461, [40, 6, 5, 7], [42, 6, 6, 8]] + -0.000402862939603353815 # B[1462, [40, 6, 5, 7], [43, 7, 0, 7]] + -0.000764679971924708997 # B[1463, [40, 6, 5, 7], [44, 7, 1, 8]] + 0.000690122720081854865 # B[1464, [40, 6, 5, 7], [45, 7, 2, 7]] + 0.00135911524951161378 # B[1465, [40, 6, 5, 7], [46, 7, 3, 8]] + 5.52075818169902449e-06 # B[1466, [40, 6, 5, 7], [47, 7, 4, 7]] + -0.000149902773226399076 # B[1467, [40, 6, 5, 7], [48, 7, 5, 8]] + 0.000389894625400750289 # B[1468, [40, 6, 5, 7], [49, 7, 6, 7]] + 0.000257807843360047251 # B[1469, [40, 6, 5, 7], [50, 7, 7, 8]] + -3.67912373811542237e-05 # B[1470, [40, 6, 5, 7], [51, 8, 0, 8]] + -0.000174743024771516643 # B[1471, [40, 6, 5, 7], [52, 8, 2, 8]] + 0.000276798622678277838 # B[1472, [40, 6, 5, 7], [53, 8, 4, 8]] + 0.000152459620483783032 # B[1473, [40, 6, 5, 7], [54, 8, 6, 8]] + -0.000616599602238733502 # B[1474, [40, 6, 5, 7], [55, 8, 8, 8]] + -5.12324624723156652e-05 # B[1475, [41, 6, 6, 6], [41, 6, 6, 6]] + -4.23334509430418893e-05 # B[1476, [41, 6, 6, 6], [42, 6, 6, 8]] + -0.000111212733055157664 # B[1477, [41, 6, 6, 6], [43, 7, 0, 7]] + 0.000882360189618891337 # B[1478, [41, 6, 6, 6], [44, 7, 1, 8]] + -0.000581964842687935843 # B[1479, [41, 6, 6, 6], [45, 7, 2, 7]] + 0.000211138997961872465 # B[1480, [41, 6, 6, 6], [46, 7, 3, 8]] + 7.79906436828414068e-05 # B[1481, [41, 6, 6, 6], [47, 7, 4, 7]] + -0.000201461425275273331 # B[1482, [41, 6, 6, 6], [48, 7, 5, 8]] + 6.87828589884392771e-05 # B[1483, [41, 6, 6, 6], [49, 7, 6, 7]] + 0.000150653067204437052 # B[1484, [41, 6, 6, 6], [50, 7, 7, 8]] + 3.87532549918634395e-05 # B[1485, [41, 6, 6, 6], [51, 8, 0, 8]] + 0.000361299779465781672 # B[1486, [41, 6, 6, 6], [52, 8, 2, 8]] + -0.000217385549744270783 # B[1487, [41, 6, 6, 6], [53, 8, 4, 8]] + 6.09508622621875856e-05 # B[1488, [41, 6, 6, 6], [54, 8, 6, 8]] + -0.000174447165900721429 # B[1489, [41, 6, 6, 6], [55, 8, 8, 8]] + 4.08451735536830007e-05 # B[1490, [42, 6, 6, 8], [42, 6, 6, 8]] + -0.000100109250872669128 # B[1491, [42, 6, 6, 8], [43, 7, 0, 7]] + 0.000543796967600337564 # B[1492, [42, 6, 6, 8], [44, 7, 1, 8]] + 0.000744432946735457124 # B[1493, [42, 6, 6, 8], [45, 7, 2, 7]] + 0.0010803210667922683 # B[1494, [42, 6, 6, 8], [46, 7, 3, 8]] + 0.000151445105968722347 # B[1495, [42, 6, 6, 8], [47, 7, 4, 7]] + -0.000100848877598445907 # B[1496, [42, 6, 6, 8], [48, 7, 5, 8]] + -0.000109088350721993355 # B[1497, [42, 6, 6, 8], [49, 7, 6, 7]] + -0.000287924009882135207 # B[1498, [42, 6, 6, 8], [50, 7, 7, 8]] + 1.48405987461727729e-05 # B[1499, [42, 6, 6, 8], [51, 8, 0, 8]] + 0.00133229142431166023 # B[1500, [42, 6, 6, 8], [52, 8, 2, 8]] + -0.00019157481902659472 # B[1501, [42, 6, 6, 8], [53, 8, 4, 8]] + -0.000214414469154704246 # B[1502, [42, 6, 6, 8], [54, 8, 6, 8]] + -0.000145460173238021184 # B[1503, [42, 6, 6, 8], [55, 8, 8, 8]] + 0.000122164068846408735 # B[1504, [43, 7, 0, 7], [43, 7, 0, 7]] + -0.000271198052548764657 # B[1505, [43, 7, 0, 7], [44, 7, 1, 8]] + -7.53020792218089818e-05 # B[1506, [43, 7, 0, 7], [45, 7, 2, 7]] + -0.000522043739406908344 # B[1507, [43, 7, 0, 7], [46, 7, 3, 8]] + -4.818852612961666e-05 # B[1508, [43, 7, 0, 7], [47, 7, 4, 7]] + -0.000220542438614808323 # B[1509, [43, 7, 0, 7], [48, 7, 5, 8]] + -0.000160998835878327362 # B[1510, [43, 7, 0, 7], [49, 7, 6, 7]] + -2.41628428966911279e-05 # B[1511, [43, 7, 0, 7], [50, 7, 7, 8]] + -1.41474469189661889e-05 # B[1512, [43, 7, 0, 7], [51, 8, 0, 8]] + -0.000160534811881916234 # B[1513, [43, 7, 0, 7], [52, 8, 2, 8]] + -1.73735621299461046e-05 # B[1514, [43, 7, 0, 7], [53, 8, 4, 8]] + 4.73251016045242445e-05 # B[1515, [43, 7, 0, 7], [54, 8, 6, 8]] + 0.000182463508348683356 # B[1516, [43, 7, 0, 7], [55, 8, 8, 8]] + -0.000629134879565343137 # B[1517, [44, 7, 1, 8], [44, 7, 1, 8]] + -0.00207361578267727673 # B[1518, [44, 7, 1, 8], [45, 7, 2, 7]] + 0.0031686999001355326 # B[1519, [44, 7, 1, 8], [46, 7, 3, 8]] + -0.000405403647932546952 # B[1520, [44, 7, 1, 8], [47, 7, 4, 7]] + -0.000111251617971438489 # B[1521, [44, 7, 1, 8], [48, 7, 5, 8]] + 0.0014482690523848242 # B[1522, [44, 7, 1, 8], [49, 7, 6, 7]] + 0.000818892450912583197 # B[1523, [44, 7, 1, 8], [50, 7, 7, 8]] + 0.000100422502558870572 # B[1524, [44, 7, 1, 8], [51, 8, 0, 8]] + -0.000412863674396233161 # B[1525, [44, 7, 1, 8], [52, 8, 2, 8]] + -0.000905494278120194153 # B[1526, [44, 7, 1, 8], [53, 8, 4, 8]] + 0.00126932173443552359 # B[1527, [44, 7, 1, 8], [54, 8, 6, 8]] + -0.000374814469421512735 # B[1528, [44, 7, 1, 8], [55, 8, 8, 8]] + -0.00330341133748704441 # B[1529, [45, 7, 2, 7], [45, 7, 2, 7]] + 0.00131616674488897398 # B[1530, [45, 7, 2, 7], [46, 7, 3, 8]] + -0.000483635326292886428 # B[1531, [45, 7, 2, 7], [47, 7, 4, 7]] + -0.00177550615332965067 # B[1532, [45, 7, 2, 7], [48, 7, 5, 8]] + 0.00226091969304176299 # B[1533, [45, 7, 2, 7], [49, 7, 6, 7]] + -0.00142635978155006456 # B[1534, [45, 7, 2, 7], [50, 7, 7, 8]] + 0.000289476939908078768 # B[1535, [45, 7, 2, 7], [51, 8, 0, 8]] + 0.000582488578419503846 # B[1536, [45, 7, 2, 7], [52, 8, 2, 8]] + -0.000228795123723987606 # B[1537, [45, 7, 2, 7], [53, 8, 4, 8]] + 0.000478658611037000373 # B[1538, [45, 7, 2, 7], [54, 8, 6, 8]] + -0.00101956994563059782 # B[1539, [45, 7, 2, 7], [55, 8, 8, 8]] + 0.00268648192223141895 # B[1540, [46, 7, 3, 8], [46, 7, 3, 8]] + 0.000515570689344949529 # B[1541, [46, 7, 3, 8], [47, 7, 4, 7]] + 0.000903689215066725768 # B[1542, [46, 7, 3, 8], [48, 7, 5, 8]] + 0.00180650309403464215 # B[1543, [46, 7, 3, 8], [49, 7, 6, 7]] + -7.48574841450792838e-05 # B[1544, [46, 7, 3, 8], [50, 7, 7, 8]] + -2.90930360741237237e-05 # B[1545, [46, 7, 3, 8], [51, 8, 0, 8]] + 0.00139057844941538594 # B[1546, [46, 7, 3, 8], [52, 8, 2, 8]] + -0.000263907165716330272 # B[1547, [46, 7, 3, 8], [53, 8, 4, 8]] + -5.74521512815137289e-05 # B[1548, [46, 7, 3, 8], [54, 8, 6, 8]] + -0.00030234445629373323 # B[1549, [46, 7, 3, 8], [55, 8, 8, 8]] + -0.000842080339294604824 # B[1550, [47, 7, 4, 7], [47, 7, 4, 7]] + -1.8677234631915389e-05 # B[1551, [47, 7, 4, 7], [48, 7, 5, 8]] + 0.000150434033167294937 # B[1552, [47, 7, 4, 7], [49, 7, 6, 7]] + 0.000201922161197246736 # B[1553, [47, 7, 4, 7], [50, 7, 7, 8]] + 5.63689077359152968e-05 # B[1554, [47, 7, 4, 7], [51, 8, 0, 8]] + 0.000490229079971716761 # B[1555, [47, 7, 4, 7], [52, 8, 2, 8]] + -0.00019335269881828529 # B[1556, [47, 7, 4, 7], [53, 8, 4, 8]] + -0.000118664083374402096 # B[1557, [47, 7, 4, 7], [54, 8, 6, 8]] + -0.000397263359111398734 # B[1558, [47, 7, 4, 7], [55, 8, 8, 8]] + -0.000724261739409587726 # B[1559, [48, 7, 5, 8], [48, 7, 5, 8]] + 0.000186853474209224685 # B[1560, [48, 7, 5, 8], [49, 7, 6, 7]] + -0.000533321040010020266 # B[1561, [48, 7, 5, 8], [50, 7, 7, 8]] + 9.95102706208284005e-08 # B[1562, [48, 7, 5, 8], [51, 8, 0, 8]] + -0.00093755398196557671 # B[1563, [48, 7, 5, 8], [52, 8, 2, 8]] + 0.000483236780374178207 # B[1564, [48, 7, 5, 8], [53, 8, 4, 8]] + -5.03524206302112531e-05 # B[1565, [48, 7, 5, 8], [54, 8, 6, 8]] + -0.000586245052440398373 # B[1566, [48, 7, 5, 8], [55, 8, 8, 8]] + -0.000207118017941997773 # B[1567, [49, 7, 6, 7], [49, 7, 6, 7]] + -9.40116364012005823e-05 # B[1568, [49, 7, 6, 7], [50, 7, 7, 8]] + 0.000124266884770383307 # B[1569, [49, 7, 6, 7], [51, 8, 0, 8]] + 0.00118479186165786239 # B[1570, [49, 7, 6, 7], [52, 8, 2, 8]] + -0.000129238345120056067 # B[1571, [49, 7, 6, 7], [53, 8, 4, 8]] + -0.000383875224777865259 # B[1572, [49, 7, 6, 7], [54, 8, 6, 8]] + -0.000457194559055141767 # B[1573, [49, 7, 6, 7], [55, 8, 8, 8]] + -0.000450510261664234871 # B[1574, [50, 7, 7, 8], [50, 7, 7, 8]] + 7.52704593073999506e-05 # B[1575, [50, 7, 7, 8], [51, 8, 0, 8]] + -0.00128732840082427732 # B[1576, [50, 7, 7, 8], [52, 8, 2, 8]] + 0.000293225651298797269 # B[1577, [50, 7, 7, 8], [53, 8, 4, 8]] + -0.000306521733645761033 # B[1578, [50, 7, 7, 8], [54, 8, 6, 8]] + -0.000370268243746852549 # B[1579, [50, 7, 7, 8], [55, 8, 8, 8]] + -4.00747887657759705e-06 # B[1580, [51, 8, 0, 8], [51, 8, 0, 8]] + -0.000179079356204300821 # B[1581, [51, 8, 0, 8], [52, 8, 2, 8]] + -6.37205046857824975e-06 # B[1582, [51, 8, 0, 8], [53, 8, 4, 8]] + 5.20087282658288075e-05 # B[1583, [51, 8, 0, 8], [54, 8, 6, 8]] + 6.68015373273544988e-05 # B[1584, [51, 8, 0, 8], [55, 8, 8, 8]] + 0.00160592146390294661 # B[1585, [52, 8, 2, 8], [52, 8, 2, 8]] + 0.000454049229948232103 # B[1586, [52, 8, 2, 8], [53, 8, 4, 8]] + 0.00110675066334388339 # B[1587, [52, 8, 2, 8], [54, 8, 6, 8]] + -0.000191060465051852771 # B[1588, [52, 8, 2, 8], [55, 8, 8, 8]] + -0.000131765455753670314 # B[1589, [53, 8, 4, 8], [53, 8, 4, 8]] + -7.05704764431217685e-05 # B[1590, [53, 8, 4, 8], [54, 8, 6, 8]] + -1.82263105369812051e-05 # B[1591, [53, 8, 4, 8], [55, 8, 8, 8]] + -0.00032731873727259329 # B[1592, [54, 8, 6, 8], [54, 8, 6, 8]] + -0.000198178389384386089 # B[1593, [54, 8, 6, 8], [55, 8, 8, 8]] + -0.000136309758672861769 # B[1594, [55, 8, 8, 8], [55, 8, 8, 8]] + +# End of potential diff --git a/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam b/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam new file mode 100644 index 0000000000..26dddf627d --- /dev/null +++ b/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam @@ -0,0 +1,10 @@ + + # required + rcutfac 2.7 + twojmax 8 + + # optional + rfac0 0.99363 + rmin0 0.0 + bzeroflag 0 + quadraticflag 1 diff --git a/examples/snap/in.C_SNAP b/examples/snap/in.C_SNAP new file mode 100644 index 0000000000..b504881e90 --- /dev/null +++ b/examples/snap/in.C_SNAP @@ -0,0 +1,35 @@ +#Carbon SNAP example: 216 atom diamond unit cell simulated NVT at ~1,000GPa and 5,000K + + +units metal +atom_style atomic +boundary p p p + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# User-defined variables # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# + +variable alat equal "2.845" +variable nx equal "3" +variable ny equal "3" +variable nz equal "3" +variable tstep equal "0.000500" + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Crystal orientation and MD box creation # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +lattice diamond ${alat} +region Bbox block 0 ${nx} 0 ${ny} 0 ${nz} +create_box 1 Bbox +create_atoms 1 region Bbox basis 1 1 +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Interatomic potential parameters # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +include pot_C.mod +mass * 12.01 + +fix NVE all nve +fix NVT all langevin 5000. 5000. 0.1 3216548 +thermo 100 +thermo_style custom step temp ke pe etotal pxx pyy pzz xlo xhi ylo yhi zlo zhi cpu +run 2000 diff --git a/examples/snap/log.23May23.C_SNAP b/examples/snap/log.23May23.C_SNAP new file mode 100644 index 0000000000..5b8b9f0066 --- /dev/null +++ b/examples/snap/log.23May23.C_SNAP @@ -0,0 +1,136 @@ +LAMMPS (3 Aug 2022) + +units metal +atom_style atomic +boundary p p p + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# User-defined variables # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# + +variable alat equal "2.845" +variable nx equal "3" +variable ny equal "3" +variable nz equal "3" +variable tstep equal "0.000500" + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Crystal orientation and MD box creation # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +lattice diamond ${alat} +lattice diamond 2.845 +Lattice spacing in x,y,z = 2.845 2.845 2.845 +region Bbox block 0 ${nx} 0 ${ny} 0 ${nz} +region Bbox block 0 3 0 ${ny} 0 ${nz} +region Bbox block 0 3 0 3 0 ${nz} +region Bbox block 0 3 0 3 0 3 +create_box 1 Bbox +Created orthogonal box = (0 0 0) to (8.535 8.535 8.535) + 1 by 1 by 1 MPI processor grid +create_atoms 1 region Bbox basis 1 1 +Created 216 atoms + using lattice units in orthogonal box = (0 0 0) to (8.535 8.535 8.535) + create_atoms CPU = 0.000 seconds +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Interatomic potential parameters # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +include pot_C.mod +# Definition of SNAP+ZBL potential. +variable zblcutinner equal 0.1 #0.38 +variable zblcutouter equal 0.2 +variable zblz equal 10 #500 + +# Specify hybrid with SNAP, ZBL, and long-range C_SNAP_2021.10.15.quadratic.ulomb + +pair_style hybrid/overlay zbl ${zblcutinner} ${zblcutouter} snap +pair_style hybrid/overlay zbl 0.1 ${zblcutouter} snap +pair_style hybrid/overlay zbl 0.1 0.2 snap +pair_coeff 1 1 zbl ${zblz} ${zblz} +pair_coeff 1 1 zbl 10 ${zblz} +pair_coeff 1 1 zbl 10 10 +pair_coeff * * snap C_SNAP_2021.10.15.quadratic.snapcoeff C_SNAP_2021.10.15.quadratic.snapparam C +SNAP Element = C, Radius 0.5, Weight 1 +SNAP keyword rcutfac 2.7 +SNAP keyword twojmax 8 +SNAP keyword rfac0 0.99363 +SNAP keyword rmin0 0.0 +SNAP keyword bzeroflag 0 +SNAP keyword quadraticflag 1 + +mass * 12.01 + +fix NVE all nve +fix NVT all langevin 5000. 5000. 0.1 3216548 +thermo 100 +thermo_style custom step temp ke pe etotal pxx pyy pzz xlo xhi ylo yhi zlo zhi cpu +run 2000 +Neighbor list info ... + update: every = 1 steps, delay = 10 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 4.7 + ghost atom cutoff = 4.7 + binsize = 2.35, bins = 4 4 4 + 2 neighbor lists, perpetual/occasional/extra = 2 0 0 + (1) pair zbl, perpetual, half/full trim from (2) + attributes: half, newton on, cut 2.2 + pair build: halffull/newton/trim + stencil: none + bin: none + (2) pair snap, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 4.835 | 4.835 | 4.835 Mbytes + Step Temp KinEng PotEng TotEng Pxx Pyy Pzz Xlo Xhi Ylo Yhi Zlo Zhi CPU + 0 0 0 -846.66062 -846.66062 9852302.8 9852302.8 9852302.8 0 8.535 0 8.535 0 8.535 0 + 100 2994.9404 83.232183 -760.46784 -677.23566 10153319 10162613 10089556 0 8.535 0 8.535 0 8.535 8.5637966 + 200 4138.1573 115.00324 -718.21196 -603.20871 10328838 10278023 10147395 0 8.535 0 8.535 0 8.535 17.231147 + 300 4231.1241 117.58688 -703.12914 -585.54226 10229126 10278574 10244536 0 8.535 0 8.535 0 8.535 25.883724 + 400 4902.5771 136.24718 -693.59525 -557.34807 10258619 10309837 10270759 0 8.535 0 8.535 0 8.535 34.454573 + 500 5231.01 145.37464 -703.59176 -558.21712 10380296 10313494 10261486 0 8.535 0 8.535 0 8.535 43.03519 + 600 4962.4828 137.91202 -701.69725 -563.78524 10405175 10240153 10223683 0 8.535 0 8.535 0 8.535 51.617418 + 700 5158.8211 143.36844 -696.3068 -552.93836 10224265 10353872 10237323 0 8.535 0 8.535 0 8.535 60.216592 + 800 5566.4588 154.69707 -691.80266 -537.10558 10345764 10333822 10328272 0 8.535 0 8.535 0 8.535 68.836406 + 900 4763.5973 132.38481 -699.56143 -567.17663 10265807 10264115 10292086 0 8.535 0 8.535 0 8.535 77.557491 + 1000 5374.1522 149.35269 -707.77182 -558.41912 10353688 10245807 10289801 0 8.535 0 8.535 0 8.535 86.134981 + 1100 4729.9838 131.45065 -687.84753 -556.39687 10236271 10295262 10280036 0 8.535 0 8.535 0 8.535 94.80143 + 1200 5524.4648 153.53002 -688.33164 -534.80162 10376941 10311014 10272151 0 8.535 0 8.535 0 8.535 103.66054 + 1300 5424.1134 150.74116 -710.48851 -559.74735 10269935 10381675 10208553 0 8.535 0 8.535 0 8.535 112.29193 + 1400 5082.4497 141.24601 -703.51889 -562.27288 10289096 10270701 10360960 0 8.535 0 8.535 0 8.535 120.98393 + 1500 4782.7699 132.91763 -709.97393 -577.0563 10264631 10200017 10341446 0 8.535 0 8.535 0 8.535 129.56238 + 1600 5080.7401 141.1985 -693.90867 -552.71017 10263936 10300165 10411302 0 8.535 0 8.535 0 8.535 138.13256 + 1700 5192.8466 144.31404 -698.99608 -554.68204 10309414 10291531 10256424 0 8.535 0 8.535 0 8.535 146.75162 + 1800 5105.1385 141.87655 -702.43759 -560.56104 10325438 10245469 10330602 0 8.535 0 8.535 0 8.535 155.63637 + 1900 5015.6808 139.39044 -706.73213 -567.34169 10345833 10310789 10319358 0 8.535 0 8.535 0 8.535 164.26556 + 2000 4894.0288 136.00962 -697.34077 -561.33115 10259839 10328896 10230941 0 8.535 0 8.535 0 8.535 172.92786 +Loop time of 172.928 on 1 procs for 2000 steps with 216 atoms + +Performance: 0.999 ns/day, 24.018 hours/ns, 11.566 timesteps/s +99.8% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 172.88 | 172.88 | 172.88 | 0.0 | 99.97 +Neigh | 0.0050877 | 0.0050877 | 0.0050877 | 0.0 | 0.00 +Comm | 0.013326 | 0.013326 | 0.013326 | 0.0 | 0.01 +Output | 0.001194 | 0.001194 | 0.001194 | 0.0 | 0.00 +Modify | 0.022687 | 0.022687 | 0.022687 | 0.0 | 0.01 +Other | | 0.006874 | | | 0.00 + +Nlocal: 216 ave 216 max 216 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1806 ave 1806 max 1806 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 1782 ave 1782 max 1782 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 32872 ave 32872 max 32872 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 32872 +Ave neighs/atom = 152.18519 +Neighbor list builds = 5 +Dangerous builds = 0 + +Total wall time: 0:02:53 diff --git a/examples/snap/pot_C.mod b/examples/snap/pot_C.mod new file mode 100644 index 0000000000..3851fb598d --- /dev/null +++ b/examples/snap/pot_C.mod @@ -0,0 +1,12 @@ +# Definition of SNAP+ZBL potential. +variable zblcutinner equal 0.1 +variable zblcutouter equal 0.2 +variable zblz equal 10 + +# Specify hybrid with SNAP, ZBL, and long-range C_SNAP_2021.10.15.quadratic.ulomb + +pair_style hybrid/overlay & +zbl ${zblcutinner} ${zblcutouter} & +snap +pair_coeff 1 1 zbl ${zblz} ${zblz} +pair_coeff * * snap C_SNAP_2021.10.15.quadratic.snapcoeff C_SNAP_2021.10.15.quadratic.snapparam C diff --git a/potentials/C_SNAP_2021.10.15.quadratic.snapcoeff b/potentials/C_SNAP_2021.10.15.quadratic.snapcoeff new file mode 100644 index 0000000000..4db83060f7 --- /dev/null +++ b/potentials/C_SNAP_2021.10.15.quadratic.snapcoeff @@ -0,0 +1,1602 @@ +#Carbon SNAP generated on 2021-10-15 08:21:38.396384 +#UNITS: metal CONTRIBUTOR: Ivan Oleynik CITATION: Jonathan T. Willman, Kien Nguyen-Cong, Ashley S. Williams, Anatoly B. Belonoshko, Stan G. Moore, Aidan P. Thompson, Mitchell A. Wood, and Ivan I. Oleynik, "Machine learning interatomic potential for simulations of carbon at extreme conditions" Phys. Rev. B 106, L180101 (2022) +1 1596 +C 0.5 1.0 + -2.7758927591660334 # B[0] + 0.00859216942217639126 # B[1, 0, 0, 0] + 0.16638458601459194 # B[2, 1, 0, 1] + 0.22261822339506554 # B[3, 1, 1, 2] + 0.257355166247009937 # B[4, 2, 0, 2] + 0.802105904460230779 # B[5, 2, 1, 3] + 0.227216469467176801 # B[6, 2, 2, 2] + 0.494646284119575508 # B[7, 2, 2, 4] + 0.276718638025069574 # B[8, 3, 0, 3] + 1.09101782892605392 # B[9, 3, 1, 4] + 0.775283725099378151 # B[10, 3, 2, 3] + -0.232869556477520168 # B[11, 3, 2, 5] + 0.188466708736270222 # B[12, 3, 3, 4] + -0.213463540195325957 # B[13, 3, 3, 6] + 0.285049005401720568 # B[14, 4, 0, 4] + -0.248039138369940321 # B[15, 4, 1, 5] + -0.017694405190132434 # B[16, 4, 2, 4] + -0.513770238875468355 # B[17, 4, 2, 6] + -0.603368424950793791 # B[18, 4, 3, 5] + -0.4245149972360448 # B[19, 4, 3, 7] + -0.149612637312833391 # B[20, 4, 4, 4] + -0.153415086019898006 # B[21, 4, 4, 6] + -0.14513624400298164 # B[22, 4, 4, 8] + -0.0460661393681677661 # B[23, 5, 0, 5] + -0.0512559726916635844 # B[24, 5, 1, 6] + -0.125285455697324882 # B[25, 5, 2, 5] + -0.297464016341802473 # B[26, 5, 2, 7] + -0.219930176940332595 # B[27, 5, 3, 6] + -0.195418601625407001 # B[28, 5, 3, 8] + -0.236454956825408069 # B[29, 5, 4, 5] + -0.247483318285177556 # B[30, 5, 4, 7] + 0.108404148378543994 # B[31, 5, 5, 6] + 0.102786344334006338 # B[32, 5, 5, 8] + -0.0174963987262215619 # B[33, 6, 0, 6] + -0.347663919737827065 # B[34, 6, 1, 7] + -0.308777238806140442 # B[35, 6, 2, 6] + -0.30366671620990171 # B[36, 6, 2, 8] + -0.190992135157848048 # B[37, 6, 3, 7] + -0.212717125362634818 # B[38, 6, 4, 6] + -0.127682310305149815 # B[39, 6, 4, 8] + 0.128955786755968027 # B[40, 6, 5, 7] + 0.108121871413745185 # B[41, 6, 6, 6] + 0.0951564970231452284 # B[42, 6, 6, 8] + -0.0443430969083889667 # B[43, 7, 0, 7] + 0.0394012265947801602 # B[44, 7, 1, 8] + 0.0238287662182333909 # B[45, 7, 2, 7] + -0.0703216614205220136 # B[46, 7, 3, 8] + -0.0229748587995626564 # B[47, 7, 4, 7] + 0.461615758896215367 # B[48, 7, 5, 8] + 0.032037855993324961 # B[49, 7, 6, 7] + 0.105399776101016598 # B[50, 7, 7, 8] + -0.0452778356788145764 # B[51, 8, 0, 8] + -0.0400452652333231421 # B[52, 8, 2, 8] + -0.152415456089667084 # B[53, 8, 4, 8] + 0.0303383368396002995 # B[54, 8, 6, 8] + 0.0660845112300222914 # B[55, 8, 8, 8] + 5.0022584003536763e-06 # B[55, [1, 0, 0, 0], [1, 0, 0, 0]] + 7.12434860521689133e-05 # B[56, [1, 0, 0, 0], [2, 1, 0, 1]] + 0.00410559459459784552 # B[57, [1, 0, 0, 0], [3, 1, 1, 2]] + -0.000152151102822628559 # B[58, [1, 0, 0, 0], [4, 2, 0, 2]] + -0.00104851962847402839 # B[59, [1, 0, 0, 0], [5, 2, 1, 3]] + 0.00174544590749468355 # B[60, [1, 0, 0, 0], [6, 2, 2, 2]] + -0.00039686396723943862 # B[61, [1, 0, 0, 0], [7, 2, 2, 4]] + 0.000344474173032960351 # B[62, [1, 0, 0, 0], [8, 3, 0, 3]] + 5.77832175303926235e-05 # B[63, [1, 0, 0, 0], [9, 3, 1, 4]] + 0.00124014860085090543 # B[64, [1, 0, 0, 0], [10, 3, 2, 3]] + 1.92520730655986946e-05 # B[65, [1, 0, 0, 0], [11, 3, 2, 5]] + -0.000659022869027497959 # B[66, [1, 0, 0, 0], [12, 3, 3, 4]] + -0.000296998157394604001 # B[67, [1, 0, 0, 0], [13, 3, 3, 6]] + 2.13348987737616014e-06 # B[68, [1, 0, 0, 0], [14, 4, 0, 4]] + -0.000377679899824956422 # B[69, [1, 0, 0, 0], [15, 4, 1, 5]] + 0.00045743496488695988 # B[70, [1, 0, 0, 0], [16, 4, 2, 4]] + -0.00047978616167941926 # B[71, [1, 0, 0, 0], [17, 4, 2, 6]] + -0.000346601408372410741 # B[72, [1, 0, 0, 0], [18, 4, 3, 5]] + -0.000216752459512900564 # B[73, [1, 0, 0, 0], [19, 4, 3, 7]] + -0.000153945954064437646 # B[74, [1, 0, 0, 0], [20, 4, 4, 4]] + 0.00029484781857681483 # B[75, [1, 0, 0, 0], [21, 4, 4, 6]] + 1.59236973873017051e-05 # B[76, [1, 0, 0, 0], [22, 4, 4, 8]] + -2.35544935613951623e-05 # B[77, [1, 0, 0, 0], [23, 5, 0, 5]] + 0.000492019807872501325 # B[78, [1, 0, 0, 0], [24, 5, 1, 6]] + 0.000376700986017126233 # B[79, [1, 0, 0, 0], [25, 5, 2, 5]] + -0.000185900021989794662 # B[80, [1, 0, 0, 0], [26, 5, 2, 7]] + 0.000219939447169378507 # B[81, [1, 0, 0, 0], [27, 5, 3, 6]] + -0.000192198129806066265 # B[82, [1, 0, 0, 0], [28, 5, 3, 8]] + 0.000175514531344928004 # B[83, [1, 0, 0, 0], [29, 5, 4, 5]] + 0.000261949015135925535 # B[84, [1, 0, 0, 0], [30, 5, 4, 7]] + 0.00021011408484750832 # B[85, [1, 0, 0, 0], [31, 5, 5, 6]] + -7.47807464450689352e-05 # B[86, [1, 0, 0, 0], [32, 5, 5, 8]] + -1.36809205491805752e-05 # B[87, [1, 0, 0, 0], [33, 6, 0, 6]] + 0.000493576806965066728 # B[88, [1, 0, 0, 0], [34, 6, 1, 7]] + 0.000216301405824667614 # B[89, [1, 0, 0, 0], [35, 6, 2, 6]] + -0.000364540437645548276 # B[90, [1, 0, 0, 0], [36, 6, 2, 8]] + -0.000251411532179113273 # B[91, [1, 0, 0, 0], [37, 6, 3, 7]] + 3.19331690196988927e-05 # B[92, [1, 0, 0, 0], [38, 6, 4, 6]] + -1.56092571080845843e-05 # B[93, [1, 0, 0, 0], [39, 6, 4, 8]] + 2.4859429830464963e-05 # B[94, [1, 0, 0, 0], [40, 6, 5, 7]] + -5.06306418207175257e-05 # B[95, [1, 0, 0, 0], [41, 6, 6, 6]] + -9.75742047871729079e-05 # B[96, [1, 0, 0, 0], [42, 6, 6, 8]] + -4.07774117821002591e-05 # B[97, [1, 0, 0, 0], [43, 7, 0, 7]] + 0.000169705539551909257 # B[98, [1, 0, 0, 0], [44, 7, 1, 8]] + 0.000261792097012429614 # B[99, [1, 0, 0, 0], [45, 7, 2, 7]] + 0.000235813389494382575 # B[100, [1, 0, 0, 0], [46, 7, 3, 8]] + 3.69194385055615637e-05 # B[101, [1, 0, 0, 0], [47, 7, 4, 7]] + 0.000101832840349036502 # B[102, [1, 0, 0, 0], [48, 7, 5, 8]] + 1.87768621704026417e-05 # B[103, [1, 0, 0, 0], [49, 7, 6, 7]] + 6.90123641682582889e-05 # B[104, [1, 0, 0, 0], [50, 7, 7, 8]] + 3.82281861928956967e-05 # B[105, [1, 0, 0, 0], [51, 8, 0, 8]] + 0.00044905358698343889 # B[106, [1, 0, 0, 0], [52, 8, 2, 8]] + 3.83170337754923374e-05 # B[107, [1, 0, 0, 0], [53, 8, 4, 8]] + -4.53472261485315942e-05 # B[108, [1, 0, 0, 0], [54, 8, 6, 8]] + -0.000105793544360549552 # B[109, [1, 0, 0, 0], [55, 8, 8, 8]] + -0.00542851209933992596 # B[110, [2, 1, 0, 1], [2, 1, 0, 1]] + -0.00800035055604917701 # B[111, [2, 1, 0, 1], [3, 1, 1, 2]] + 0.000279580761847972054 # B[112, [2, 1, 0, 1], [4, 2, 0, 2]] + -0.0132643544617690821 # B[113, [2, 1, 0, 1], [5, 2, 1, 3]] + -0.00300637860380324968 # B[114, [2, 1, 0, 1], [6, 2, 2, 2]] + 0.00343216933390476549 # B[115, [2, 1, 0, 1], [7, 2, 2, 4]] + 6.39026040622058672e-05 # B[116, [2, 1, 0, 1], [8, 3, 0, 3]] + -0.0124005148347727506 # B[117, [2, 1, 0, 1], [9, 3, 1, 4]] + -0.0036690465725984691 # B[118, [2, 1, 0, 1], [10, 3, 2, 3]] + -0.0066468850826254932 # B[119, [2, 1, 0, 1], [11, 3, 2, 5]] + -0.00518212543330048934 # B[120, [2, 1, 0, 1], [12, 3, 3, 4]] + -0.00269613907034030407 # B[121, [2, 1, 0, 1], [13, 3, 3, 6]] + -0.000330193583102013615 # B[122, [2, 1, 0, 1], [14, 4, 0, 4]] + -0.000429062486184235686 # B[123, [2, 1, 0, 1], [15, 4, 1, 5]] + -0.000991704717453613382 # B[124, [2, 1, 0, 1], [16, 4, 2, 4]] + 0.00152944521177345071 # B[125, [2, 1, 0, 1], [17, 4, 2, 6]] + -0.00660856033628089406 # B[126, [2, 1, 0, 1], [18, 4, 3, 5]] + 0.00146758746394204951 # B[127, [2, 1, 0, 1], [19, 4, 3, 7]] + -0.00161093753941019967 # B[128, [2, 1, 0, 1], [20, 4, 4, 4]] + -0.00101484284665418574 # B[129, [2, 1, 0, 1], [21, 4, 4, 6]] + 0.00150269420364470413 # B[130, [2, 1, 0, 1], [22, 4, 4, 8]] + -0.000251279508914979688 # B[131, [2, 1, 0, 1], [23, 5, 0, 5]] + 0.00427791921512100763 # B[132, [2, 1, 0, 1], [24, 5, 1, 6]] + -0.00312327633171666707 # B[133, [2, 1, 0, 1], [25, 5, 2, 5]] + 0.00145518956483171066 # B[134, [2, 1, 0, 1], [26, 5, 2, 7]] + -0.00296392629706135422 # B[135, [2, 1, 0, 1], [27, 5, 3, 6]] + 0.00106990236696331148 # B[136, [2, 1, 0, 1], [28, 5, 3, 8]] + 0.000140740776400729824 # B[137, [2, 1, 0, 1], [29, 5, 4, 5]] + -0.000704484148092703912 # B[138, [2, 1, 0, 1], [30, 5, 4, 7]] + 0.000555926138942124939 # B[139, [2, 1, 0, 1], [31, 5, 5, 6]] + 0.000749361142656781065 # B[140, [2, 1, 0, 1], [32, 5, 5, 8]] + -0.000275563231062828096 # B[141, [2, 1, 0, 1], [33, 6, 0, 6]] + 0.00404287546990938183 # B[142, [2, 1, 0, 1], [34, 6, 1, 7]] + -0.00329083016295819491 # B[143, [2, 1, 0, 1], [35, 6, 2, 6]] + 0.00374648670440783874 # B[144, [2, 1, 0, 1], [36, 6, 2, 8]] + -0.000931584323738718183 # B[145, [2, 1, 0, 1], [37, 6, 3, 7]] + 0.001545987588966576 # B[146, [2, 1, 0, 1], [38, 6, 4, 6]] + 0.000136630337825366203 # B[147, [2, 1, 0, 1], [39, 6, 4, 8]] + -0.000338191518470186761 # B[148, [2, 1, 0, 1], [40, 6, 5, 7]] + 0.000383732900037425575 # B[149, [2, 1, 0, 1], [41, 6, 6, 6]] + 0.000891911333988446714 # B[150, [2, 1, 0, 1], [42, 6, 6, 8]] + 0.000372325777048820861 # B[151, [2, 1, 0, 1], [43, 7, 0, 7]] + 0.00203975899324063559 # B[152, [2, 1, 0, 1], [44, 7, 1, 8]] + -0.00366168906366426058 # B[153, [2, 1, 0, 1], [45, 7, 2, 7]] + -0.00217927110231279971 # B[154, [2, 1, 0, 1], [46, 7, 3, 8]] + -0.000355180731966526532 # B[155, [2, 1, 0, 1], [47, 7, 4, 7]] + -0.00190295940654904624 # B[156, [2, 1, 0, 1], [48, 7, 5, 8]] + -0.00045640385432905474 # B[157, [2, 1, 0, 1], [49, 7, 6, 7]] + -0.00123273230096131864 # B[158, [2, 1, 0, 1], [50, 7, 7, 8]] + 2.61749541232737803e-06 # B[159, [2, 1, 0, 1], [51, 8, 0, 8]] + -0.00188736987570012403 # B[160, [2, 1, 0, 1], [52, 8, 2, 8]] + 0.000127235145614493401 # B[161, [2, 1, 0, 1], [53, 8, 4, 8]] + -0.000446185446234578786 # B[162, [2, 1, 0, 1], [54, 8, 6, 8]] + 3.06626149019382718e-05 # B[163, [2, 1, 0, 1], [55, 8, 8, 8]] + 0.00500803145405033512 # B[164, [3, 1, 1, 2], [3, 1, 1, 2]] + 0.0136537265129433767 # B[165, [3, 1, 1, 2], [4, 2, 0, 2]] + 0.00586793418015095231 # B[166, [3, 1, 1, 2], [5, 2, 1, 3]] + 0.0108897828563872673 # B[167, [3, 1, 1, 2], [6, 2, 2, 2]] + 0.000782326392446437181 # B[168, [3, 1, 1, 2], [7, 2, 2, 4]] + -0.00196905235294965193 # B[169, [3, 1, 1, 2], [8, 3, 0, 3]] + -0.00575620599927615263 # B[170, [3, 1, 1, 2], [9, 3, 1, 4]] + -0.0395084171352078836 # B[171, [3, 1, 1, 2], [10, 3, 2, 3]] + -0.0402914809330097226 # B[172, [3, 1, 1, 2], [11, 3, 2, 5]] + -0.031380925125560552 # B[173, [3, 1, 1, 2], [12, 3, 3, 4]] + 0.0074098991236085333 # B[174, [3, 1, 1, 2], [13, 3, 3, 6]] + -0.00144234945688183152 # B[175, [3, 1, 1, 2], [14, 4, 0, 4]] + -0.00715563010950572616 # B[176, [3, 1, 1, 2], [15, 4, 1, 5]] + -0.0068004389765142035 # B[177, [3, 1, 1, 2], [16, 4, 2, 4]] + -0.0397838555572563451 # B[178, [3, 1, 1, 2], [17, 4, 2, 6]] + 0.00335672059516798228 # B[179, [3, 1, 1, 2], [18, 4, 3, 5]] + 0.0148934683418572647 # B[180, [3, 1, 1, 2], [19, 4, 3, 7]] + -0.000967980016249102011 # B[181, [3, 1, 1, 2], [20, 4, 4, 4]] + 0.00772576295059950596 # B[182, [3, 1, 1, 2], [21, 4, 4, 6]] + -0.00450662666899595381 # B[183, [3, 1, 1, 2], [22, 4, 4, 8]] + -0.00395807515027411967 # B[184, [3, 1, 1, 2], [23, 5, 0, 5]] + 0.010414612350238486 # B[185, [3, 1, 1, 2], [24, 5, 1, 6]] + -0.00513372683983254804 # B[186, [3, 1, 1, 2], [25, 5, 2, 5]] + -0.0265398819124704963 # B[187, [3, 1, 1, 2], [26, 5, 2, 7]] + 0.00742434172938952544 # B[188, [3, 1, 1, 2], [27, 5, 3, 6]] + -0.00256386423704287481 # B[189, [3, 1, 1, 2], [28, 5, 3, 8]] + 0.00841179553194743718 # B[190, [3, 1, 1, 2], [29, 5, 4, 5]] + 0.00668617729586690451 # B[191, [3, 1, 1, 2], [30, 5, 4, 7]] + 0.000484464094046739568 # B[192, [3, 1, 1, 2], [31, 5, 5, 6]] + 0.00458460314168420216 # B[193, [3, 1, 1, 2], [32, 5, 5, 8]] + -0.00235318401641824212 # B[194, [3, 1, 1, 2], [33, 6, 0, 6]] + -0.000804392064641467762 # B[195, [3, 1, 1, 2], [34, 6, 1, 7]] + -0.000974349018272668323 # B[196, [3, 1, 1, 2], [35, 6, 2, 6]] + -0.0186467861443154748 # B[197, [3, 1, 1, 2], [36, 6, 2, 8]] + 0.0149394908128317495 # B[198, [3, 1, 1, 2], [37, 6, 3, 7]] + -0.001417773975968062 # B[199, [3, 1, 1, 2], [38, 6, 4, 6]] + 0.00708801668305296916 # B[200, [3, 1, 1, 2], [39, 6, 4, 8]] + 0.00422029817457212405 # B[201, [3, 1, 1, 2], [40, 6, 5, 7]] + 0.00110117813016081525 # B[202, [3, 1, 1, 2], [41, 6, 6, 6]] + -0.00187490884044745794 # B[203, [3, 1, 1, 2], [42, 6, 6, 8]] + -0.00530063898164105998 # B[204, [3, 1, 1, 2], [43, 7, 0, 7]] + 0.0156639815207892212 # B[205, [3, 1, 1, 2], [44, 7, 1, 8]] + 0.0118519420103458811 # B[206, [3, 1, 1, 2], [45, 7, 2, 7]] + 0.00375057568532275679 # B[207, [3, 1, 1, 2], [46, 7, 3, 8]] + 0.00757584350406629962 # B[208, [3, 1, 1, 2], [47, 7, 4, 7]] + 0.0106601777099339986 # B[209, [3, 1, 1, 2], [48, 7, 5, 8]] + -0.0041075690062942552 # B[210, [3, 1, 1, 2], [49, 7, 6, 7]] + 0.00248707997936048041 # B[211, [3, 1, 1, 2], [50, 7, 7, 8]] + -0.0025390217113529746 # B[212, [3, 1, 1, 2], [51, 8, 0, 8]] + 0.00498354453902482165 # B[213, [3, 1, 1, 2], [52, 8, 2, 8]] + 0.00383782774054214912 # B[214, [3, 1, 1, 2], [53, 8, 4, 8]] + 0.00318870204625110783 # B[215, [3, 1, 1, 2], [54, 8, 6, 8]] + -0.00078409267383599678 # B[216, [3, 1, 1, 2], [55, 8, 8, 8]] + 0.00411479420703600093 # B[217, [4, 2, 0, 2], [4, 2, 0, 2]] + -0.00352482696278418658 # B[218, [4, 2, 0, 2], [5, 2, 1, 3]] + 0.00293296373222708129 # B[219, [4, 2, 0, 2], [6, 2, 2, 2]] + -0.00169108240942662173 # B[220, [4, 2, 0, 2], [7, 2, 2, 4]] + -0.00166875839344953099 # B[221, [4, 2, 0, 2], [8, 3, 0, 3]] + -0.00303743189373234653 # B[222, [4, 2, 0, 2], [9, 3, 1, 4]] + -0.00360352002032471395 # B[223, [4, 2, 0, 2], [10, 3, 2, 3]] + -0.00844475258400314774 # B[224, [4, 2, 0, 2], [11, 3, 2, 5]] + -0.00267861760564082688 # B[225, [4, 2, 0, 2], [12, 3, 3, 4]] + 0.00249373694942188646 # B[226, [4, 2, 0, 2], [13, 3, 3, 6]] + 0.00129518789575956 # B[227, [4, 2, 0, 2], [14, 4, 0, 4]] + -0.000616706097657935626 # B[228, [4, 2, 0, 2], [15, 4, 1, 5]] + -0.00374793183827557257 # B[229, [4, 2, 0, 2], [16, 4, 2, 4]] + -0.00725453590077526286 # B[230, [4, 2, 0, 2], [17, 4, 2, 6]] + -0.00328165463874066426 # B[231, [4, 2, 0, 2], [18, 4, 3, 5]] + -0.00387910875571249565 # B[232, [4, 2, 0, 2], [19, 4, 3, 7]] + -0.000691443248665482221 # B[233, [4, 2, 0, 2], [20, 4, 4, 4]] + -0.00364575524119575139 # B[234, [4, 2, 0, 2], [21, 4, 4, 6]] + 0.000579213613942424974 # B[235, [4, 2, 0, 2], [22, 4, 4, 8]] + 0.000382530088889220486 # B[236, [4, 2, 0, 2], [23, 5, 0, 5]] + 0.000700082663528700608 # B[237, [4, 2, 0, 2], [24, 5, 1, 6]] + -0.00303645662419470708 # B[238, [4, 2, 0, 2], [25, 5, 2, 5]] + -0.00412449214914962191 # B[239, [4, 2, 0, 2], [26, 5, 2, 7]] + -0.000863747946010486305 # B[240, [4, 2, 0, 2], [27, 5, 3, 6]] + 0.000597171151136822748 # B[241, [4, 2, 0, 2], [28, 5, 3, 8]] + -0.00290482182317059953 # B[242, [4, 2, 0, 2], [29, 5, 4, 5]] + -0.00218615594313117554 # B[243, [4, 2, 0, 2], [30, 5, 4, 7]] + 0.00120270898159113111 # B[244, [4, 2, 0, 2], [31, 5, 5, 6]] + -0.000439562436330729364 # B[245, [4, 2, 0, 2], [32, 5, 5, 8]] + -0.000155002689849706443 # B[246, [4, 2, 0, 2], [33, 6, 0, 6]] + -0.00203784613220199399 # B[247, [4, 2, 0, 2], [34, 6, 1, 7]] + -0.00251933129878168221 # B[248, [4, 2, 0, 2], [35, 6, 2, 6]] + -0.00227857345941180406 # B[249, [4, 2, 0, 2], [36, 6, 2, 8]] + 0.00307391827986236085 # B[250, [4, 2, 0, 2], [37, 6, 3, 7]] + -0.000435707916552085118 # B[251, [4, 2, 0, 2], [38, 6, 4, 6]] + -0.00141960729594133419 # B[252, [4, 2, 0, 2], [39, 6, 4, 8]] + -0.000275734648504752638 # B[253, [4, 2, 0, 2], [40, 6, 5, 7]] + 0.000703286595409794617 # B[254, [4, 2, 0, 2], [41, 6, 6, 6]] + -5.55751922647368824e-05 # B[255, [4, 2, 0, 2], [42, 6, 6, 8]] + -0.000401816924228297345 # B[256, [4, 2, 0, 2], [43, 7, 0, 7]] + -0.000554714661495172429 # B[257, [4, 2, 0, 2], [44, 7, 1, 8]] + 0.00088244559527147267 # B[258, [4, 2, 0, 2], [45, 7, 2, 7]] + 0.000429487284537406104 # B[259, [4, 2, 0, 2], [46, 7, 3, 8]] + 0.000160720016534536374 # B[260, [4, 2, 0, 2], [47, 7, 4, 7]] + -0.000116046064898544729 # B[261, [4, 2, 0, 2], [48, 7, 5, 8]] + 0.00077812424584384446 # B[262, [4, 2, 0, 2], [49, 7, 6, 7]] + 0.0014223009786123353 # B[263, [4, 2, 0, 2], [50, 7, 7, 8]] + 5.45987148103492526e-05 # B[264, [4, 2, 0, 2], [51, 8, 0, 8]] + -0.00229888217343966316 # B[265, [4, 2, 0, 2], [52, 8, 2, 8]] + -0.00144376280980788169 # B[266, [4, 2, 0, 2], [53, 8, 4, 8]] + 0.000240138800657541986 # B[267, [4, 2, 0, 2], [54, 8, 6, 8]] + -4.09764373741731969e-05 # B[268, [4, 2, 0, 2], [55, 8, 8, 8]] + 0.0453826120189535706 # B[269, [5, 2, 1, 3], [5, 2, 1, 3]] + 0.00337080799390409615 # B[270, [5, 2, 1, 3], [6, 2, 2, 2]] + 0.0339316309546992961 # B[271, [5, 2, 1, 3], [7, 2, 2, 4]] + 0.00483677443671226039 # B[272, [5, 2, 1, 3], [8, 3, 0, 3]] + 0.00174954019608989774 # B[273, [5, 2, 1, 3], [9, 3, 1, 4]] + 0.00420306320210527603 # B[274, [5, 2, 1, 3], [10, 3, 2, 3]] + -0.0179939258962366969 # B[275, [5, 2, 1, 3], [11, 3, 2, 5]] + -0.01997198698308544 # B[276, [5, 2, 1, 3], [12, 3, 3, 4]] + -0.0136471344704570501 # B[277, [5, 2, 1, 3], [13, 3, 3, 6]] + -0.00203572867299816902 # B[278, [5, 2, 1, 3], [14, 4, 0, 4]] + 0.0113893698593142377 # B[279, [5, 2, 1, 3], [15, 4, 1, 5]] + -0.00283495847488346529 # B[280, [5, 2, 1, 3], [16, 4, 2, 4]] + -0.0209899506178404249 # B[281, [5, 2, 1, 3], [17, 4, 2, 6]] + 0.00307893999573658839 # B[282, [5, 2, 1, 3], [18, 4, 3, 5]] + 0.00625880909518397067 # B[283, [5, 2, 1, 3], [19, 4, 3, 7]] + 0.00109461945578659598 # B[284, [5, 2, 1, 3], [20, 4, 4, 4]] + 0.00213752786441095705 # B[285, [5, 2, 1, 3], [21, 4, 4, 6]] + -0.00379774849562602296 # B[286, [5, 2, 1, 3], [22, 4, 4, 8]] + -0.0013508169978871552 # B[287, [5, 2, 1, 3], [23, 5, 0, 5]] + 0.00921730935112183292 # B[288, [5, 2, 1, 3], [24, 5, 1, 6]] + -0.0029427132897584694 # B[289, [5, 2, 1, 3], [25, 5, 2, 5]] + 0.0013497580216050211 # B[290, [5, 2, 1, 3], [26, 5, 2, 7]] + -0.0130362734683665445 # B[291, [5, 2, 1, 3], [27, 5, 3, 6]] + 0.000858369129835153365 # B[292, [5, 2, 1, 3], [28, 5, 3, 8]] + 0.0129288669947052737 # B[293, [5, 2, 1, 3], [29, 5, 4, 5]] + -0.00373719468786774291 # B[294, [5, 2, 1, 3], [30, 5, 4, 7]] + -0.00885030928727506203 # B[295, [5, 2, 1, 3], [31, 5, 5, 6]] + 0.00285083482960970039 # B[296, [5, 2, 1, 3], [32, 5, 5, 8]] + 0.00351819863542377799 # B[297, [5, 2, 1, 3], [33, 6, 0, 6]] + -0.00783526064954031404 # B[298, [5, 2, 1, 3], [34, 6, 1, 7]] + -0.00257460837433342703 # B[299, [5, 2, 1, 3], [35, 6, 2, 6]] + -0.00421680657028429638 # B[300, [5, 2, 1, 3], [36, 6, 2, 8]] + -0.00918753516813325399 # B[301, [5, 2, 1, 3], [37, 6, 3, 7]] + -0.00316878171100497871 # B[302, [5, 2, 1, 3], [38, 6, 4, 6]] + 0.000939804682159322766 # B[303, [5, 2, 1, 3], [39, 6, 4, 8]] + -0.00618801787900946643 # B[304, [5, 2, 1, 3], [40, 6, 5, 7]] + -0.00623545765495540482 # B[305, [5, 2, 1, 3], [41, 6, 6, 6]] + 0.00519552954815065936 # B[306, [5, 2, 1, 3], [42, 6, 6, 8]] + 0.0042213652228506697 # B[307, [5, 2, 1, 3], [43, 7, 0, 7]] + 0.0113944611011103838 # B[308, [5, 2, 1, 3], [44, 7, 1, 8]] + -0.00104197865751114085 # B[309, [5, 2, 1, 3], [45, 7, 2, 7]] + -0.0087446191630695079 # B[310, [5, 2, 1, 3], [46, 7, 3, 8]] + -0.00196327596558909696 # B[311, [5, 2, 1, 3], [47, 7, 4, 7]] + -0.00447686867642808298 # B[312, [5, 2, 1, 3], [48, 7, 5, 8]] + -0.00474469665733750351 # B[313, [5, 2, 1, 3], [49, 7, 6, 7]] + -0.0059004868061462868 # B[314, [5, 2, 1, 3], [50, 7, 7, 8]] + 2.22874717926892923e-05 # B[315, [5, 2, 1, 3], [51, 8, 0, 8]] + -0.00154741089157206784 # B[316, [5, 2, 1, 3], [52, 8, 2, 8]] + 0.00417852330669051582 # B[317, [5, 2, 1, 3], [53, 8, 4, 8]] + 0.00134060860138395356 # B[318, [5, 2, 1, 3], [54, 8, 6, 8]] + -4.29219459423162489e-05 # B[319, [5, 2, 1, 3], [55, 8, 8, 8]] + 0.000319124100064731785 # B[320, [6, 2, 2, 2], [6, 2, 2, 2]] + -0.00839561599135440172 # B[321, [6, 2, 2, 2], [7, 2, 2, 4]] + -0.00326195850510992494 # B[322, [6, 2, 2, 2], [8, 3, 0, 3]] + 0.0194547426296311776 # B[323, [6, 2, 2, 2], [9, 3, 1, 4]] + -0.020516093722439413 # B[324, [6, 2, 2, 2], [10, 3, 2, 3]] + -0.00901624473884381043 # B[325, [6, 2, 2, 2], [11, 3, 2, 5]] + 0.0129026669830971837 # B[326, [6, 2, 2, 2], [12, 3, 3, 4]] + 0.00463182910296210636 # B[327, [6, 2, 2, 2], [13, 3, 3, 6]] + -0.00261498466108737743 # B[328, [6, 2, 2, 2], [14, 4, 0, 4]] + 0.0215819608660451426 # B[329, [6, 2, 2, 2], [15, 4, 1, 5]] + 0.000767688854520869957 # B[330, [6, 2, 2, 2], [16, 4, 2, 4]] + -0.00666111439578009716 # B[331, [6, 2, 2, 2], [17, 4, 2, 6]] + 0.0112705725443772303 # B[332, [6, 2, 2, 2], [18, 4, 3, 5]] + 0.00228839615631495127 # B[333, [6, 2, 2, 2], [19, 4, 3, 7]] + 0.00124148748415313414 # B[334, [6, 2, 2, 2], [20, 4, 4, 4]] + 0.00353391028977510834 # B[335, [6, 2, 2, 2], [21, 4, 4, 6]] + -0.00310464569903003834 # B[336, [6, 2, 2, 2], [22, 4, 4, 8]] + -0.001770681064288395 # B[337, [6, 2, 2, 2], [23, 5, 0, 5]] + 0.000554784469018851215 # B[338, [6, 2, 2, 2], [24, 5, 1, 6]] + -0.000102008183116791319 # B[339, [6, 2, 2, 2], [25, 5, 2, 5]] + -0.00128750706249572758 # B[340, [6, 2, 2, 2], [26, 5, 2, 7]] + 0.0046490656013451568 # B[341, [6, 2, 2, 2], [27, 5, 3, 6]] + 0.0034506831073765681 # B[342, [6, 2, 2, 2], [28, 5, 3, 8]] + 0.00501652811902741046 # B[343, [6, 2, 2, 2], [29, 5, 4, 5]] + -1.88389891915279224e-05 # B[344, [6, 2, 2, 2], [30, 5, 4, 7]] + -0.00246586719805504942 # B[345, [6, 2, 2, 2], [31, 5, 5, 6]] + -0.00339629261051872756 # B[346, [6, 2, 2, 2], [32, 5, 5, 8]] + -1.22729584505151552e-05 # B[347, [6, 2, 2, 2], [33, 6, 0, 6]] + -0.0055646406349652653 # B[348, [6, 2, 2, 2], [34, 6, 1, 7]] + 0.00216606634250279383 # B[349, [6, 2, 2, 2], [35, 6, 2, 6]] + -0.000140725603696151627 # B[350, [6, 2, 2, 2], [36, 6, 2, 8]] + -0.01190136261487338 # B[351, [6, 2, 2, 2], [37, 6, 3, 7]] + -0.000996588010308921109 # B[352, [6, 2, 2, 2], [38, 6, 4, 6]] + -0.0040124728576705895 # B[353, [6, 2, 2, 2], [39, 6, 4, 8]] + 0.000422679331586792552 # B[354, [6, 2, 2, 2], [40, 6, 5, 7]] + 0.000548939662545001959 # B[355, [6, 2, 2, 2], [41, 6, 6, 6]] + 0.00256895119228900404 # B[356, [6, 2, 2, 2], [42, 6, 6, 8]] + -0.000615139781019174688 # B[357, [6, 2, 2, 2], [43, 7, 0, 7]] + -0.00404941774617198578 # B[358, [6, 2, 2, 2], [44, 7, 1, 8]] + 0.00466754848324051064 # B[359, [6, 2, 2, 2], [45, 7, 2, 7]] + 0.00150461796185176488 # B[360, [6, 2, 2, 2], [46, 7, 3, 8]] + 0.0037489054114537468 # B[361, [6, 2, 2, 2], [47, 7, 4, 7]] + 0.00285804436398595782 # B[362, [6, 2, 2, 2], [48, 7, 5, 8]] + -0.00287521518361254919 # B[363, [6, 2, 2, 2], [49, 7, 6, 7]] + 0.000969520968104660755 # B[364, [6, 2, 2, 2], [50, 7, 7, 8]] + -0.000716125857042927043 # B[365, [6, 2, 2, 2], [51, 8, 0, 8]] + -0.00157385185114507437 # B[366, [6, 2, 2, 2], [52, 8, 2, 8]] + 0.002689243736875038 # B[367, [6, 2, 2, 2], [53, 8, 4, 8]] + -0.000661038690452418623 # B[368, [6, 2, 2, 2], [54, 8, 6, 8]] + 0.00157186481624649321 # B[369, [6, 2, 2, 2], [55, 8, 8, 8]] + -0.0134601349926017494 # B[370, [7, 2, 2, 4], [7, 2, 2, 4]] + -0.000918558149715113011 # B[371, [7, 2, 2, 4], [8, 3, 0, 3]] + -0.00377418701166061087 # B[372, [7, 2, 2, 4], [9, 3, 1, 4]] + 0.0148168734486278948 # B[373, [7, 2, 2, 4], [10, 3, 2, 3]] + -0.00535328606426562371 # B[374, [7, 2, 2, 4], [11, 3, 2, 5]] + 0.00804271469408427385 # B[375, [7, 2, 2, 4], [12, 3, 3, 4]] + 0.00136329663181449737 # B[376, [7, 2, 2, 4], [13, 3, 3, 6]] + 0.000218608555253111195 # B[377, [7, 2, 2, 4], [14, 4, 0, 4]] + 0.00767165886258287799 # B[378, [7, 2, 2, 4], [15, 4, 1, 5]] + -0.0022580429604385833 # B[379, [7, 2, 2, 4], [16, 4, 2, 4]] + -0.0050991924246220309 # B[380, [7, 2, 2, 4], [17, 4, 2, 6]] + -0.00308509180848093572 # B[381, [7, 2, 2, 4], [18, 4, 3, 5]] + -0.000900097231895549623 # B[382, [7, 2, 2, 4], [19, 4, 3, 7]] + -0.0063557020842957869 # B[383, [7, 2, 2, 4], [20, 4, 4, 4]] + -0.000409569358807882096 # B[384, [7, 2, 2, 4], [21, 4, 4, 6]] + 0.00254581400782049119 # B[385, [7, 2, 2, 4], [22, 4, 4, 8]] + 0.000657951401298526029 # B[386, [7, 2, 2, 4], [23, 5, 0, 5]] + -0.00940269729352927013 # B[387, [7, 2, 2, 4], [24, 5, 1, 6]] + 0.00333566383730494239 # B[388, [7, 2, 2, 4], [25, 5, 2, 5]] + 0.00896493308698088215 # B[389, [7, 2, 2, 4], [26, 5, 2, 7]] + 0.00132812590751918685 # B[390, [7, 2, 2, 4], [27, 5, 3, 6]] + -0.00127282140780485189 # B[391, [7, 2, 2, 4], [28, 5, 3, 8]] + -0.00435358176352772068 # B[392, [7, 2, 2, 4], [29, 5, 4, 5]] + -0.00226566527245459885 # B[393, [7, 2, 2, 4], [30, 5, 4, 7]] + 0.00326597657188156627 # B[394, [7, 2, 2, 4], [31, 5, 5, 6]] + -0.00247993076825692074 # B[395, [7, 2, 2, 4], [32, 5, 5, 8]] + -0.00138012806761597748 # B[396, [7, 2, 2, 4], [33, 6, 0, 6]] + -0.00296559266178312566 # B[397, [7, 2, 2, 4], [34, 6, 1, 7]] + -0.00345134318647404535 # B[398, [7, 2, 2, 4], [35, 6, 2, 6]] + 0.00604122282441024554 # B[399, [7, 2, 2, 4], [36, 6, 2, 8]] + -0.00602530276328681197 # B[400, [7, 2, 2, 4], [37, 6, 3, 7]] + 0.00113230868581531974 # B[401, [7, 2, 2, 4], [38, 6, 4, 6]] + 0.00132069580529702024 # B[402, [7, 2, 2, 4], [39, 6, 4, 8]] + -0.00355708848499901743 # B[403, [7, 2, 2, 4], [40, 6, 5, 7]] + 0.00103954578232134899 # B[404, [7, 2, 2, 4], [41, 6, 6, 6]] + 0.00138660655783935638 # B[405, [7, 2, 2, 4], [42, 6, 6, 8]] + 0.00122312383058832339 # B[406, [7, 2, 2, 4], [43, 7, 0, 7]] + 0.00122422070912251465 # B[407, [7, 2, 2, 4], [44, 7, 1, 8]] + -0.00497379521097694472 # B[408, [7, 2, 2, 4], [45, 7, 2, 7]] + -0.00811974704425355749 # B[409, [7, 2, 2, 4], [46, 7, 3, 8]] + 0.00114732010903773659 # B[410, [7, 2, 2, 4], [47, 7, 4, 7]] + -0.00569074628354063975 # B[411, [7, 2, 2, 4], [48, 7, 5, 8]] + 0.00235624642317577588 # B[412, [7, 2, 2, 4], [49, 7, 6, 7]] + 7.98437182146268919e-05 # B[413, [7, 2, 2, 4], [50, 7, 7, 8]] + 0.00113891921332402897 # B[414, [7, 2, 2, 4], [51, 8, 0, 8]] + -0.00492469555442132112 # B[415, [7, 2, 2, 4], [52, 8, 2, 8]] + 0.000792980352556455804 # B[416, [7, 2, 2, 4], [53, 8, 4, 8]] + 0.00153854887229367375 # B[417, [7, 2, 2, 4], [54, 8, 6, 8]] + -0.000881221748445243022 # B[418, [7, 2, 2, 4], [55, 8, 8, 8]] + -0.00136471788502227735 # B[419, [8, 3, 0, 3], [8, 3, 0, 3]] + 0.00246251727263488776 # B[420, [8, 3, 0, 3], [9, 3, 1, 4]] + 0.000996613519267240677 # B[421, [8, 3, 0, 3], [10, 3, 2, 3]] + -0.00207976146372090831 # B[422, [8, 3, 0, 3], [11, 3, 2, 5]] + -9.97509064182486305e-05 # B[423, [8, 3, 0, 3], [12, 3, 3, 4]] + 0.000656935135924852087 # B[424, [8, 3, 0, 3], [13, 3, 3, 6]] + -0.000492474229225159377 # B[425, [8, 3, 0, 3], [14, 4, 0, 4]] + 0.0032189163248994351 # B[426, [8, 3, 0, 3], [15, 4, 1, 5]] + -0.00115555104609991501 # B[427, [8, 3, 0, 3], [16, 4, 2, 4]] + -0.000101151026370576574 # B[428, [8, 3, 0, 3], [17, 4, 2, 6]] + 0.00020301152740384229 # B[429, [8, 3, 0, 3], [18, 4, 3, 5]] + -0.000285445107860462371 # B[430, [8, 3, 0, 3], [19, 4, 3, 7]] + 0.000462665925556146607 # B[431, [8, 3, 0, 3], [20, 4, 4, 4]] + -2.75652763320703015e-05 # B[432, [8, 3, 0, 3], [21, 4, 4, 6]] + -0.000358778647317398169 # B[433, [8, 3, 0, 3], [22, 4, 4, 8]] + -0.000397176131748222527 # B[434, [8, 3, 0, 3], [23, 5, 0, 5]] + -0.00026950177456114624 # B[435, [8, 3, 0, 3], [24, 5, 1, 6]] + 0.00119424632084062527 # B[436, [8, 3, 0, 3], [25, 5, 2, 5]] + 0.000922347152199163439 # B[437, [8, 3, 0, 3], [26, 5, 2, 7]] + -0.000340838509282952173 # B[438, [8, 3, 0, 3], [27, 5, 3, 6]] + 0.00128847730890532808 # B[439, [8, 3, 0, 3], [28, 5, 3, 8]] + -0.00044582191494569115 # B[440, [8, 3, 0, 3], [29, 5, 4, 5]] + -0.00114898350718379422 # B[441, [8, 3, 0, 3], [30, 5, 4, 7]] + -0.000530499767100067743 # B[442, [8, 3, 0, 3], [31, 5, 5, 6]] + 1.68864176486992895e-05 # B[443, [8, 3, 0, 3], [32, 5, 5, 8]] + -0.000312292146951373417 # B[444, [8, 3, 0, 3], [33, 6, 0, 6]] + -0.00186273440079770883 # B[445, [8, 3, 0, 3], [34, 6, 1, 7]] + -0.000475625961442131123 # B[446, [8, 3, 0, 3], [35, 6, 2, 6]] + 0.000505090975521763769 # B[447, [8, 3, 0, 3], [36, 6, 2, 8]] + 0.000128630083375533277 # B[448, [8, 3, 0, 3], [37, 6, 3, 7]] + -0.000431369283499544176 # B[449, [8, 3, 0, 3], [38, 6, 4, 6]] + 0.000461881443708941908 # B[450, [8, 3, 0, 3], [39, 6, 4, 8]] + 0.000867550860200114182 # B[451, [8, 3, 0, 3], [40, 6, 5, 7]] + 0.000179604539903628624 # B[452, [8, 3, 0, 3], [41, 6, 6, 6]] + -0.000405383988192370426 # B[453, [8, 3, 0, 3], [42, 6, 6, 8]] + -0.000305572243426546764 # B[454, [8, 3, 0, 3], [43, 7, 0, 7]] + -0.0010766931736053021 # B[455, [8, 3, 0, 3], [44, 7, 1, 8]] + 0.000701859051866787764 # B[456, [8, 3, 0, 3], [45, 7, 2, 7]] + -1.5413662061584954e-05 # B[457, [8, 3, 0, 3], [46, 7, 3, 8]] + 0.000428834666348756888 # B[458, [8, 3, 0, 3], [47, 7, 4, 7]] + 0.000468098667731533385 # B[459, [8, 3, 0, 3], [48, 7, 5, 8]] + 0.000158467988956009775 # B[460, [8, 3, 0, 3], [49, 7, 6, 7]] + 2.77948419442784408e-05 # B[461, [8, 3, 0, 3], [50, 7, 7, 8]] + -0.000282655955044820717 # B[462, [8, 3, 0, 3], [51, 8, 0, 8]] + 0.000100300940760145348 # B[463, [8, 3, 0, 3], [52, 8, 2, 8]] + 0.000314947671131902973 # B[464, [8, 3, 0, 3], [53, 8, 4, 8]] + 0.000144842823919437078 # B[465, [8, 3, 0, 3], [54, 8, 6, 8]] + 7.00050428864840146e-05 # B[466, [8, 3, 0, 3], [55, 8, 8, 8]] + 0.0118411448561217512 # B[467, [9, 3, 1, 4], [9, 3, 1, 4]] + 0.0158809314732707603 # B[468, [9, 3, 1, 4], [10, 3, 2, 3]] + -0.00690506493475962109 # B[469, [9, 3, 1, 4], [11, 3, 2, 5]] + 0.0085626937099196887 # B[470, [9, 3, 1, 4], [12, 3, 3, 4]] + -0.00387686964925252654 # B[471, [9, 3, 1, 4], [13, 3, 3, 6]] + 0.00015029200549142481 # B[472, [9, 3, 1, 4], [14, 4, 0, 4]] + -0.000142532963490632015 # B[473, [9, 3, 1, 4], [15, 4, 1, 5]] + 0.00921427022949583042 # B[474, [9, 3, 1, 4], [16, 4, 2, 4]] + -0.0112717231196791407 # B[475, [9, 3, 1, 4], [17, 4, 2, 6]] + -0.0122014182952103704 # B[476, [9, 3, 1, 4], [18, 4, 3, 5]] + -0.0111571557686284996 # B[477, [9, 3, 1, 4], [19, 4, 3, 7]] + -0.00276180055211498916 # B[478, [9, 3, 1, 4], [20, 4, 4, 4]] + -0.00444456405006457382 # B[479, [9, 3, 1, 4], [21, 4, 4, 6]] + -0.00248162623330630983 # B[480, [9, 3, 1, 4], [22, 4, 4, 8]] + 0.000238830840202226575 # B[481, [9, 3, 1, 4], [23, 5, 0, 5]] + 0.0106883008114137777 # B[482, [9, 3, 1, 4], [24, 5, 1, 6]] + -0.00176293319638371826 # B[483, [9, 3, 1, 4], [25, 5, 2, 5]] + -0.000706186990249144109 # B[484, [9, 3, 1, 4], [26, 5, 2, 7]] + -0.000957413082652629373 # B[485, [9, 3, 1, 4], [27, 5, 3, 6]] + -0.00485998335666546887 # B[486, [9, 3, 1, 4], [28, 5, 3, 8]] + -0.000739967956913101287 # B[487, [9, 3, 1, 4], [29, 5, 4, 5]] + -0.00656002591947351353 # B[488, [9, 3, 1, 4], [30, 5, 4, 7]] + -0.00191607250770065712 # B[489, [9, 3, 1, 4], [31, 5, 5, 6]] + -0.000375150046930213714 # B[490, [9, 3, 1, 4], [32, 5, 5, 8]] + 0.000379540253919751804 # B[491, [9, 3, 1, 4], [33, 6, 0, 6]] + 0.0103809997405371179 # B[492, [9, 3, 1, 4], [34, 6, 1, 7]] + -0.00167937900508645203 # B[493, [9, 3, 1, 4], [35, 6, 2, 6]] + -0.000942453027264282192 # B[494, [9, 3, 1, 4], [36, 6, 2, 8]] + -0.00358794660355351257 # B[495, [9, 3, 1, 4], [37, 6, 3, 7]] + 0.00367542903060237222 # B[496, [9, 3, 1, 4], [38, 6, 4, 6]] + -0.00605874518215254298 # B[497, [9, 3, 1, 4], [39, 6, 4, 8]] + -0.0053364107721741022 # B[498, [9, 3, 1, 4], [40, 6, 5, 7]] + -0.00220303686176452889 # B[499, [9, 3, 1, 4], [41, 6, 6, 6]] + 0.000240224733534942676 # B[500, [9, 3, 1, 4], [42, 6, 6, 8]] + 0.00118204722287629585 # B[501, [9, 3, 1, 4], [43, 7, 0, 7]] + 0.00391606544218769514 # B[502, [9, 3, 1, 4], [44, 7, 1, 8]] + -0.00190557542057654024 # B[503, [9, 3, 1, 4], [45, 7, 2, 7]] + -0.0010749256928406746 # B[504, [9, 3, 1, 4], [46, 7, 3, 8]] + 6.24186835188134462e-05 # B[505, [9, 3, 1, 4], [47, 7, 4, 7]] + -0.00250872188348977114 # B[506, [9, 3, 1, 4], [48, 7, 5, 8]] + -0.00164710314956706405 # B[507, [9, 3, 1, 4], [49, 7, 6, 7]] + -0.0029144992153610676 # B[508, [9, 3, 1, 4], [50, 7, 7, 8]] + 0.000712015267242259442 # B[509, [9, 3, 1, 4], [51, 8, 0, 8]] + -0.00179539873092394715 # B[510, [9, 3, 1, 4], [52, 8, 2, 8]] + 0.00203000698298521493 # B[511, [9, 3, 1, 4], [53, 8, 4, 8]] + -0.00103477100047664442 # B[512, [9, 3, 1, 4], [54, 8, 6, 8]] + -0.000727628763147338854 # B[513, [9, 3, 1, 4], [55, 8, 8, 8]] + 0.0163451466486591972 # B[514, [10, 3, 2, 3], [10, 3, 2, 3]] + -0.00145259448176927441 # B[515, [10, 3, 2, 3], [11, 3, 2, 5]] + -0.00808947571520425568 # B[516, [10, 3, 2, 3], [12, 3, 3, 4]] + -0.00693599935022420205 # B[517, [10, 3, 2, 3], [13, 3, 3, 6]] + -0.00419683318703741731 # B[518, [10, 3, 2, 3], [14, 4, 0, 4]] + 0.00927666204585274323 # B[519, [10, 3, 2, 3], [15, 4, 1, 5]] + -0.0138962541759877663 # B[520, [10, 3, 2, 3], [16, 4, 2, 4]] + 0.0115061801390417759 # B[521, [10, 3, 2, 3], [17, 4, 2, 6]] + 0.0118559077356181798 # B[522, [10, 3, 2, 3], [18, 4, 3, 5]] + 0.00193270595871023604 # B[523, [10, 3, 2, 3], [19, 4, 3, 7]] + 0.00156708209719190472 # B[524, [10, 3, 2, 3], [20, 4, 4, 4]] + 0.0030286948486105119 # B[525, [10, 3, 2, 3], [21, 4, 4, 6]] + -6.03736466163237034e-05 # B[526, [10, 3, 2, 3], [22, 4, 4, 8]] + -0.00147218391304548835 # B[527, [10, 3, 2, 3], [23, 5, 0, 5]] + 0.000931966019926808685 # B[528, [10, 3, 2, 3], [24, 5, 1, 6]] + 0.0153667638164197012 # B[529, [10, 3, 2, 3], [25, 5, 2, 5]] + -0.0023105273691670326 # B[530, [10, 3, 2, 3], [26, 5, 2, 7]] + 0.0018873267014898696 # B[531, [10, 3, 2, 3], [27, 5, 3, 6]] + -0.00221592978134090707 # B[532, [10, 3, 2, 3], [28, 5, 3, 8]] + 0.00175823978838723916 # B[533, [10, 3, 2, 3], [29, 5, 4, 5]] + 0.00134986143361107494 # B[534, [10, 3, 2, 3], [30, 5, 4, 7]] + -0.00280444330034939227 # B[535, [10, 3, 2, 3], [31, 5, 5, 6]] + -0.000446159575940244073 # B[536, [10, 3, 2, 3], [32, 5, 5, 8]] + 0.000126573802730074736 # B[537, [10, 3, 2, 3], [33, 6, 0, 6]] + 7.95217271451070795e-05 # B[538, [10, 3, 2, 3], [34, 6, 1, 7]] + -0.000615992203402992468 # B[539, [10, 3, 2, 3], [35, 6, 2, 6]] + -0.0106304231235931409 # B[540, [10, 3, 2, 3], [36, 6, 2, 8]] + -0.00513102234934090934 # B[541, [10, 3, 2, 3], [37, 6, 3, 7]] + 0.00086364506858761271 # B[542, [10, 3, 2, 3], [38, 6, 4, 6]] + -0.00427816275089007263 # B[543, [10, 3, 2, 3], [39, 6, 4, 8]] + -0.00709876751806875171 # B[544, [10, 3, 2, 3], [40, 6, 5, 7]] + -0.00107679083671011894 # B[545, [10, 3, 2, 3], [41, 6, 6, 6]] + -0.0014022801302571164 # B[546, [10, 3, 2, 3], [42, 6, 6, 8]] + 0.00032001340322446864 # B[547, [10, 3, 2, 3], [43, 7, 0, 7]] + 0.0099494513037338677 # B[548, [10, 3, 2, 3], [44, 7, 1, 8]] + 0.00657164457459321564 # B[549, [10, 3, 2, 3], [45, 7, 2, 7]] + -0.00193909086513409032 # B[550, [10, 3, 2, 3], [46, 7, 3, 8]] + -0.000661327911070458407 # B[551, [10, 3, 2, 3], [47, 7, 4, 7]] + -0.00236609840279333045 # B[552, [10, 3, 2, 3], [48, 7, 5, 8]] + 0.000323126961361372422 # B[553, [10, 3, 2, 3], [49, 7, 6, 7]] + 0.00156411007472663857 # B[554, [10, 3, 2, 3], [50, 7, 7, 8]] + -0.000413410696562647312 # B[555, [10, 3, 2, 3], [51, 8, 0, 8]] + 0.00151556635054790959 # B[556, [10, 3, 2, 3], [52, 8, 2, 8]] + 0.0032252808357782943 # B[557, [10, 3, 2, 3], [53, 8, 4, 8]] + 0.00431814581620697767 # B[558, [10, 3, 2, 3], [54, 8, 6, 8]] + 0.000198535493268348594 # B[559, [10, 3, 2, 3], [55, 8, 8, 8]] + 0.0156540432654675432 # B[560, [11, 3, 2, 5], [11, 3, 2, 5]] + 0.00979845476873780416 # B[561, [11, 3, 2, 5], [12, 3, 3, 4]] + 0.00873265456764509701 # B[562, [11, 3, 2, 5], [13, 3, 3, 6]] + -0.00355250352643814854 # B[563, [11, 3, 2, 5], [14, 4, 0, 4]] + 0.0197388975583387243 # B[564, [11, 3, 2, 5], [15, 4, 1, 5]] + 0.0158965586216084157 # B[565, [11, 3, 2, 5], [16, 4, 2, 4]] + 0.0126440348146513917 # B[566, [11, 3, 2, 5], [17, 4, 2, 6]] + 0.00588822462217037865 # B[567, [11, 3, 2, 5], [18, 4, 3, 5]] + 0.00465829809814364074 # B[568, [11, 3, 2, 5], [19, 4, 3, 7]] + 0.00460100330976275125 # B[569, [11, 3, 2, 5], [20, 4, 4, 4]] + 0.00507979510261629894 # B[570, [11, 3, 2, 5], [21, 4, 4, 6]] + -0.000978147842247499566 # B[571, [11, 3, 2, 5], [22, 4, 4, 8]] + 0.000175648698607325238 # B[572, [11, 3, 2, 5], [23, 5, 0, 5]] + 0.00701365729786882983 # B[573, [11, 3, 2, 5], [24, 5, 1, 6]] + 0.0124121871279893672 # B[574, [11, 3, 2, 5], [25, 5, 2, 5]] + 0.0133268604743271169 # B[575, [11, 3, 2, 5], [26, 5, 2, 7]] + -0.00306906262974302943 # B[576, [11, 3, 2, 5], [27, 5, 3, 6]] + 0.00411586711144847073 # B[577, [11, 3, 2, 5], [28, 5, 3, 8]] + -0.00483702208096517539 # B[578, [11, 3, 2, 5], [29, 5, 4, 5]] + 0.000232830853394127776 # B[579, [11, 3, 2, 5], [30, 5, 4, 7]] + -0.00500644765401524715 # B[580, [11, 3, 2, 5], [31, 5, 5, 6]] + -0.000732991087538808345 # B[581, [11, 3, 2, 5], [32, 5, 5, 8]] + 0.0028290195015726223 # B[582, [11, 3, 2, 5], [33, 6, 0, 6]] + 0.000660043236562475252 # B[583, [11, 3, 2, 5], [34, 6, 1, 7]] + 0.00858014820620479901 # B[584, [11, 3, 2, 5], [35, 6, 2, 6]] + 0.00979420830127970127 # B[585, [11, 3, 2, 5], [36, 6, 2, 8]] + -0.00276929529868128257 # B[586, [11, 3, 2, 5], [37, 6, 3, 7]] + -0.00462592209123751513 # B[587, [11, 3, 2, 5], [38, 6, 4, 6]] + 0.000957159367659247626 # B[588, [11, 3, 2, 5], [39, 6, 4, 8]] + -0.00289923459154850169 # B[589, [11, 3, 2, 5], [40, 6, 5, 7]] + -0.00605668820795574915 # B[590, [11, 3, 2, 5], [41, 6, 6, 6]] + -0.00571070540762017888 # B[591, [11, 3, 2, 5], [42, 6, 6, 8]] + 0.00247733408975375075 # B[592, [11, 3, 2, 5], [43, 7, 0, 7]] + 0.00452000165177812024 # B[593, [11, 3, 2, 5], [44, 7, 1, 8]] + 0.00267833963693382693 # B[594, [11, 3, 2, 5], [45, 7, 2, 7]] + -0.00558917145621175976 # B[595, [11, 3, 2, 5], [46, 7, 3, 8]] + -0.00228097422335522999 # B[596, [11, 3, 2, 5], [47, 7, 4, 7]] + -0.00366604043706369575 # B[597, [11, 3, 2, 5], [48, 7, 5, 8]] + -0.00340088281218112534 # B[598, [11, 3, 2, 5], [49, 7, 6, 7]] + -0.00355022426643257852 # B[599, [11, 3, 2, 5], [50, 7, 7, 8]] + 0.00124080314205340242 # B[600, [11, 3, 2, 5], [51, 8, 0, 8]] + 0.00287261267197001097 # B[601, [11, 3, 2, 5], [52, 8, 2, 8]] + 0.000744815191487350516 # B[602, [11, 3, 2, 5], [53, 8, 4, 8]] + -0.000112288931147085103 # B[603, [11, 3, 2, 5], [54, 8, 6, 8]] + -0.000128712309023326903 # B[604, [11, 3, 2, 5], [55, 8, 8, 8]] + -0.00238666366477884723 # B[605, [12, 3, 3, 4], [12, 3, 3, 4]] + 0.000248696286071804773 # B[606, [12, 3, 3, 4], [13, 3, 3, 6]] + -0.000479775127143412111 # B[607, [12, 3, 3, 4], [14, 4, 0, 4]] + 0.00175952173341571141 # B[608, [12, 3, 3, 4], [15, 4, 1, 5]] + 0.000197368498788095745 # B[609, [12, 3, 3, 4], [16, 4, 2, 4]] + 0.00726401135600521306 # B[610, [12, 3, 3, 4], [17, 4, 2, 6]] + -0.00118096336629036625 # B[611, [12, 3, 3, 4], [18, 4, 3, 5]] + 0.00702896514440041337 # B[612, [12, 3, 3, 4], [19, 4, 3, 7]] + -0.00236026619914155369 # B[613, [12, 3, 3, 4], [20, 4, 4, 4]] + -0.00341152672753146672 # B[614, [12, 3, 3, 4], [21, 4, 4, 6]] + 0.00348613231611557411 # B[615, [12, 3, 3, 4], [22, 4, 4, 8]] + 0.00244457707345889508 # B[616, [12, 3, 3, 4], [23, 5, 0, 5]] + -0.000822727235681003019 # B[617, [12, 3, 3, 4], [24, 5, 1, 6]] + -0.00248763810919495551 # B[618, [12, 3, 3, 4], [25, 5, 2, 5]] + 0.00796413115978647848 # B[619, [12, 3, 3, 4], [26, 5, 2, 7]] + -0.00179317048488774472 # B[620, [12, 3, 3, 4], [27, 5, 3, 6]] + 0.00454384820995466787 # B[621, [12, 3, 3, 4], [28, 5, 3, 8]] + -0.00425365149530766012 # B[622, [12, 3, 3, 4], [29, 5, 4, 5]] + -0.000569152560526600682 # B[623, [12, 3, 3, 4], [30, 5, 4, 7]] + -0.00506501220127485163 # B[624, [12, 3, 3, 4], [31, 5, 5, 6]] + -0.00142637122228714969 # B[625, [12, 3, 3, 4], [32, 5, 5, 8]] + 0.00190739239349446005 # B[626, [12, 3, 3, 4], [33, 6, 0, 6]] + 0.00215429853006474104 # B[627, [12, 3, 3, 4], [34, 6, 1, 7]] + 0.00512135793044871807 # B[628, [12, 3, 3, 4], [35, 6, 2, 6]] + 0.00479344551680733165 # B[629, [12, 3, 3, 4], [36, 6, 2, 8]] + -0.000813733007282164966 # B[630, [12, 3, 3, 4], [37, 6, 3, 7]] + -0.00162747725274282884 # B[631, [12, 3, 3, 4], [38, 6, 4, 6]] + -0.00440004969635155417 # B[632, [12, 3, 3, 4], [39, 6, 4, 8]] + -0.00939941153506137356 # B[633, [12, 3, 3, 4], [40, 6, 5, 7]] + -0.00314893787689287524 # B[634, [12, 3, 3, 4], [41, 6, 6, 6]] + -0.00125776748984993136 # B[635, [12, 3, 3, 4], [42, 6, 6, 8]] + 0.00129112127843685615 # B[636, [12, 3, 3, 4], [43, 7, 0, 7]] + 0.00564724346615860621 # B[637, [12, 3, 3, 4], [44, 7, 1, 8]] + -0.0018460571659526942 # B[638, [12, 3, 3, 4], [45, 7, 2, 7]] + -0.000300525523225368685 # B[639, [12, 3, 3, 4], [46, 7, 3, 8]] + -0.00277157581435865698 # B[640, [12, 3, 3, 4], [47, 7, 4, 7]] + -0.00975210406554173105 # B[641, [12, 3, 3, 4], [48, 7, 5, 8]] + -0.00233845213984289896 # B[642, [12, 3, 3, 4], [49, 7, 6, 7]] + -0.00138723239922117561 # B[643, [12, 3, 3, 4], [50, 7, 7, 8]] + 0.000864866797073243071 # B[644, [12, 3, 3, 4], [51, 8, 0, 8]] + -0.000747563068773752452 # B[645, [12, 3, 3, 4], [52, 8, 2, 8]] + 0.000965474694725087373 # B[646, [12, 3, 3, 4], [53, 8, 4, 8]] + -0.00140612646390263218 # B[647, [12, 3, 3, 4], [54, 8, 6, 8]] + -0.00149643617894318522 # B[648, [12, 3, 3, 4], [55, 8, 8, 8]] + 0.00149153681612450295 # B[649, [13, 3, 3, 6], [13, 3, 3, 6]] + -0.000954556711257832646 # B[650, [13, 3, 3, 6], [14, 4, 0, 4]] + 0.00120983585813713799 # B[651, [13, 3, 3, 6], [15, 4, 1, 5]] + 0.00300317867570911888 # B[652, [13, 3, 3, 6], [16, 4, 2, 4]] + 0.00236443796053106663 # B[653, [13, 3, 3, 6], [17, 4, 2, 6]] + 0.00415524139600132597 # B[654, [13, 3, 3, 6], [18, 4, 3, 5]] + -0.000123573851697839077 # B[655, [13, 3, 3, 6], [19, 4, 3, 7]] + 0.000470359195248265527 # B[656, [13, 3, 3, 6], [20, 4, 4, 4]] + 0.000635927641249957321 # B[657, [13, 3, 3, 6], [21, 4, 4, 6]] + 0.000747673754939660613 # B[658, [13, 3, 3, 6], [22, 4, 4, 8]] + 0.00074188846631736971 # B[659, [13, 3, 3, 6], [23, 5, 0, 5]] + 0.00463957097737913854 # B[660, [13, 3, 3, 6], [24, 5, 1, 6]] + -0.00271105182543343939 # B[661, [13, 3, 3, 6], [25, 5, 2, 5]] + 6.90411348413036419e-06 # B[662, [13, 3, 3, 6], [26, 5, 2, 7]] + 0.000911354980270381865 # B[663, [13, 3, 3, 6], [27, 5, 3, 6]] + -0.0028545746938972022 # B[664, [13, 3, 3, 6], [28, 5, 3, 8]] + -1.76062828863947363e-05 # B[665, [13, 3, 3, 6], [29, 5, 4, 5]] + -1.51206672011107435e-05 # B[666, [13, 3, 3, 6], [30, 5, 4, 7]] + -0.000798318879555708766 # B[667, [13, 3, 3, 6], [31, 5, 5, 6]] + -0.0015978026047660434 # B[668, [13, 3, 3, 6], [32, 5, 5, 8]] + 0.00034244751324807865 # B[669, [13, 3, 3, 6], [33, 6, 0, 6]] + 0.00338996797689858353 # B[670, [13, 3, 3, 6], [34, 6, 1, 7]] + 0.000289281476490772793 # B[671, [13, 3, 3, 6], [35, 6, 2, 6]] + -0.000559772151149058594 # B[672, [13, 3, 3, 6], [36, 6, 2, 8]] + -0.000650724286175463629 # B[673, [13, 3, 3, 6], [37, 6, 3, 7]] + 0.00148244897292096334 # B[674, [13, 3, 3, 6], [38, 6, 4, 6]] + 0.000183404639618602733 # B[675, [13, 3, 3, 6], [39, 6, 4, 8]] + -0.00185779692530890772 # B[676, [13, 3, 3, 6], [40, 6, 5, 7]] + -0.000708322215432564961 # B[677, [13, 3, 3, 6], [41, 6, 6, 6]] + -0.000491831969715535167 # B[678, [13, 3, 3, 6], [42, 6, 6, 8]] + 0.000833818016036214082 # B[679, [13, 3, 3, 6], [43, 7, 0, 7]] + -0.00256922900730601443 # B[680, [13, 3, 3, 6], [44, 7, 1, 8]] + -0.00112433206588518839 # B[681, [13, 3, 3, 6], [45, 7, 2, 7]] + 6.43716101358243753e-05 # B[682, [13, 3, 3, 6], [46, 7, 3, 8]] + -0.00126304972485289518 # B[683, [13, 3, 3, 6], [47, 7, 4, 7]] + -0.00210937996313975001 # B[684, [13, 3, 3, 6], [48, 7, 5, 8]] + -0.00126022676030809744 # B[685, [13, 3, 3, 6], [49, 7, 6, 7]] + -0.000555039709846411045 # B[686, [13, 3, 3, 6], [50, 7, 7, 8]] + 0.000790824100586496465 # B[687, [13, 3, 3, 6], [51, 8, 0, 8]] + -0.000844206812343649936 # B[688, [13, 3, 3, 6], [52, 8, 2, 8]] + 0.000195900027714517901 # B[689, [13, 3, 3, 6], [53, 8, 4, 8]] + -0.000823274415849936658 # B[690, [13, 3, 3, 6], [54, 8, 6, 8]] + -0.000330474595809105917 # B[691, [13, 3, 3, 6], [55, 8, 8, 8]] + -3.04835503155357485e-05 # B[692, [14, 4, 0, 4], [14, 4, 0, 4]] + -0.000825475145007361147 # B[693, [14, 4, 0, 4], [15, 4, 1, 5]] + -0.00244887111925138484 # B[694, [14, 4, 0, 4], [16, 4, 2, 4]] + -0.00122050568127611732 # B[695, [14, 4, 0, 4], [17, 4, 2, 6]] + -0.00226655265247485693 # B[696, [14, 4, 0, 4], [18, 4, 3, 5]] + -0.000767631950688907327 # B[697, [14, 4, 0, 4], [19, 4, 3, 7]] + -0.000547575812124723171 # B[698, [14, 4, 0, 4], [20, 4, 4, 4]] + -0.00121783548699544442 # B[699, [14, 4, 0, 4], [21, 4, 4, 6]] + 6.68947985199286332e-05 # B[700, [14, 4, 0, 4], [22, 4, 4, 8]] + -9.6030771921717939e-05 # B[701, [14, 4, 0, 4], [23, 5, 0, 5]] + -0.000544408900336967871 # B[702, [14, 4, 0, 4], [24, 5, 1, 6]] + -0.00139019051437529293 # B[703, [14, 4, 0, 4], [25, 5, 2, 5]] + -0.000281919324988699413 # B[704, [14, 4, 0, 4], [26, 5, 2, 7]] + -0.00125721115437776171 # B[705, [14, 4, 0, 4], [27, 5, 3, 6]] + -0.000282797770993010317 # B[706, [14, 4, 0, 4], [28, 5, 3, 8]] + -0.00139320549871079641 # B[707, [14, 4, 0, 4], [29, 5, 4, 5]] + -0.000628813518841068401 # B[708, [14, 4, 0, 4], [30, 5, 4, 7]] + -0.000607292163329276047 # B[709, [14, 4, 0, 4], [31, 5, 5, 6]] + 0.000242807689929189566 # B[710, [14, 4, 0, 4], [32, 5, 5, 8]] + -0.000100536983796830487 # B[711, [14, 4, 0, 4], [33, 6, 0, 6]] + 0.00111838401982674706 # B[712, [14, 4, 0, 4], [34, 6, 1, 7]] + -0.0012014113032742873 # B[713, [14, 4, 0, 4], [35, 6, 2, 6]] + -1.32311363260466386e-05 # B[714, [14, 4, 0, 4], [36, 6, 2, 8]] + 0.000753146180409180327 # B[715, [14, 4, 0, 4], [37, 6, 3, 7]] + -0.000270332227596856156 # B[716, [14, 4, 0, 4], [38, 6, 4, 6]] + -0.000293750660311472775 # B[717, [14, 4, 0, 4], [39, 6, 4, 8]] + 6.52480591955099942e-05 # B[718, [14, 4, 0, 4], [40, 6, 5, 7]] + -4.70588815947581285e-05 # B[719, [14, 4, 0, 4], [41, 6, 6, 6]] + 0.000244731448919628669 # B[720, [14, 4, 0, 4], [42, 6, 6, 8]] + -9.3149326930830334e-05 # B[721, [14, 4, 0, 4], [43, 7, 0, 7]] + 0.000731947904616598796 # B[722, [14, 4, 0, 4], [44, 7, 1, 8]] + -0.00107463735030771668 # B[723, [14, 4, 0, 4], [45, 7, 2, 7]] + 0.000139861959076940934 # B[724, [14, 4, 0, 4], [46, 7, 3, 8]] + 0.000101877532936889281 # B[725, [14, 4, 0, 4], [47, 7, 4, 7]] + -0.000196888502333611437 # B[726, [14, 4, 0, 4], [48, 7, 5, 8]] + 6.12030178565765859e-05 # B[727, [14, 4, 0, 4], [49, 7, 6, 7]] + -0.000223986590912481076 # B[728, [14, 4, 0, 4], [50, 7, 7, 8]] + -6.56819431667232667e-05 # B[729, [14, 4, 0, 4], [51, 8, 0, 8]] + -0.000970632773483491584 # B[730, [14, 4, 0, 4], [52, 8, 2, 8]] + -0.000182189294658170395 # B[731, [14, 4, 0, 4], [53, 8, 4, 8]] + -3.45215935849477185e-05 # B[732, [14, 4, 0, 4], [54, 8, 6, 8]] + 6.19739521221795986e-05 # B[733, [14, 4, 0, 4], [55, 8, 8, 8]] + 0.000242753902013392972 # B[734, [15, 4, 1, 5], [15, 4, 1, 5]] + 0.00729727211034517358 # B[735, [15, 4, 1, 5], [16, 4, 2, 4]] + -0.0024545495000649507 # B[736, [15, 4, 1, 5], [17, 4, 2, 6]] + -0.00265559618939786597 # B[737, [15, 4, 1, 5], [18, 4, 3, 5]] + 0.00473045463551583639 # B[738, [15, 4, 1, 5], [19, 4, 3, 7]] + -0.000140785797905494323 # B[739, [15, 4, 1, 5], [20, 4, 4, 4]] + 0.00179841698526277474 # B[740, [15, 4, 1, 5], [21, 4, 4, 6]] + 0.00129773534161339073 # B[741, [15, 4, 1, 5], [22, 4, 4, 8]] + 0.00172905697138841467 # B[742, [15, 4, 1, 5], [23, 5, 0, 5]] + -0.00408304027381215483 # B[743, [15, 4, 1, 5], [24, 5, 1, 6]] + -0.00205043992851699228 # B[744, [15, 4, 1, 5], [25, 5, 2, 5]] + 0.000756591579123801249 # B[745, [15, 4, 1, 5], [26, 5, 2, 7]] + -0.00421238291006168549 # B[746, [15, 4, 1, 5], [27, 5, 3, 6]] + -0.00196911327032830725 # B[747, [15, 4, 1, 5], [28, 5, 3, 8]] + 0.000729488918071528446 # B[748, [15, 4, 1, 5], [29, 5, 4, 5]] + -0.00177843604064341788 # B[749, [15, 4, 1, 5], [30, 5, 4, 7]] + -0.00130376966915328159 # B[750, [15, 4, 1, 5], [31, 5, 5, 6]] + -0.00198695656227435707 # B[751, [15, 4, 1, 5], [32, 5, 5, 8]] + 0.000608914142072050635 # B[752, [15, 4, 1, 5], [33, 6, 0, 6]] + -0.00109469344681823767 # B[753, [15, 4, 1, 5], [34, 6, 1, 7]] + -0.00451953523789613495 # B[754, [15, 4, 1, 5], [35, 6, 2, 6]] + 0.00279449892877900279 # B[755, [15, 4, 1, 5], [36, 6, 2, 8]] + -0.00435984465194903283 # B[756, [15, 4, 1, 5], [37, 6, 3, 7]] + 0.00275969130186590542 # B[757, [15, 4, 1, 5], [38, 6, 4, 6]] + 0.00154021904971430755 # B[758, [15, 4, 1, 5], [39, 6, 4, 8]] + -0.00146163413862035289 # B[759, [15, 4, 1, 5], [40, 6, 5, 7]] + -0.000333421796264918996 # B[760, [15, 4, 1, 5], [41, 6, 6, 6]] + -0.00139958818201657261 # B[761, [15, 4, 1, 5], [42, 6, 6, 8]] + 0.000750502250600797172 # B[762, [15, 4, 1, 5], [43, 7, 0, 7]] + 0.00476052216726493421 # B[763, [15, 4, 1, 5], [44, 7, 1, 8]] + -0.00155321215408361565 # B[764, [15, 4, 1, 5], [45, 7, 2, 7]] + -0.00351167160511536933 # B[765, [15, 4, 1, 5], [46, 7, 3, 8]] + 0.00268907735535169144 # B[766, [15, 4, 1, 5], [47, 7, 4, 7]] + -0.00296394481906553462 # B[767, [15, 4, 1, 5], [48, 7, 5, 8]] + -0.00115945739998543369 # B[768, [15, 4, 1, 5], [49, 7, 6, 7]] + -0.0011498694923236445 # B[769, [15, 4, 1, 5], [50, 7, 7, 8]] + 0.000691127444573572114 # B[770, [15, 4, 1, 5], [51, 8, 0, 8]] + 0.00149148321917135169 # B[771, [15, 4, 1, 5], [52, 8, 2, 8]] + 0.00226549729687968923 # B[772, [15, 4, 1, 5], [53, 8, 4, 8]] + -0.00127955154911817224 # B[773, [15, 4, 1, 5], [54, 8, 6, 8]] + -0.0006680598304007173 # B[774, [15, 4, 1, 5], [55, 8, 8, 8]] + 0.00773393138113156846 # B[775, [16, 4, 2, 4], [16, 4, 2, 4]] + 0.00481567776445743917 # B[776, [16, 4, 2, 4], [17, 4, 2, 6]] + 0.00646602315581837339 # B[777, [16, 4, 2, 4], [18, 4, 3, 5]] + 0.00401373256364237051 # B[778, [16, 4, 2, 4], [19, 4, 3, 7]] + -0.000224833927917125753 # B[779, [16, 4, 2, 4], [20, 4, 4, 4]] + 0.0030532060451974926 # B[780, [16, 4, 2, 4], [21, 4, 4, 6]] + -0.000126777823410560014 # B[781, [16, 4, 2, 4], [22, 4, 4, 8]] + 0.00109512376860463863 # B[782, [16, 4, 2, 4], [23, 5, 0, 5]] + 0.0014906978453806609 # B[783, [16, 4, 2, 4], [24, 5, 1, 6]] + 0.00278609484035531206 # B[784, [16, 4, 2, 4], [25, 5, 2, 5]] + 0.00720611209490516682 # B[785, [16, 4, 2, 4], [26, 5, 2, 7]] + 0.00230880055683394415 # B[786, [16, 4, 2, 4], [27, 5, 3, 6]] + 0.00492114792718315389 # B[787, [16, 4, 2, 4], [28, 5, 3, 8]] + 0.00102265649585190407 # B[788, [16, 4, 2, 4], [29, 5, 4, 5]] + -0.000348239317084679881 # B[789, [16, 4, 2, 4], [30, 5, 4, 7]] + -0.00394431438420023671 # B[790, [16, 4, 2, 4], [31, 5, 5, 6]] + -0.00362914461095884553 # B[791, [16, 4, 2, 4], [32, 5, 5, 8]] + 0.000172019923347470349 # B[792, [16, 4, 2, 4], [33, 6, 0, 6]] + -0.000316455135754767445 # B[793, [16, 4, 2, 4], [34, 6, 1, 7]] + 0.00107098215861984453 # B[794, [16, 4, 2, 4], [35, 6, 2, 6]] + -0.000907131668137324478 # B[795, [16, 4, 2, 4], [36, 6, 2, 8]] + -0.000367695081353409058 # B[796, [16, 4, 2, 4], [37, 6, 3, 7]] + 0.00181370580350630889 # B[797, [16, 4, 2, 4], [38, 6, 4, 6]] + 0.000820930060826967692 # B[798, [16, 4, 2, 4], [39, 6, 4, 8]] + -0.00466238776474962348 # B[799, [16, 4, 2, 4], [40, 6, 5, 7]] + -0.0024305728850557008 # B[800, [16, 4, 2, 4], [41, 6, 6, 6]] + -0.00165013696151081928 # B[801, [16, 4, 2, 4], [42, 6, 6, 8]] + 0.000760058338755045804 # B[802, [16, 4, 2, 4], [43, 7, 0, 7]] + -0.00203289214112462729 # B[803, [16, 4, 2, 4], [44, 7, 1, 8]] + -0.00103057221789182719 # B[804, [16, 4, 2, 4], [45, 7, 2, 7]] + 0.00188720556649034019 # B[805, [16, 4, 2, 4], [46, 7, 3, 8]] + -0.000348979964538542048 # B[806, [16, 4, 2, 4], [47, 7, 4, 7]] + -0.00595514004121479486 # B[807, [16, 4, 2, 4], [48, 7, 5, 8]] + -0.00122307692783891336 # B[808, [16, 4, 2, 4], [49, 7, 6, 7]] + -0.00161626528708522232 # B[809, [16, 4, 2, 4], [50, 7, 7, 8]] + 0.000683658453003721522 # B[810, [16, 4, 2, 4], [51, 8, 0, 8]] + 0.000169503544911074264 # B[811, [16, 4, 2, 4], [52, 8, 2, 8]] + 0.00163132840171071117 # B[812, [16, 4, 2, 4], [53, 8, 4, 8]] + -0.000633742642666999118 # B[813, [16, 4, 2, 4], [54, 8, 6, 8]] + -0.000861029784191980584 # B[814, [16, 4, 2, 4], [55, 8, 8, 8]] + 0.0101724317893582689 # B[815, [17, 4, 2, 6], [17, 4, 2, 6]] + 0.00963074903115390332 # B[816, [17, 4, 2, 6], [18, 4, 3, 5]] + 0.00792776812488414986 # B[817, [17, 4, 2, 6], [19, 4, 3, 7]] + 0.00129789596639547263 # B[818, [17, 4, 2, 6], [20, 4, 4, 4]] + 0.0025280260724625768 # B[819, [17, 4, 2, 6], [21, 4, 4, 6]] + -0.00130604081814601758 # B[820, [17, 4, 2, 6], [22, 4, 4, 8]] + 0.00061656245411057832 # B[821, [17, 4, 2, 6], [23, 5, 0, 5]] + 0.00256026791937838134 # B[822, [17, 4, 2, 6], [24, 5, 1, 6]] + 0.00833728674660196879 # B[823, [17, 4, 2, 6], [25, 5, 2, 5]] + 0.00819332084025456604 # B[824, [17, 4, 2, 6], [26, 5, 2, 7]] + 0.00199258058679730159 # B[825, [17, 4, 2, 6], [27, 5, 3, 6]] + -0.00235687406293394464 # B[826, [17, 4, 2, 6], [28, 5, 3, 8]] + 0.00172306590551023903 # B[827, [17, 4, 2, 6], [29, 5, 4, 5]] + 0.00273320921325834404 # B[828, [17, 4, 2, 6], [30, 5, 4, 7]] + 0.00124490813870011289 # B[829, [17, 4, 2, 6], [31, 5, 5, 6]] + -0.00239829497882970916 # B[830, [17, 4, 2, 6], [32, 5, 5, 8]] + 0.000403489881901454572 # B[831, [17, 4, 2, 6], [33, 6, 0, 6]] + 0.0115977289566935714 # B[832, [17, 4, 2, 6], [34, 6, 1, 7]] + 0.00631330244272786285 # B[833, [17, 4, 2, 6], [35, 6, 2, 6]] + 0.00745951676374975552 # B[834, [17, 4, 2, 6], [36, 6, 2, 8]] + 0.00129555462014044158 # B[835, [17, 4, 2, 6], [37, 6, 3, 7]] + 0.0031708889242759988 # B[836, [17, 4, 2, 6], [38, 6, 4, 6]] + 0.00314059501950873093 # B[837, [17, 4, 2, 6], [39, 6, 4, 8]] + -0.00157311519106628078 # B[838, [17, 4, 2, 6], [40, 6, 5, 7]] + -0.000535633835711041804 # B[839, [17, 4, 2, 6], [41, 6, 6, 6]] + -0.00106218347026977491 # B[840, [17, 4, 2, 6], [42, 6, 6, 8]] + 0.00171130648037900839 # B[841, [17, 4, 2, 6], [43, 7, 0, 7]] + 0.00318381348777509654 # B[842, [17, 4, 2, 6], [44, 7, 1, 8]] + 0.00121186975917000981 # B[843, [17, 4, 2, 6], [45, 7, 2, 7]] + -0.00505226933268299559 # B[844, [17, 4, 2, 6], [46, 7, 3, 8]] + 0.000505489038324865442 # B[845, [17, 4, 2, 6], [47, 7, 4, 7]] + -0.00260650572816220009 # B[846, [17, 4, 2, 6], [48, 7, 5, 8]] + -0.00458388666826989831 # B[847, [17, 4, 2, 6], [49, 7, 6, 7]] + -0.0030323259618317824 # B[848, [17, 4, 2, 6], [50, 7, 7, 8]] + 0.000919810997489799165 # B[849, [17, 4, 2, 6], [51, 8, 0, 8]] + 0.00153843620323466154 # B[850, [17, 4, 2, 6], [52, 8, 2, 8]] + 0.00177452104337356975 # B[851, [17, 4, 2, 6], [53, 8, 4, 8]] + -0.00133363365246129796 # B[852, [17, 4, 2, 6], [54, 8, 6, 8]] + 0.000497168699576265929 # B[853, [17, 4, 2, 6], [55, 8, 8, 8]] + 0.00916493227652732945 # B[854, [18, 4, 3, 5], [18, 4, 3, 5]] + 0.00662893191875722591 # B[855, [18, 4, 3, 5], [19, 4, 3, 7]] + 0.00102473567933248147 # B[856, [18, 4, 3, 5], [20, 4, 4, 4]] + 0.000661293664462594619 # B[857, [18, 4, 3, 5], [21, 4, 4, 6]] + 0.00302383517430961438 # B[858, [18, 4, 3, 5], [22, 4, 4, 8]] + 0.00182134236384280147 # B[859, [18, 4, 3, 5], [23, 5, 0, 5]] + 0.00481003527044247467 # B[860, [18, 4, 3, 5], [24, 5, 1, 6]] + 0.00472221587821478311 # B[861, [18, 4, 3, 5], [25, 5, 2, 5]] + 0.00204855894682247092 # B[862, [18, 4, 3, 5], [26, 5, 2, 7]] + 0.00108437129165206425 # B[863, [18, 4, 3, 5], [27, 5, 3, 6]] + 0.000188071259560827417 # B[864, [18, 4, 3, 5], [28, 5, 3, 8]] + 0.000402244806083140727 # B[865, [18, 4, 3, 5], [29, 5, 4, 5]] + 0.00350511561101824257 # B[866, [18, 4, 3, 5], [30, 5, 4, 7]] + -0.00196731170271619883 # B[867, [18, 4, 3, 5], [31, 5, 5, 6]] + -0.000854471064769226317 # B[868, [18, 4, 3, 5], [32, 5, 5, 8]] + 0.00163753590726098495 # B[869, [18, 4, 3, 5], [33, 6, 0, 6]] + 0.00678767470498069323 # B[870, [18, 4, 3, 5], [34, 6, 1, 7]] + 0.00671898362129526739 # B[871, [18, 4, 3, 5], [35, 6, 2, 6]] + 0.00504150139406711259 # B[872, [18, 4, 3, 5], [36, 6, 2, 8]] + -0.00150058947564556469 # B[873, [18, 4, 3, 5], [37, 6, 3, 7]] + 0.00126561580055304518 # B[874, [18, 4, 3, 5], [38, 6, 4, 6]] + -0.000556565865268397481 # B[875, [18, 4, 3, 5], [39, 6, 4, 8]] + -0.00527488386402661519 # B[876, [18, 4, 3, 5], [40, 6, 5, 7]] + -0.00214157468754809163 # B[877, [18, 4, 3, 5], [41, 6, 6, 6]] + -0.0020431148178264337 # B[878, [18, 4, 3, 5], [42, 6, 6, 8]] + 0.00142704628054338232 # B[879, [18, 4, 3, 5], [43, 7, 0, 7]] + 0.00368882624306161085 # B[880, [18, 4, 3, 5], [44, 7, 1, 8]] + -0.000742447358153045661 # B[881, [18, 4, 3, 5], [45, 7, 2, 7]] + -0.00158678830901623838 # B[882, [18, 4, 3, 5], [46, 7, 3, 8]] + -0.00107876302160130055 # B[883, [18, 4, 3, 5], [47, 7, 4, 7]] + -0.00701537311445033646 # B[884, [18, 4, 3, 5], [48, 7, 5, 8]] + -0.00184801443295596127 # B[885, [18, 4, 3, 5], [49, 7, 6, 7]] + -0.00127678697871524667 # B[886, [18, 4, 3, 5], [50, 7, 7, 8]] + 0.00105641109188138113 # B[887, [18, 4, 3, 5], [51, 8, 0, 8]] + 0.000718098622203026428 # B[888, [18, 4, 3, 5], [52, 8, 2, 8]] + 0.00219486004289275692 # B[889, [18, 4, 3, 5], [53, 8, 4, 8]] + -0.00158748993130468905 # B[890, [18, 4, 3, 5], [54, 8, 6, 8]] + -0.00105128398142791644 # B[891, [18, 4, 3, 5], [55, 8, 8, 8]] + -0.00705876763301777586 # B[892, [19, 4, 3, 7], [19, 4, 3, 7]] + 0.00377186011578763136 # B[893, [19, 4, 3, 7], [20, 4, 4, 4]] + 0.00351225097737749986 # B[894, [19, 4, 3, 7], [21, 4, 4, 6]] + -0.00323798036048509805 # B[895, [19, 4, 3, 7], [22, 4, 4, 8]] + 0.00126225430824061444 # B[896, [19, 4, 3, 7], [23, 5, 0, 5]] + -0.00132900767543010258 # B[897, [19, 4, 3, 7], [24, 5, 1, 6]] + 0.000212743875668733318 # B[898, [19, 4, 3, 7], [25, 5, 2, 5]] + -8.93559293989563963e-05 # B[899, [19, 4, 3, 7], [26, 5, 2, 7]] + 0.00401415269432878544 # B[900, [19, 4, 3, 7], [27, 5, 3, 6]] + -0.00422923196125859352 # B[901, [19, 4, 3, 7], [28, 5, 3, 8]] + 0.00252733635050122335 # B[902, [19, 4, 3, 7], [29, 5, 4, 5]] + -0.00020969110581340808 # B[903, [19, 4, 3, 7], [30, 5, 4, 7]] + -0.000969147769818896193 # B[904, [19, 4, 3, 7], [31, 5, 5, 6]] + -0.00249817386761041864 # B[905, [19, 4, 3, 7], [32, 5, 5, 8]] + 7.71120512828363247e-05 # B[906, [19, 4, 3, 7], [33, 6, 0, 6]] + 0.00560302176075209817 # B[907, [19, 4, 3, 7], [34, 6, 1, 7]] + 0.00342833731167378752 # B[908, [19, 4, 3, 7], [35, 6, 2, 6]] + 0.00116548365936076578 # B[909, [19, 4, 3, 7], [36, 6, 2, 8]] + 0.00499590856190199745 # B[910, [19, 4, 3, 7], [37, 6, 3, 7]] + 0.00391644837067879614 # B[911, [19, 4, 3, 7], [38, 6, 4, 6]] + 0.00116606811408420229 # B[912, [19, 4, 3, 7], [39, 6, 4, 8]] + -0.000563820914290556058 # B[913, [19, 4, 3, 7], [40, 6, 5, 7]] + -0.000251464925992161276 # B[914, [19, 4, 3, 7], [41, 6, 6, 6]] + -0.000718753250305587815 # B[915, [19, 4, 3, 7], [42, 6, 6, 8]] + 0.000453024387943248494 # B[916, [19, 4, 3, 7], [43, 7, 0, 7]] + -0.00146422451962339994 # B[917, [19, 4, 3, 7], [44, 7, 1, 8]] + 0.00271974781140060795 # B[918, [19, 4, 3, 7], [45, 7, 2, 7]] + 0.00151707017829591159 # B[919, [19, 4, 3, 7], [46, 7, 3, 8]] + 0.00202377896423465691 # B[920, [19, 4, 3, 7], [47, 7, 4, 7]] + -0.00131185948123999779 # B[921, [19, 4, 3, 7], [48, 7, 5, 8]] + 0.000239464941185672797 # B[922, [19, 4, 3, 7], [49, 7, 6, 7]] + -0.000667571478871501964 # B[923, [19, 4, 3, 7], [50, 7, 7, 8]] + 0.000666789360176615192 # B[924, [19, 4, 3, 7], [51, 8, 0, 8]] + 0.00179543252151156355 # B[925, [19, 4, 3, 7], [52, 8, 2, 8]] + 0.000954396542852647967 # B[926, [19, 4, 3, 7], [53, 8, 4, 8]] + 0.000593331439814590023 # B[927, [19, 4, 3, 7], [54, 8, 6, 8]] + -0.000292670120459602445 # B[928, [19, 4, 3, 7], [55, 8, 8, 8]] + -0.000303353861178074294 # B[929, [20, 4, 4, 4], [20, 4, 4, 4]] + -6.41585335468541906e-05 # B[930, [20, 4, 4, 4], [21, 4, 4, 6]] + 0.00145464895340288725 # B[931, [20, 4, 4, 4], [22, 4, 4, 8]] + 0.000557677559397141802 # B[932, [20, 4, 4, 4], [23, 5, 0, 5]] + 0.00214733001664968188 # B[933, [20, 4, 4, 4], [24, 5, 1, 6]] + 0.000196804226194771757 # B[934, [20, 4, 4, 4], [25, 5, 2, 5]] + 0.00169621771662652795 # B[935, [20, 4, 4, 4], [26, 5, 2, 7]] + -0.00126951106424718924 # B[936, [20, 4, 4, 4], [27, 5, 3, 6]] + 0.00156201190059711802 # B[937, [20, 4, 4, 4], [28, 5, 3, 8]] + -0.000188505112089858498 # B[938, [20, 4, 4, 4], [29, 5, 4, 5]] + 0.00101485096974841295 # B[939, [20, 4, 4, 4], [30, 5, 4, 7]] + -0.000254023094278113288 # B[940, [20, 4, 4, 4], [31, 5, 5, 6]] + -0.000332430225508446864 # B[941, [20, 4, 4, 4], [32, 5, 5, 8]] + 0.000393172799404761797 # B[942, [20, 4, 4, 4], [33, 6, 0, 6]] + -0.000945851456653874594 # B[943, [20, 4, 4, 4], [34, 6, 1, 7]] + 0.000937118523093692299 # B[944, [20, 4, 4, 4], [35, 6, 2, 6]] + 0.00108463610451345858 # B[945, [20, 4, 4, 4], [36, 6, 2, 8]] + -0.00167878968186336089 # B[946, [20, 4, 4, 4], [37, 6, 3, 7]] + 0.000109649976457827647 # B[947, [20, 4, 4, 4], [38, 6, 4, 6]] + 0.000205908523746248934 # B[948, [20, 4, 4, 4], [39, 6, 4, 8]] + -0.000952641271225448949 # B[949, [20, 4, 4, 4], [40, 6, 5, 7]] + -0.000386842165161269298 # B[950, [20, 4, 4, 4], [41, 6, 6, 6]] + -0.000662992329463731739 # B[951, [20, 4, 4, 4], [42, 6, 6, 8]] + 0.000368522676488847178 # B[952, [20, 4, 4, 4], [43, 7, 0, 7]] + -0.000181924614212486402 # B[953, [20, 4, 4, 4], [44, 7, 1, 8]] + -0.00119374010493299761 # B[954, [20, 4, 4, 4], [45, 7, 2, 7]] + -0.000775398926021152179 # B[955, [20, 4, 4, 4], [46, 7, 3, 8]] + -0.000670782103704289923 # B[956, [20, 4, 4, 4], [47, 7, 4, 7]] + -0.00192682764111087456 # B[957, [20, 4, 4, 4], [48, 7, 5, 8]] + -0.000648663865567958298 # B[958, [20, 4, 4, 4], [49, 7, 6, 7]] + -0.000387954189232417312 # B[959, [20, 4, 4, 4], [50, 7, 7, 8]] + 0.000302370648048068055 # B[960, [20, 4, 4, 4], [51, 8, 0, 8]] + -0.00085980088667597307 # B[961, [20, 4, 4, 4], [52, 8, 2, 8]] + 0.000568399123124077588 # B[962, [20, 4, 4, 4], [53, 8, 4, 8]] + -0.000482151590861096269 # B[963, [20, 4, 4, 4], [54, 8, 6, 8]] + -0.000405828455879983507 # B[964, [20, 4, 4, 4], [55, 8, 8, 8]] + 0.00165997230068267755 # B[965, [21, 4, 4, 6], [21, 4, 4, 6]] + 0.000963896255597472551 # B[966, [21, 4, 4, 6], [22, 4, 4, 8]] + 0.0002094521100325826 # B[967, [21, 4, 4, 6], [23, 5, 0, 5]] + 0.000534879644705995444 # B[968, [21, 4, 4, 6], [24, 5, 1, 6]] + 0.00292236533791157905 # B[969, [21, 4, 4, 6], [25, 5, 2, 5]] + 0.00151524368635043427 # B[970, [21, 4, 4, 6], [26, 5, 2, 7]] + -0.00101689007388491501 # B[971, [21, 4, 4, 6], [27, 5, 3, 6]] + 0.000738459806183821427 # B[972, [21, 4, 4, 6], [28, 5, 3, 8]] + 0.00148643764242684627 # B[973, [21, 4, 4, 6], [29, 5, 4, 5]] + 0.0011556877894129472 # B[974, [21, 4, 4, 6], [30, 5, 4, 7]] + -0.000208381440186615127 # B[975, [21, 4, 4, 6], [31, 5, 5, 6]] + -0.00143743030752817389 # B[976, [21, 4, 4, 6], [32, 5, 5, 8]] + -0.00016600302639456152 # B[977, [21, 4, 4, 6], [33, 6, 0, 6]] + 0.00172160125073629253 # B[978, [21, 4, 4, 6], [34, 6, 1, 7]] + 0.00344812165058533751 # B[979, [21, 4, 4, 6], [35, 6, 2, 6]] + 0.000544104512334869089 # B[980, [21, 4, 4, 6], [36, 6, 2, 8]] + -0.00182558144376257503 # B[981, [21, 4, 4, 6], [37, 6, 3, 7]] + 0.00101065848983370246 # B[982, [21, 4, 4, 6], [38, 6, 4, 6]] + 0.00103400096073465869 # B[983, [21, 4, 4, 6], [39, 6, 4, 8]] + -0.000235944095127582111 # B[984, [21, 4, 4, 6], [40, 6, 5, 7]] + 0.000154580830205655606 # B[985, [21, 4, 4, 6], [41, 6, 6, 6]] + -0.000488680460493023505 # B[986, [21, 4, 4, 6], [42, 6, 6, 8]] + 3.83739714257189113e-05 # B[987, [21, 4, 4, 6], [43, 7, 0, 7]] + -0.000275037336268196993 # B[988, [21, 4, 4, 6], [44, 7, 1, 8]] + 0.0017878021157122859 # B[989, [21, 4, 4, 6], [45, 7, 2, 7]] + -0.00110857713686632331 # B[990, [21, 4, 4, 6], [46, 7, 3, 8]] + -0.000126074852562767237 # B[991, [21, 4, 4, 6], [47, 7, 4, 7]] + -0.00125862858469075189 # B[992, [21, 4, 4, 6], [48, 7, 5, 8]] + -0.000277638160776805254 # B[993, [21, 4, 4, 6], [49, 7, 6, 7]] + 0.000163335859971639602 # B[994, [21, 4, 4, 6], [50, 7, 7, 8]] + 0.000151747507838979889 # B[995, [21, 4, 4, 6], [51, 8, 0, 8]] + 0.00156180455186682998 # B[996, [21, 4, 4, 6], [52, 8, 2, 8]] + 0.00112614353705531994 # B[997, [21, 4, 4, 6], [53, 8, 4, 8]] + -0.000376140365477903652 # B[998, [21, 4, 4, 6], [54, 8, 6, 8]] + -0.000378786757414536351 # B[999, [21, 4, 4, 6], [55, 8, 8, 8]] + -0.00186381195965971969 # B[1000, [22, 4, 4, 8], [22, 4, 4, 8]] + 0.000334060235611270684 # B[1001, [22, 4, 4, 8], [23, 5, 0, 5]] + -0.000182139490643212255 # B[1002, [22, 4, 4, 8], [24, 5, 1, 6]] + -0.000866414678376911532 # B[1003, [22, 4, 4, 8], [25, 5, 2, 5]] + -0.000713836573909394211 # B[1004, [22, 4, 4, 8], [26, 5, 2, 7]] + 0.00340359387460056721 # B[1005, [22, 4, 4, 8], [27, 5, 3, 6]] + -0.0025631762232975969 # B[1006, [22, 4, 4, 8], [28, 5, 3, 8]] + 0.00154837338005092001 # B[1007, [22, 4, 4, 8], [29, 5, 4, 5]] + -0.000713785025005329171 # B[1008, [22, 4, 4, 8], [30, 5, 4, 7]] + -6.17852167664190155e-06 # B[1009, [22, 4, 4, 8], [31, 5, 5, 6]] + -0.000925788250245492385 # B[1010, [22, 4, 4, 8], [32, 5, 5, 8]] + -0.000220618203180443506 # B[1011, [22, 4, 4, 8], [33, 6, 0, 6]] + 0.00158760304062654546 # B[1012, [22, 4, 4, 8], [34, 6, 1, 7]] + -0.00201296543384867077 # B[1013, [22, 4, 4, 8], [35, 6, 2, 6]] + -0.000153111573438037551 # B[1014, [22, 4, 4, 8], [36, 6, 2, 8]] + 0.001936342943994784 # B[1015, [22, 4, 4, 8], [37, 6, 3, 7]] + 0.0014724303902098404 # B[1016, [22, 4, 4, 8], [38, 6, 4, 6]] + 0.000412977919829218137 # B[1017, [22, 4, 4, 8], [39, 6, 4, 8]] + 0.000243129124011996767 # B[1018, [22, 4, 4, 8], [40, 6, 5, 7]] + 0.000433542078585167322 # B[1019, [22, 4, 4, 8], [41, 6, 6, 6]] + 5.87712210821707964e-05 # B[1020, [22, 4, 4, 8], [42, 6, 6, 8]] + -2.13873587015245281e-05 # B[1021, [22, 4, 4, 8], [43, 7, 0, 7]] + -0.00121671500578664389 # B[1022, [22, 4, 4, 8], [44, 7, 1, 8]] + 0.00185443425860575776 # B[1023, [22, 4, 4, 8], [45, 7, 2, 7]] + 0.00153976874095648406 # B[1024, [22, 4, 4, 8], [46, 7, 3, 8]] + 0.00100585852984078766 # B[1025, [22, 4, 4, 8], [47, 7, 4, 7]] + 0.000146502145157426621 # B[1026, [22, 4, 4, 8], [48, 7, 5, 8]] + 0.00026572798098887726 # B[1027, [22, 4, 4, 8], [49, 7, 6, 7]] + 0.000239744529446223043 # B[1028, [22, 4, 4, 8], [50, 7, 7, 8]] + 3.13331575558552233e-05 # B[1029, [22, 4, 4, 8], [51, 8, 0, 8]] + 0.0005761629631739415 # B[1030, [22, 4, 4, 8], [52, 8, 2, 8]] + 0.00020451472183747807 # B[1031, [22, 4, 4, 8], [53, 8, 4, 8]] + 0.000761501707699011737 # B[1032, [22, 4, 4, 8], [54, 8, 6, 8]] + 4.7608269104475881e-05 # B[1033, [22, 4, 4, 8], [55, 8, 8, 8]] + 0.00010288893231941848 # B[1034, [23, 5, 0, 5], [23, 5, 0, 5]] + -0.000598160679614365143 # B[1035, [23, 5, 0, 5], [24, 5, 1, 6]] + -0.000125600887517359969 # B[1036, [23, 5, 0, 5], [25, 5, 2, 5]] + -0.000541602347577959872 # B[1037, [23, 5, 0, 5], [26, 5, 2, 7]] + 0.000138742295315047448 # B[1038, [23, 5, 0, 5], [27, 5, 3, 6]] + 0.000320496112291311641 # B[1039, [23, 5, 0, 5], [28, 5, 3, 8]] + 9.77076363189860464e-05 # B[1040, [23, 5, 0, 5], [29, 5, 4, 5]] + -0.00018519393057754574 # B[1041, [23, 5, 0, 5], [30, 5, 4, 7]] + -0.000314308790209320843 # B[1042, [23, 5, 0, 5], [31, 5, 5, 6]] + -2.03507196530547385e-05 # B[1043, [23, 5, 0, 5], [32, 5, 5, 8]] + -8.76692912155085935e-08 # B[1044, [23, 5, 0, 5], [33, 6, 0, 6]] + -0.000208914241663854874 # B[1045, [23, 5, 0, 5], [34, 6, 1, 7]] + 0.000289191305925793653 # B[1046, [23, 5, 0, 5], [35, 6, 2, 6]] + 0.000292827060287376498 # B[1047, [23, 5, 0, 5], [36, 6, 2, 8]] + -0.000195999965143696386 # B[1048, [23, 5, 0, 5], [37, 6, 3, 7]] + 0.000122837407081860615 # B[1049, [23, 5, 0, 5], [38, 6, 4, 6]] + 0.000238061673948679331 # B[1050, [23, 5, 0, 5], [39, 6, 4, 8]] + 6.23458911314621333e-06 # B[1051, [23, 5, 0, 5], [40, 6, 5, 7]] + 0.000153645644536796327 # B[1052, [23, 5, 0, 5], [41, 6, 6, 6]] + 0.000208144485879115104 # B[1053, [23, 5, 0, 5], [42, 6, 6, 8]] + 0.000107382317423423967 # B[1054, [23, 5, 0, 5], [43, 7, 0, 7]] + -3.16437877474207152e-05 # B[1055, [23, 5, 0, 5], [44, 7, 1, 8]] + 5.2567890411161361e-05 # B[1056, [23, 5, 0, 5], [45, 7, 2, 7]] + -0.000407365287815795313 # B[1057, [23, 5, 0, 5], [46, 7, 3, 8]] + -0.000277007442936893014 # B[1058, [23, 5, 0, 5], [47, 7, 4, 7]] + -0.000163960409271388802 # B[1059, [23, 5, 0, 5], [48, 7, 5, 8]] + -0.00018222236229294142 # B[1060, [23, 5, 0, 5], [49, 7, 6, 7]] + -8.93725149996096868e-05 # B[1061, [23, 5, 0, 5], [50, 7, 7, 8]] + -4.59835267753172516e-05 # B[1062, [23, 5, 0, 5], [51, 8, 0, 8]] + -3.00980967951527262e-05 # B[1063, [23, 5, 0, 5], [52, 8, 2, 8]] + -0.00011786089545340328 # B[1064, [23, 5, 0, 5], [53, 8, 4, 8]] + 6.24840877215676604e-05 # B[1065, [23, 5, 0, 5], [54, 8, 6, 8]] + 0.000151333518371397913 # B[1066, [23, 5, 0, 5], [55, 8, 8, 8]] + -0.00373509601310103353 # B[1067, [24, 5, 1, 6], [24, 5, 1, 6]] + 0.00250350668234289742 # B[1068, [24, 5, 1, 6], [25, 5, 2, 5]] + -0.00141763987470412255 # B[1069, [24, 5, 1, 6], [26, 5, 2, 7]] + -0.000458490741576836162 # B[1070, [24, 5, 1, 6], [27, 5, 3, 6]] + 0.000169432811229417585 # B[1071, [24, 5, 1, 6], [28, 5, 3, 8]] + -0.000531768848310092699 # B[1072, [24, 5, 1, 6], [29, 5, 4, 5]] + 0.0019269207337581605 # B[1073, [24, 5, 1, 6], [30, 5, 4, 7]] + 0.000623468915929115824 # B[1074, [24, 5, 1, 6], [31, 5, 5, 6]] + 0.000262459747020924762 # B[1075, [24, 5, 1, 6], [32, 5, 5, 8]] + 0.000319464830252011445 # B[1076, [24, 5, 1, 6], [33, 6, 0, 6]] + 0.00250974732963905444 # B[1077, [24, 5, 1, 6], [34, 6, 1, 7]] + 0.00423653007687384807 # B[1078, [24, 5, 1, 6], [35, 6, 2, 6]] + 0.00144771358428595707 # B[1079, [24, 5, 1, 6], [36, 6, 2, 8]] + 0.00255496505633429419 # B[1080, [24, 5, 1, 6], [37, 6, 3, 7]] + -0.000923899857380450218 # B[1081, [24, 5, 1, 6], [38, 6, 4, 6]] + -0.000308666389289608337 # B[1082, [24, 5, 1, 6], [39, 6, 4, 8]] + 0.00222537659577300671 # B[1083, [24, 5, 1, 6], [40, 6, 5, 7]] + -0.00107541311587263343 # B[1084, [24, 5, 1, 6], [41, 6, 6, 6]] + -0.00278767944085371068 # B[1085, [24, 5, 1, 6], [42, 6, 6, 8]] + -0.000867530969177243705 # B[1086, [24, 5, 1, 6], [43, 7, 0, 7]] + 0.00357297895621819196 # B[1087, [24, 5, 1, 6], [44, 7, 1, 8]] + 0.00383976572090019216 # B[1088, [24, 5, 1, 6], [45, 7, 2, 7]] + -0.000580234942856992786 # B[1089, [24, 5, 1, 6], [46, 7, 3, 8]] + 0.00102888910081111798 # B[1090, [24, 5, 1, 6], [47, 7, 4, 7]] + 0.00132107614311613355 # B[1091, [24, 5, 1, 6], [48, 7, 5, 8]] + 0.00101848252621374036 # B[1092, [24, 5, 1, 6], [49, 7, 6, 7]] + 0.00160018234143227862 # B[1093, [24, 5, 1, 6], [50, 7, 7, 8]] + -5.52824024903572631e-05 # B[1094, [24, 5, 1, 6], [51, 8, 0, 8]] + 4.59186780197786033e-05 # B[1095, [24, 5, 1, 6], [52, 8, 2, 8]] + -0.000153436254581188554 # B[1096, [24, 5, 1, 6], [53, 8, 4, 8]] + -0.000546750998621967597 # B[1097, [24, 5, 1, 6], [54, 8, 6, 8]] + 0.000595956738118895348 # B[1098, [24, 5, 1, 6], [55, 8, 8, 8]] + 0.0083807047595118693 # B[1099, [25, 5, 2, 5], [25, 5, 2, 5]] + -0.000170544318645505719 # B[1100, [25, 5, 2, 5], [26, 5, 2, 7]] + 0.00235544441902155004 # B[1101, [25, 5, 2, 5], [27, 5, 3, 6]] + -0.00340197827063909962 # B[1102, [25, 5, 2, 5], [28, 5, 3, 8]] + 0.00311335525578198104 # B[1103, [25, 5, 2, 5], [29, 5, 4, 5]] + 0.00185214714164834123 # B[1104, [25, 5, 2, 5], [30, 5, 4, 7]] + -0.00328905913600528992 # B[1105, [25, 5, 2, 5], [31, 5, 5, 6]] + -0.00141866010082636025 # B[1106, [25, 5, 2, 5], [32, 5, 5, 8]] + 0.000176317033907393006 # B[1107, [25, 5, 2, 5], [33, 6, 0, 6]] + 0.00648328973805229608 # B[1108, [25, 5, 2, 5], [34, 6, 1, 7]] + 4.8980528358618259e-05 # B[1109, [25, 5, 2, 5], [35, 6, 2, 6]] + -0.00616971046300731144 # B[1110, [25, 5, 2, 5], [36, 6, 2, 8]] + -0.00135942372726050205 # B[1111, [25, 5, 2, 5], [37, 6, 3, 7]] + 0.000572735024796908881 # B[1112, [25, 5, 2, 5], [38, 6, 4, 6]] + -0.00229752149848994405 # B[1113, [25, 5, 2, 5], [39, 6, 4, 8]] + 0.0003485310815041524 # B[1114, [25, 5, 2, 5], [40, 6, 5, 7]] + -0.0011437361439647427 # B[1115, [25, 5, 2, 5], [41, 6, 6, 6]] + -0.000604819873822432311 # B[1116, [25, 5, 2, 5], [42, 6, 6, 8]] + 9.06237770597643696e-05 # B[1117, [25, 5, 2, 5], [43, 7, 0, 7]] + -0.000382141545017884894 # B[1118, [25, 5, 2, 5], [44, 7, 1, 8]] + -0.000842464094047663554 # B[1119, [25, 5, 2, 5], [45, 7, 2, 7]] + 0.000461973830441065811 # B[1120, [25, 5, 2, 5], [46, 7, 3, 8]] + 2.86192620363814355e-06 # B[1121, [25, 5, 2, 5], [47, 7, 4, 7]] + -0.0023436531447123838 # B[1122, [25, 5, 2, 5], [48, 7, 5, 8]] + 0.00134025173860287308 # B[1123, [25, 5, 2, 5], [49, 7, 6, 7]] + -0.000520013981518205846 # B[1124, [25, 5, 2, 5], [50, 7, 7, 8]] + 0.000515782740310496285 # B[1125, [25, 5, 2, 5], [51, 8, 0, 8]] + 0.00421651313615256564 # B[1126, [25, 5, 2, 5], [52, 8, 2, 8]] + 0.000755327719218409519 # B[1127, [25, 5, 2, 5], [53, 8, 4, 8]] + 0.000182937308412391315 # B[1128, [25, 5, 2, 5], [54, 8, 6, 8]] + 8.10383680097163071e-05 # B[1129, [25, 5, 2, 5], [55, 8, 8, 8]] + 0.000177735296666065024 # B[1130, [26, 5, 2, 7], [26, 5, 2, 7]] + -0.000642334677407747565 # B[1131, [26, 5, 2, 7], [27, 5, 3, 6]] + 0.000205172894139061396 # B[1132, [26, 5, 2, 7], [28, 5, 3, 8]] + -0.000537004220752698019 # B[1133, [26, 5, 2, 7], [29, 5, 4, 5]] + 5.14115941491347442e-05 # B[1134, [26, 5, 2, 7], [30, 5, 4, 7]] + 0.000417673445165051005 # B[1135, [26, 5, 2, 7], [31, 5, 5, 6]] + 0.00158446769775330391 # B[1136, [26, 5, 2, 7], [32, 5, 5, 8]] + 0.00121383407410429606 # B[1137, [26, 5, 2, 7], [33, 6, 0, 6]] + -0.00111992976945914785 # B[1138, [26, 5, 2, 7], [34, 6, 1, 7]] + 0.00398972286341117699 # B[1139, [26, 5, 2, 7], [35, 6, 2, 6]] + 0.00454565411209783762 # B[1140, [26, 5, 2, 7], [36, 6, 2, 8]] + -0.00300928796618537761 # B[1141, [26, 5, 2, 7], [37, 6, 3, 7]] + -0.00280024702462813163 # B[1142, [26, 5, 2, 7], [38, 6, 4, 6]] + 0.00182097597359056305 # B[1143, [26, 5, 2, 7], [39, 6, 4, 8]] + 0.00247143387165752772 # B[1144, [26, 5, 2, 7], [40, 6, 5, 7]] + -0.00143698477566456435 # B[1145, [26, 5, 2, 7], [41, 6, 6, 6]] + -0.00105878554545993375 # B[1146, [26, 5, 2, 7], [42, 6, 6, 8]] + 0.000650619036842032747 # B[1147, [26, 5, 2, 7], [43, 7, 0, 7]] + 8.72947879012740853e-05 # B[1148, [26, 5, 2, 7], [44, 7, 1, 8]] + -0.0002084941102769855 # B[1149, [26, 5, 2, 7], [45, 7, 2, 7]] + -0.000924608969529588931 # B[1150, [26, 5, 2, 7], [46, 7, 3, 8]] + -0.000320719808114693777 # B[1151, [26, 5, 2, 7], [47, 7, 4, 7]] + 0.00241998856780361801 # B[1152, [26, 5, 2, 7], [48, 7, 5, 8]] + -0.00171923440812344827 # B[1153, [26, 5, 2, 7], [49, 7, 6, 7]] + -0.000301390241580377569 # B[1154, [26, 5, 2, 7], [50, 7, 7, 8]] + -6.37461557401481499e-05 # B[1155, [26, 5, 2, 7], [51, 8, 0, 8]] + 0.00161644303684405446 # B[1156, [26, 5, 2, 7], [52, 8, 2, 8]] + 0.00104379414920739667 # B[1157, [26, 5, 2, 7], [53, 8, 4, 8]] + -0.00119795702190159808 # B[1158, [26, 5, 2, 7], [54, 8, 6, 8]] + 0.000604059138156293803 # B[1159, [26, 5, 2, 7], [55, 8, 8, 8]] + 0.000513459633959805622 # B[1160, [27, 5, 3, 6], [27, 5, 3, 6]] + -0.000172334638360790993 # B[1161, [27, 5, 3, 6], [28, 5, 3, 8]] + 1.60719061511648345e-05 # B[1162, [27, 5, 3, 6], [29, 5, 4, 5]] + 0.00440279299288983371 # B[1163, [27, 5, 3, 6], [30, 5, 4, 7]] + 0.000549761981236742206 # B[1164, [27, 5, 3, 6], [31, 5, 5, 6]] + 0.000424619689378998542 # B[1165, [27, 5, 3, 6], [32, 5, 5, 8]] + 0.000247367934895610653 # B[1166, [27, 5, 3, 6], [33, 6, 0, 6]] + 0.00400569055534595944 # B[1167, [27, 5, 3, 6], [34, 6, 1, 7]] + 0.00274378194299987679 # B[1168, [27, 5, 3, 6], [35, 6, 2, 6]] + 0.00368141326251353665 # B[1169, [27, 5, 3, 6], [36, 6, 2, 8]] + 0.00160469169395054817 # B[1170, [27, 5, 3, 6], [37, 6, 3, 7]] + 0.000105807739550402985 # B[1171, [27, 5, 3, 6], [38, 6, 4, 6]] + -0.000682801438033796976 # B[1172, [27, 5, 3, 6], [39, 6, 4, 8]] + -0.00121964915110857504 # B[1173, [27, 5, 3, 6], [40, 6, 5, 7]] + -0.000817665263990522556 # B[1174, [27, 5, 3, 6], [41, 6, 6, 6]] + 0.000534593784435832137 # B[1175, [27, 5, 3, 6], [42, 6, 6, 8]] + 0.000116542343021167755 # B[1176, [27, 5, 3, 6], [43, 7, 0, 7]] + 0.00351267154418699948 # B[1177, [27, 5, 3, 6], [44, 7, 1, 8]] + -0.00189934642995405814 # B[1178, [27, 5, 3, 6], [45, 7, 2, 7]] + 0.000751906974843792597 # B[1179, [27, 5, 3, 6], [46, 7, 3, 8]] + -0.000446808189773967301 # B[1180, [27, 5, 3, 6], [47, 7, 4, 7]] + -0.00324699511848197502 # B[1181, [27, 5, 3, 6], [48, 7, 5, 8]] + 2.53540837371335481e-05 # B[1182, [27, 5, 3, 6], [49, 7, 6, 7]] + 7.5273388360289073e-07 # B[1183, [27, 5, 3, 6], [50, 7, 7, 8]] + 0.00023346363571073725 # B[1184, [27, 5, 3, 6], [51, 8, 0, 8]] + 0.000490008984593369619 # B[1185, [27, 5, 3, 6], [52, 8, 2, 8]] + 0.000205260233742234413 # B[1186, [27, 5, 3, 6], [53, 8, 4, 8]] + -7.84984665939646165e-05 # B[1187, [27, 5, 3, 6], [54, 8, 6, 8]] + -0.000299454037036409743 # B[1188, [27, 5, 3, 6], [55, 8, 8, 8]] + -0.00411961786705090406 # B[1189, [28, 5, 3, 8], [28, 5, 3, 8]] + 0.00256764268592788759 # B[1190, [28, 5, 3, 8], [29, 5, 4, 5]] + -0.000267820435572239945 # B[1191, [28, 5, 3, 8], [30, 5, 4, 7]] + 0.000545048575291992229 # B[1192, [28, 5, 3, 8], [31, 5, 5, 6]] + -0.000141236037433873154 # B[1193, [28, 5, 3, 8], [32, 5, 5, 8]] + -8.17647193563642016e-05 # B[1194, [28, 5, 3, 8], [33, 6, 0, 6]] + 0.00184594470809960887 # B[1195, [28, 5, 3, 8], [34, 6, 1, 7]] + 0.000715653691449843685 # B[1196, [28, 5, 3, 8], [35, 6, 2, 6]] + -0.000371782729873919304 # B[1197, [28, 5, 3, 8], [36, 6, 2, 8]] + 0.00184451560473704312 # B[1198, [28, 5, 3, 8], [37, 6, 3, 7]] + 0.00298992898894900189 # B[1199, [28, 5, 3, 8], [38, 6, 4, 6]] + 0.00087474408278464047 # B[1200, [28, 5, 3, 8], [39, 6, 4, 8]] + 0.00115889056554823421 # B[1201, [28, 5, 3, 8], [40, 6, 5, 7]] + -0.000209440071593354482 # B[1202, [28, 5, 3, 8], [41, 6, 6, 6]] + 0.000707847416081031772 # B[1203, [28, 5, 3, 8], [42, 6, 6, 8]] + 0.00025922895119332573 # B[1204, [28, 5, 3, 8], [43, 7, 0, 7]] + -0.00210744601505012327 # B[1205, [28, 5, 3, 8], [44, 7, 1, 8]] + -0.00187401632149015486 # B[1206, [28, 5, 3, 8], [45, 7, 2, 7]] + 0.000616682247583759391 # B[1207, [28, 5, 3, 8], [46, 7, 3, 8]] + 0.00142526179781785924 # B[1208, [28, 5, 3, 8], [47, 7, 4, 7]] + -9.1619163886703936e-06 # B[1209, [28, 5, 3, 8], [48, 7, 5, 8]] + -0.000300978843055903222 # B[1210, [28, 5, 3, 8], [49, 7, 6, 7]] + -0.000124034381208077554 # B[1211, [28, 5, 3, 8], [50, 7, 7, 8]] + 0.000249158311162858692 # B[1212, [28, 5, 3, 8], [51, 8, 0, 8]] + -0.000970252220622513538 # B[1213, [28, 5, 3, 8], [52, 8, 2, 8]] + 0.000840312328335843066 # B[1214, [28, 5, 3, 8], [53, 8, 4, 8]] + 0.000145361901756495965 # B[1215, [28, 5, 3, 8], [54, 8, 6, 8]] + 0.00013163551986085896 # B[1216, [28, 5, 3, 8], [55, 8, 8, 8]] + 0.00265810885844912576 # B[1217, [29, 5, 4, 5], [29, 5, 4, 5]] + 0.00191793603428468823 # B[1218, [29, 5, 4, 5], [30, 5, 4, 7]] + 0.000446118694394436605 # B[1219, [29, 5, 4, 5], [31, 5, 5, 6]] + -9.59445098255573559e-05 # B[1220, [29, 5, 4, 5], [32, 5, 5, 8]] + 0.000369255428727587043 # B[1221, [29, 5, 4, 5], [33, 6, 0, 6]] + -0.000553149628059141762 # B[1222, [29, 5, 4, 5], [34, 6, 1, 7]] + 0.00315275275750991242 # B[1223, [29, 5, 4, 5], [35, 6, 2, 6]] + 0.00138540352181828336 # B[1224, [29, 5, 4, 5], [36, 6, 2, 8]] + 0.000776256233303879162 # B[1225, [29, 5, 4, 5], [37, 6, 3, 7]] + 0.000594477884906325672 # B[1226, [29, 5, 4, 5], [38, 6, 4, 6]] + 0.000757712543509288586 # B[1227, [29, 5, 4, 5], [39, 6, 4, 8]] + -0.000917903532807641184 # B[1228, [29, 5, 4, 5], [40, 6, 5, 7]] + -0.000915313398456763742 # B[1229, [29, 5, 4, 5], [41, 6, 6, 6]] + -0.00116732293566375843 # B[1230, [29, 5, 4, 5], [42, 6, 6, 8]] + 0.000172432189541951719 # B[1231, [29, 5, 4, 5], [43, 7, 0, 7]] + 0.000845370011774060912 # B[1232, [29, 5, 4, 5], [44, 7, 1, 8]] + 0.00178029205661471915 # B[1233, [29, 5, 4, 5], [45, 7, 2, 7]] + 0.00129739636685697463 # B[1234, [29, 5, 4, 5], [46, 7, 3, 8]] + 0.000282865369400489564 # B[1235, [29, 5, 4, 5], [47, 7, 4, 7]] + -0.00178988233479955398 # B[1236, [29, 5, 4, 5], [48, 7, 5, 8]] + 0.00023603474784275949 # B[1237, [29, 5, 4, 5], [49, 7, 6, 7]] + -0.000461436431325358207 # B[1238, [29, 5, 4, 5], [50, 7, 7, 8]] + 0.000234131705926524103 # B[1239, [29, 5, 4, 5], [51, 8, 0, 8]] + 0.00216254821351878363 # B[1240, [29, 5, 4, 5], [52, 8, 2, 8]] + 0.000831658742681578439 # B[1241, [29, 5, 4, 5], [53, 8, 4, 8]] + -0.00046318901257626742 # B[1242, [29, 5, 4, 5], [54, 8, 6, 8]] + -0.000607580535321294163 # B[1243, [29, 5, 4, 5], [55, 8, 8, 8]] + 0.00158347719827001653 # B[1244, [30, 5, 4, 7], [30, 5, 4, 7]] + 0.00120733638068271261 # B[1245, [30, 5, 4, 7], [31, 5, 5, 6]] + -0.000191610125195333311 # B[1246, [30, 5, 4, 7], [32, 5, 5, 8]] + -0.000363280761575070915 # B[1247, [30, 5, 4, 7], [33, 6, 0, 6]] + 0.0015080393447339897 # B[1248, [30, 5, 4, 7], [34, 6, 1, 7]] + 0.00144737958774105498 # B[1249, [30, 5, 4, 7], [35, 6, 2, 6]] + -0.000191256340607337365 # B[1250, [30, 5, 4, 7], [36, 6, 2, 8]] + 0.00324542123326504103 # B[1251, [30, 5, 4, 7], [37, 6, 3, 7]] + 0.00135369467391198949 # B[1252, [30, 5, 4, 7], [38, 6, 4, 6]] + 0.00077393986417062131 # B[1253, [30, 5, 4, 7], [39, 6, 4, 8]] + 0.00187057819081324836 # B[1254, [30, 5, 4, 7], [40, 6, 5, 7]] + 4.06728949024891956e-05 # B[1255, [30, 5, 4, 7], [41, 6, 6, 6]] + -0.000100060243024913467 # B[1256, [30, 5, 4, 7], [42, 6, 6, 8]] + -0.000170624797097965186 # B[1257, [30, 5, 4, 7], [43, 7, 0, 7]] + -0.00157200294852092963 # B[1258, [30, 5, 4, 7], [44, 7, 1, 8]] + -5.099465391029262e-05 # B[1259, [30, 5, 4, 7], [45, 7, 2, 7]] + 0.00166973065524506255 # B[1260, [30, 5, 4, 7], [46, 7, 3, 8]] + 0.000976468235486894175 # B[1261, [30, 5, 4, 7], [47, 7, 4, 7]] + -0.000570830124590235299 # B[1262, [30, 5, 4, 7], [48, 7, 5, 8]] + 0.000667250794893839427 # B[1263, [30, 5, 4, 7], [49, 7, 6, 7]] + -0.000273376565753529832 # B[1264, [30, 5, 4, 7], [50, 7, 7, 8]] + 0.000206233716860107844 # B[1265, [30, 5, 4, 7], [51, 8, 0, 8]] + 0.00260342927157033218 # B[1266, [30, 5, 4, 7], [52, 8, 2, 8]] + 0.000943954042545826558 # B[1267, [30, 5, 4, 7], [53, 8, 4, 8]] + -0.00022781927635321525 # B[1268, [30, 5, 4, 7], [54, 8, 6, 8]] + -0.000448456045604168733 # B[1269, [30, 5, 4, 7], [55, 8, 8, 8]] + 0.00102985782764508475 # B[1270, [31, 5, 5, 6], [31, 5, 5, 6]] + -8.89908688742153606e-05 # B[1271, [31, 5, 5, 6], [32, 5, 5, 8]] + -0.000162481274467801695 # B[1272, [31, 5, 5, 6], [33, 6, 0, 6]] + 0.00263772603538907271 # B[1273, [31, 5, 5, 6], [34, 6, 1, 7]] + -0.00223528099165903275 # B[1274, [31, 5, 5, 6], [35, 6, 2, 6]] + 0.000441657599119526373 # B[1275, [31, 5, 5, 6], [36, 6, 2, 8]] + 0.00165514785004864176 # B[1276, [31, 5, 5, 6], [37, 6, 3, 7]] + 0.000898928585103351413 # B[1277, [31, 5, 5, 6], [38, 6, 4, 6]] + -0.00026071204606309753 # B[1278, [31, 5, 5, 6], [39, 6, 4, 8]] + -0.000251612913047311385 # B[1279, [31, 5, 5, 6], [40, 6, 5, 7]] + -0.00022773870089292346 # B[1280, [31, 5, 5, 6], [41, 6, 6, 6]] + -0.000449951686975022525 # B[1281, [31, 5, 5, 6], [42, 6, 6, 8]] + -0.000252400784021909741 # B[1282, [31, 5, 5, 6], [43, 7, 0, 7]] + 0.000574433272355396977 # B[1283, [31, 5, 5, 6], [44, 7, 1, 8]] + -0.0014040949400035245 # B[1284, [31, 5, 5, 6], [45, 7, 2, 7]] + 0.00124516802775002586 # B[1285, [31, 5, 5, 6], [46, 7, 3, 8]] + 0.000875572292146320832 # B[1286, [31, 5, 5, 6], [47, 7, 4, 7]] + -0.000509730931921630048 # B[1287, [31, 5, 5, 6], [48, 7, 5, 8]] + 0.000422266146488117777 # B[1288, [31, 5, 5, 6], [49, 7, 6, 7]] + -0.000239146684560266956 # B[1289, [31, 5, 5, 6], [50, 7, 7, 8]] + 9.95899703990707486e-05 # B[1290, [31, 5, 5, 6], [51, 8, 0, 8]] + -0.0020784147827535588 # B[1291, [31, 5, 5, 6], [52, 8, 2, 8]] + 0.000735684723224858811 # B[1292, [31, 5, 5, 6], [53, 8, 4, 8]] + -0.000248804810033285279 # B[1293, [31, 5, 5, 6], [54, 8, 6, 8]] + -0.000598263607047986451 # B[1294, [31, 5, 5, 6], [55, 8, 8, 8]] + 0.000131065920905359436 # B[1295, [32, 5, 5, 8], [32, 5, 5, 8]] + 0.000100196796943449913 # B[1296, [32, 5, 5, 8], [33, 6, 0, 6]] + -0.00173991171955805834 # B[1297, [32, 5, 5, 8], [34, 6, 1, 7]] + -0.000490539010579770906 # B[1298, [32, 5, 5, 8], [35, 6, 2, 6]] + 0.000676191083650941674 # B[1299, [32, 5, 5, 8], [36, 6, 2, 8]] + 0.000446932761165407325 # B[1300, [32, 5, 5, 8], [37, 6, 3, 7]] + -0.000153107558622965576 # B[1301, [32, 5, 5, 8], [38, 6, 4, 6]] + 1.67752859932734574e-05 # B[1302, [32, 5, 5, 8], [39, 6, 4, 8]] + 0.000215146896189506113 # B[1303, [32, 5, 5, 8], [40, 6, 5, 7]] + -0.000188466441880926362 # B[1304, [32, 5, 5, 8], [41, 6, 6, 6]] + -4.80917708388720055e-06 # B[1305, [32, 5, 5, 8], [42, 6, 6, 8]] + -5.04429979448911547e-05 # B[1306, [32, 5, 5, 8], [43, 7, 0, 7]] + -0.000494944862407609067 # B[1307, [32, 5, 5, 8], [44, 7, 1, 8]] + -0.000424473825928651724 # B[1308, [32, 5, 5, 8], [45, 7, 2, 7]] + 0.000417544384337296959 # B[1309, [32, 5, 5, 8], [46, 7, 3, 8]] + 0.000431586591455488614 # B[1310, [32, 5, 5, 8], [47, 7, 4, 7]] + 0.000187341827588022357 # B[1311, [32, 5, 5, 8], [48, 7, 5, 8]] + -6.87669988055673864e-05 # B[1312, [32, 5, 5, 8], [49, 7, 6, 7]] + 0.000147867669408649482 # B[1313, [32, 5, 5, 8], [50, 7, 7, 8]] + -7.32201679551347517e-06 # B[1314, [32, 5, 5, 8], [51, 8, 0, 8]] + -0.000392519615947300787 # B[1315, [32, 5, 5, 8], [52, 8, 2, 8]] + 8.78465325612771269e-05 # B[1316, [32, 5, 5, 8], [53, 8, 4, 8]] + -6.3960070015590606e-05 # B[1317, [32, 5, 5, 8], [54, 8, 6, 8]] + -7.97839909379757101e-06 # B[1318, [32, 5, 5, 8], [55, 8, 8, 8]] + 3.95695067041609838e-05 # B[1319, [33, 6, 0, 6], [33, 6, 0, 6]] + -0.000611658005184461534 # B[1320, [33, 6, 0, 6], [34, 6, 1, 7]] + -0.000277914808470863806 # B[1321, [33, 6, 0, 6], [35, 6, 2, 6]] + 0.000987938388973043716 # B[1322, [33, 6, 0, 6], [36, 6, 2, 8]] + 0.000198558948919527745 # B[1323, [33, 6, 0, 6], [37, 6, 3, 7]] + 9.76274805398642809e-05 # B[1324, [33, 6, 0, 6], [38, 6, 4, 6]] + 9.92197766131464043e-05 # B[1325, [33, 6, 0, 6], [39, 6, 4, 8]] + -4.16996931875308896e-05 # B[1326, [33, 6, 0, 6], [40, 6, 5, 7]] + -5.3495059095630057e-05 # B[1327, [33, 6, 0, 6], [41, 6, 6, 6]] + 1.0720822351671655e-05 # B[1328, [33, 6, 0, 6], [42, 6, 6, 8]] + 0.000114464898537391946 # B[1329, [33, 6, 0, 6], [43, 7, 0, 7]] + -0.00033593422820483651 # B[1330, [33, 6, 0, 6], [44, 7, 1, 8]] + -0.00061665800523461739 # B[1331, [33, 6, 0, 6], [45, 7, 2, 7]] + -0.000258302532232180387 # B[1332, [33, 6, 0, 6], [46, 7, 3, 8]] + 3.78181072490033077e-05 # B[1333, [33, 6, 0, 6], [47, 7, 4, 7]] + -0.000326273283142861775 # B[1334, [33, 6, 0, 6], [48, 7, 5, 8]] + 1.74277156155672186e-05 # B[1335, [33, 6, 0, 6], [49, 7, 6, 7]] + -0.000206600107910874173 # B[1336, [33, 6, 0, 6], [50, 7, 7, 8]] + 2.12855018918572947e-05 # B[1337, [33, 6, 0, 6], [51, 8, 0, 8]] + -0.000696835386532819456 # B[1338, [33, 6, 0, 6], [52, 8, 2, 8]] + 8.06841007746916805e-05 # B[1339, [33, 6, 0, 6], [53, 8, 4, 8]] + 1.96129469472779844e-05 # B[1340, [33, 6, 0, 6], [54, 8, 6, 8]] + 7.35114191380559223e-05 # B[1341, [33, 6, 0, 6], [55, 8, 8, 8]] + 0.00360109138862139185 # B[1342, [34, 6, 1, 7], [34, 6, 1, 7]] + 0.00304872474261531218 # B[1343, [34, 6, 1, 7], [35, 6, 2, 6]] + -0.00546316824530662139 # B[1344, [34, 6, 1, 7], [36, 6, 2, 8]] + 0.000721988419001898946 # B[1345, [34, 6, 1, 7], [37, 6, 3, 7]] + -0.00254968694435141717 # B[1346, [34, 6, 1, 7], [38, 6, 4, 6]] + -0.00102187793811427596 # B[1347, [34, 6, 1, 7], [39, 6, 4, 8]] + 0.000977866285507509106 # B[1348, [34, 6, 1, 7], [40, 6, 5, 7]] + 0.00129156024637028417 # B[1349, [34, 6, 1, 7], [41, 6, 6, 6]] + 8.43980229575398005e-05 # B[1350, [34, 6, 1, 7], [42, 6, 6, 8]] + -0.000854491821273548058 # B[1351, [34, 6, 1, 7], [43, 7, 0, 7]] + -0.00229655360277009144 # B[1352, [34, 6, 1, 7], [44, 7, 1, 8]] + 0.00392740594657482126 # B[1353, [34, 6, 1, 7], [45, 7, 2, 7]] + 0.00282086313880587115 # B[1354, [34, 6, 1, 7], [46, 7, 3, 8]] + -0.00269367822401865922 # B[1355, [34, 6, 1, 7], [47, 7, 4, 7]] + 0.00120544917432826269 # B[1356, [34, 6, 1, 7], [48, 7, 5, 8]] + 0.00137213082032611872 # B[1357, [34, 6, 1, 7], [49, 7, 6, 7]] + 0.00278774897747785522 # B[1358, [34, 6, 1, 7], [50, 7, 7, 8]] + -1.00075929411755707e-05 # B[1359, [34, 6, 1, 7], [51, 8, 0, 8]] + 0.00331402709384703321 # B[1360, [34, 6, 1, 7], [52, 8, 2, 8]] + -0.00220016465090739841 # B[1361, [34, 6, 1, 7], [53, 8, 4, 8]] + 0.000794479619849004434 # B[1362, [34, 6, 1, 7], [54, 8, 6, 8]] + 0.000207117210070053084 # B[1363, [34, 6, 1, 7], [55, 8, 8, 8]] + 0.000547206364960122621 # B[1364, [35, 6, 2, 6], [35, 6, 2, 6]] + 0.00243529980905243717 # B[1365, [35, 6, 2, 6], [36, 6, 2, 8]] + 0.000346076245330416421 # B[1366, [35, 6, 2, 6], [37, 6, 3, 7]] + 0.00220550296989585788 # B[1367, [35, 6, 2, 6], [38, 6, 4, 6]] + 0.00101934408216735467 # B[1368, [35, 6, 2, 6], [39, 6, 4, 8]] + 6.76995447894471192e-05 # B[1369, [35, 6, 2, 6], [40, 6, 5, 7]] + -4.61734905116591154e-05 # B[1370, [35, 6, 2, 6], [41, 6, 6, 6]] + 0.000809543629624515093 # B[1371, [35, 6, 2, 6], [42, 6, 6, 8]] + 0.000219078295465409238 # B[1372, [35, 6, 2, 6], [43, 7, 0, 7]] + -0.00316872925249137884 # B[1373, [35, 6, 2, 6], [44, 7, 1, 8]] + 0.000676713636760976206 # B[1374, [35, 6, 2, 6], [45, 7, 2, 7]] + -0.00100477918211841141 # B[1375, [35, 6, 2, 6], [46, 7, 3, 8]] + 0.000400524978896980161 # B[1376, [35, 6, 2, 6], [47, 7, 4, 7]] + -0.00197634098305848622 # B[1377, [35, 6, 2, 6], [48, 7, 5, 8]] + 0.000367979983554051621 # B[1378, [35, 6, 2, 6], [49, 7, 6, 7]] + -0.00126672502130457942 # B[1379, [35, 6, 2, 6], [50, 7, 7, 8]] + 0.000161373464169148675 # B[1380, [35, 6, 2, 6], [51, 8, 0, 8]] + 0.00258770627559228462 # B[1381, [35, 6, 2, 6], [52, 8, 2, 8]] + 0.000816135012742828661 # B[1382, [35, 6, 2, 6], [53, 8, 4, 8]] + -3.28991122771973843e-05 # B[1383, [35, 6, 2, 6], [54, 8, 6, 8]] + -4.18127338362338707e-05 # B[1384, [35, 6, 2, 6], [55, 8, 8, 8]] + 0.00658745572292138409 # B[1385, [36, 6, 2, 8], [36, 6, 2, 8]] + -0.00238764687643479301 # B[1386, [36, 6, 2, 8], [37, 6, 3, 7]] + -0.000831950910425274803 # B[1387, [36, 6, 2, 8], [38, 6, 4, 6]] + 0.00351737364404769177 # B[1388, [36, 6, 2, 8], [39, 6, 4, 8]] + -0.00276293358095670936 # B[1389, [36, 6, 2, 8], [40, 6, 5, 7]] + -0.00115031008308692437 # B[1390, [36, 6, 2, 8], [41, 6, 6, 6]] + -0.000921624256609663434 # B[1391, [36, 6, 2, 8], [42, 6, 6, 8]] + 0.000810924380859275734 # B[1392, [36, 6, 2, 8], [43, 7, 0, 7]] + -0.00488922361819911239 # B[1393, [36, 6, 2, 8], [44, 7, 1, 8]] + 0.00170426259508682162 # B[1394, [36, 6, 2, 8], [45, 7, 2, 7]] + -0.000698037236981145087 # B[1395, [36, 6, 2, 8], [46, 7, 3, 8]] + -0.00159293071425275958 # B[1396, [36, 6, 2, 8], [47, 7, 4, 7]] + 0.00145526568566858513 # B[1397, [36, 6, 2, 8], [48, 7, 5, 8]] + -0.0034526631911915729 # B[1398, [36, 6, 2, 8], [49, 7, 6, 7]] + 0.00136118079841816148 # B[1399, [36, 6, 2, 8], [50, 7, 7, 8]] + -0.000519558666561149851 # B[1400, [36, 6, 2, 8], [51, 8, 0, 8]] + -0.00125430728243427136 # B[1401, [36, 6, 2, 8], [52, 8, 2, 8]] + 0.000225746730173992209 # B[1402, [36, 6, 2, 8], [53, 8, 4, 8]] + 0.000144081610870761424 # B[1403, [36, 6, 2, 8], [54, 8, 6, 8]] + 0.000848192939185923693 # B[1404, [36, 6, 2, 8], [55, 8, 8, 8]] + 0.00209760366601450393 # B[1405, [37, 6, 3, 7], [37, 6, 3, 7]] + -0.00114098142783233825 # B[1406, [37, 6, 3, 7], [38, 6, 4, 6]] + -0.00012482798433224862 # B[1407, [37, 6, 3, 7], [39, 6, 4, 8]] + 0.000414303981445450498 # B[1408, [37, 6, 3, 7], [40, 6, 5, 7]] + -2.06949976952613968e-05 # B[1409, [37, 6, 3, 7], [41, 6, 6, 6]] + 0.000986658381613915447 # B[1410, [37, 6, 3, 7], [42, 6, 6, 8]] + 0.000196361012595618056 # B[1411, [37, 6, 3, 7], [43, 7, 0, 7]] + 0.000421620511108736218 # B[1412, [37, 6, 3, 7], [44, 7, 1, 8]] + -0.00121366957406692996 # B[1413, [37, 6, 3, 7], [45, 7, 2, 7]] + 0.000319772245183778947 # B[1414, [37, 6, 3, 7], [46, 7, 3, 8]] + -0.00189440310525268441 # B[1415, [37, 6, 3, 7], [47, 7, 4, 7]] + -0.000420808921505540223 # B[1416, [37, 6, 3, 7], [48, 7, 5, 8]] + -0.000833056882638676111 # B[1417, [37, 6, 3, 7], [49, 7, 6, 7]] + -0.000210394181928773294 # B[1418, [37, 6, 3, 7], [50, 7, 7, 8]] + 4.67415997983874898e-05 # B[1419, [37, 6, 3, 7], [51, 8, 0, 8]] + -0.000629437221263145228 # B[1420, [37, 6, 3, 7], [52, 8, 2, 8]] + -0.000561739301858470846 # B[1421, [37, 6, 3, 7], [53, 8, 4, 8]] + -0.000244403089656959616 # B[1422, [37, 6, 3, 7], [54, 8, 6, 8]] + 0.000170058213410727299 # B[1423, [37, 6, 3, 7], [55, 8, 8, 8]] + 0.000190580820336867102 # B[1424, [38, 6, 4, 6], [38, 6, 4, 6]] + -5.17086422710446442e-05 # B[1425, [38, 6, 4, 6], [39, 6, 4, 8]] + -0.000870479233908965505 # B[1426, [38, 6, 4, 6], [40, 6, 5, 7]] + 8.56431173592298034e-05 # B[1427, [38, 6, 4, 6], [41, 6, 6, 6]] + -0.000219028113680014638 # B[1428, [38, 6, 4, 6], [42, 6, 6, 8]] + 6.99094597341239771e-05 # B[1429, [38, 6, 4, 6], [43, 7, 0, 7]] + -0.00217214753267054063 # B[1430, [38, 6, 4, 6], [44, 7, 1, 8]] + 0.00103452950595812193 # B[1431, [38, 6, 4, 6], [45, 7, 2, 7]] + 0.000131158053198399821 # B[1432, [38, 6, 4, 6], [46, 7, 3, 8]] + -0.000991288929959081421 # B[1433, [38, 6, 4, 6], [47, 7, 4, 7]] + -0.000321058899826150157 # B[1434, [38, 6, 4, 6], [48, 7, 5, 8]] + -0.000126379357764709599 # B[1435, [38, 6, 4, 6], [49, 7, 6, 7]] + 0.000513859397020456632 # B[1436, [38, 6, 4, 6], [50, 7, 7, 8]] + -2.72482190626921472e-05 # B[1437, [38, 6, 4, 6], [51, 8, 0, 8]] + 0.000742781076179950886 # B[1438, [38, 6, 4, 6], [52, 8, 2, 8]] + -9.17701606060090935e-05 # B[1439, [38, 6, 4, 6], [53, 8, 4, 8]] + 1.49768390447675703e-05 # B[1440, [38, 6, 4, 6], [54, 8, 6, 8]] + -5.94521118466549703e-05 # B[1441, [38, 6, 4, 6], [55, 8, 8, 8]] + 0.00161400415689978271 # B[1442, [39, 6, 4, 8], [39, 6, 4, 8]] + -0.000149892220376375129 # B[1443, [39, 6, 4, 8], [40, 6, 5, 7]] + -0.000242832088631229209 # B[1444, [39, 6, 4, 8], [41, 6, 6, 6]] + -4.23223006292567511e-05 # B[1445, [39, 6, 4, 8], [42, 6, 6, 8]] + 0.000145544599928226076 # B[1446, [39, 6, 4, 8], [43, 7, 0, 7]] + -0.000846976149028450323 # B[1447, [39, 6, 4, 8], [44, 7, 1, 8]] + 0.000313402576083809947 # B[1448, [39, 6, 4, 8], [45, 7, 2, 7]] + -0.00105304559168569421 # B[1449, [39, 6, 4, 8], [46, 7, 3, 8]] + -0.000563622717067245593 # B[1450, [39, 6, 4, 8], [47, 7, 4, 7]] + -0.000176248327800098206 # B[1451, [39, 6, 4, 8], [48, 7, 5, 8]] + -0.000523005481859822874 # B[1452, [39, 6, 4, 8], [49, 7, 6, 7]] + 0.000327425878709725754 # B[1453, [39, 6, 4, 8], [50, 7, 7, 8]] + -0.000214075091648432969 # B[1454, [39, 6, 4, 8], [51, 8, 0, 8]] + 0.000892962890338189208 # B[1455, [39, 6, 4, 8], [52, 8, 2, 8]] + 0.000483016760753301674 # B[1456, [39, 6, 4, 8], [53, 8, 4, 8]] + 0.000385986009520520711 # B[1457, [39, 6, 4, 8], [54, 8, 6, 8]] + 0.000210387221014841225 # B[1458, [39, 6, 4, 8], [55, 8, 8, 8]] + 0.000423894835630976054 # B[1459, [40, 6, 5, 7], [40, 6, 5, 7]] + 2.52152593651043533e-05 # B[1460, [40, 6, 5, 7], [41, 6, 6, 6]] + 0.0001406783760301792 # B[1461, [40, 6, 5, 7], [42, 6, 6, 8]] + -0.000402862939603353815 # B[1462, [40, 6, 5, 7], [43, 7, 0, 7]] + -0.000764679971924708997 # B[1463, [40, 6, 5, 7], [44, 7, 1, 8]] + 0.000690122720081854865 # B[1464, [40, 6, 5, 7], [45, 7, 2, 7]] + 0.00135911524951161378 # B[1465, [40, 6, 5, 7], [46, 7, 3, 8]] + 5.52075818169902449e-06 # B[1466, [40, 6, 5, 7], [47, 7, 4, 7]] + -0.000149902773226399076 # B[1467, [40, 6, 5, 7], [48, 7, 5, 8]] + 0.000389894625400750289 # B[1468, [40, 6, 5, 7], [49, 7, 6, 7]] + 0.000257807843360047251 # B[1469, [40, 6, 5, 7], [50, 7, 7, 8]] + -3.67912373811542237e-05 # B[1470, [40, 6, 5, 7], [51, 8, 0, 8]] + -0.000174743024771516643 # B[1471, [40, 6, 5, 7], [52, 8, 2, 8]] + 0.000276798622678277838 # B[1472, [40, 6, 5, 7], [53, 8, 4, 8]] + 0.000152459620483783032 # B[1473, [40, 6, 5, 7], [54, 8, 6, 8]] + -0.000616599602238733502 # B[1474, [40, 6, 5, 7], [55, 8, 8, 8]] + -5.12324624723156652e-05 # B[1475, [41, 6, 6, 6], [41, 6, 6, 6]] + -4.23334509430418893e-05 # B[1476, [41, 6, 6, 6], [42, 6, 6, 8]] + -0.000111212733055157664 # B[1477, [41, 6, 6, 6], [43, 7, 0, 7]] + 0.000882360189618891337 # B[1478, [41, 6, 6, 6], [44, 7, 1, 8]] + -0.000581964842687935843 # B[1479, [41, 6, 6, 6], [45, 7, 2, 7]] + 0.000211138997961872465 # B[1480, [41, 6, 6, 6], [46, 7, 3, 8]] + 7.79906436828414068e-05 # B[1481, [41, 6, 6, 6], [47, 7, 4, 7]] + -0.000201461425275273331 # B[1482, [41, 6, 6, 6], [48, 7, 5, 8]] + 6.87828589884392771e-05 # B[1483, [41, 6, 6, 6], [49, 7, 6, 7]] + 0.000150653067204437052 # B[1484, [41, 6, 6, 6], [50, 7, 7, 8]] + 3.87532549918634395e-05 # B[1485, [41, 6, 6, 6], [51, 8, 0, 8]] + 0.000361299779465781672 # B[1486, [41, 6, 6, 6], [52, 8, 2, 8]] + -0.000217385549744270783 # B[1487, [41, 6, 6, 6], [53, 8, 4, 8]] + 6.09508622621875856e-05 # B[1488, [41, 6, 6, 6], [54, 8, 6, 8]] + -0.000174447165900721429 # B[1489, [41, 6, 6, 6], [55, 8, 8, 8]] + 4.08451735536830007e-05 # B[1490, [42, 6, 6, 8], [42, 6, 6, 8]] + -0.000100109250872669128 # B[1491, [42, 6, 6, 8], [43, 7, 0, 7]] + 0.000543796967600337564 # B[1492, [42, 6, 6, 8], [44, 7, 1, 8]] + 0.000744432946735457124 # B[1493, [42, 6, 6, 8], [45, 7, 2, 7]] + 0.0010803210667922683 # B[1494, [42, 6, 6, 8], [46, 7, 3, 8]] + 0.000151445105968722347 # B[1495, [42, 6, 6, 8], [47, 7, 4, 7]] + -0.000100848877598445907 # B[1496, [42, 6, 6, 8], [48, 7, 5, 8]] + -0.000109088350721993355 # B[1497, [42, 6, 6, 8], [49, 7, 6, 7]] + -0.000287924009882135207 # B[1498, [42, 6, 6, 8], [50, 7, 7, 8]] + 1.48405987461727729e-05 # B[1499, [42, 6, 6, 8], [51, 8, 0, 8]] + 0.00133229142431166023 # B[1500, [42, 6, 6, 8], [52, 8, 2, 8]] + -0.00019157481902659472 # B[1501, [42, 6, 6, 8], [53, 8, 4, 8]] + -0.000214414469154704246 # B[1502, [42, 6, 6, 8], [54, 8, 6, 8]] + -0.000145460173238021184 # B[1503, [42, 6, 6, 8], [55, 8, 8, 8]] + 0.000122164068846408735 # B[1504, [43, 7, 0, 7], [43, 7, 0, 7]] + -0.000271198052548764657 # B[1505, [43, 7, 0, 7], [44, 7, 1, 8]] + -7.53020792218089818e-05 # B[1506, [43, 7, 0, 7], [45, 7, 2, 7]] + -0.000522043739406908344 # B[1507, [43, 7, 0, 7], [46, 7, 3, 8]] + -4.818852612961666e-05 # B[1508, [43, 7, 0, 7], [47, 7, 4, 7]] + -0.000220542438614808323 # B[1509, [43, 7, 0, 7], [48, 7, 5, 8]] + -0.000160998835878327362 # B[1510, [43, 7, 0, 7], [49, 7, 6, 7]] + -2.41628428966911279e-05 # B[1511, [43, 7, 0, 7], [50, 7, 7, 8]] + -1.41474469189661889e-05 # B[1512, [43, 7, 0, 7], [51, 8, 0, 8]] + -0.000160534811881916234 # B[1513, [43, 7, 0, 7], [52, 8, 2, 8]] + -1.73735621299461046e-05 # B[1514, [43, 7, 0, 7], [53, 8, 4, 8]] + 4.73251016045242445e-05 # B[1515, [43, 7, 0, 7], [54, 8, 6, 8]] + 0.000182463508348683356 # B[1516, [43, 7, 0, 7], [55, 8, 8, 8]] + -0.000629134879565343137 # B[1517, [44, 7, 1, 8], [44, 7, 1, 8]] + -0.00207361578267727673 # B[1518, [44, 7, 1, 8], [45, 7, 2, 7]] + 0.0031686999001355326 # B[1519, [44, 7, 1, 8], [46, 7, 3, 8]] + -0.000405403647932546952 # B[1520, [44, 7, 1, 8], [47, 7, 4, 7]] + -0.000111251617971438489 # B[1521, [44, 7, 1, 8], [48, 7, 5, 8]] + 0.0014482690523848242 # B[1522, [44, 7, 1, 8], [49, 7, 6, 7]] + 0.000818892450912583197 # B[1523, [44, 7, 1, 8], [50, 7, 7, 8]] + 0.000100422502558870572 # B[1524, [44, 7, 1, 8], [51, 8, 0, 8]] + -0.000412863674396233161 # B[1525, [44, 7, 1, 8], [52, 8, 2, 8]] + -0.000905494278120194153 # B[1526, [44, 7, 1, 8], [53, 8, 4, 8]] + 0.00126932173443552359 # B[1527, [44, 7, 1, 8], [54, 8, 6, 8]] + -0.000374814469421512735 # B[1528, [44, 7, 1, 8], [55, 8, 8, 8]] + -0.00330341133748704441 # B[1529, [45, 7, 2, 7], [45, 7, 2, 7]] + 0.00131616674488897398 # B[1530, [45, 7, 2, 7], [46, 7, 3, 8]] + -0.000483635326292886428 # B[1531, [45, 7, 2, 7], [47, 7, 4, 7]] + -0.00177550615332965067 # B[1532, [45, 7, 2, 7], [48, 7, 5, 8]] + 0.00226091969304176299 # B[1533, [45, 7, 2, 7], [49, 7, 6, 7]] + -0.00142635978155006456 # B[1534, [45, 7, 2, 7], [50, 7, 7, 8]] + 0.000289476939908078768 # B[1535, [45, 7, 2, 7], [51, 8, 0, 8]] + 0.000582488578419503846 # B[1536, [45, 7, 2, 7], [52, 8, 2, 8]] + -0.000228795123723987606 # B[1537, [45, 7, 2, 7], [53, 8, 4, 8]] + 0.000478658611037000373 # B[1538, [45, 7, 2, 7], [54, 8, 6, 8]] + -0.00101956994563059782 # B[1539, [45, 7, 2, 7], [55, 8, 8, 8]] + 0.00268648192223141895 # B[1540, [46, 7, 3, 8], [46, 7, 3, 8]] + 0.000515570689344949529 # B[1541, [46, 7, 3, 8], [47, 7, 4, 7]] + 0.000903689215066725768 # B[1542, [46, 7, 3, 8], [48, 7, 5, 8]] + 0.00180650309403464215 # B[1543, [46, 7, 3, 8], [49, 7, 6, 7]] + -7.48574841450792838e-05 # B[1544, [46, 7, 3, 8], [50, 7, 7, 8]] + -2.90930360741237237e-05 # B[1545, [46, 7, 3, 8], [51, 8, 0, 8]] + 0.00139057844941538594 # B[1546, [46, 7, 3, 8], [52, 8, 2, 8]] + -0.000263907165716330272 # B[1547, [46, 7, 3, 8], [53, 8, 4, 8]] + -5.74521512815137289e-05 # B[1548, [46, 7, 3, 8], [54, 8, 6, 8]] + -0.00030234445629373323 # B[1549, [46, 7, 3, 8], [55, 8, 8, 8]] + -0.000842080339294604824 # B[1550, [47, 7, 4, 7], [47, 7, 4, 7]] + -1.8677234631915389e-05 # B[1551, [47, 7, 4, 7], [48, 7, 5, 8]] + 0.000150434033167294937 # B[1552, [47, 7, 4, 7], [49, 7, 6, 7]] + 0.000201922161197246736 # B[1553, [47, 7, 4, 7], [50, 7, 7, 8]] + 5.63689077359152968e-05 # B[1554, [47, 7, 4, 7], [51, 8, 0, 8]] + 0.000490229079971716761 # B[1555, [47, 7, 4, 7], [52, 8, 2, 8]] + -0.00019335269881828529 # B[1556, [47, 7, 4, 7], [53, 8, 4, 8]] + -0.000118664083374402096 # B[1557, [47, 7, 4, 7], [54, 8, 6, 8]] + -0.000397263359111398734 # B[1558, [47, 7, 4, 7], [55, 8, 8, 8]] + -0.000724261739409587726 # B[1559, [48, 7, 5, 8], [48, 7, 5, 8]] + 0.000186853474209224685 # B[1560, [48, 7, 5, 8], [49, 7, 6, 7]] + -0.000533321040010020266 # B[1561, [48, 7, 5, 8], [50, 7, 7, 8]] + 9.95102706208284005e-08 # B[1562, [48, 7, 5, 8], [51, 8, 0, 8]] + -0.00093755398196557671 # B[1563, [48, 7, 5, 8], [52, 8, 2, 8]] + 0.000483236780374178207 # B[1564, [48, 7, 5, 8], [53, 8, 4, 8]] + -5.03524206302112531e-05 # B[1565, [48, 7, 5, 8], [54, 8, 6, 8]] + -0.000586245052440398373 # B[1566, [48, 7, 5, 8], [55, 8, 8, 8]] + -0.000207118017941997773 # B[1567, [49, 7, 6, 7], [49, 7, 6, 7]] + -9.40116364012005823e-05 # B[1568, [49, 7, 6, 7], [50, 7, 7, 8]] + 0.000124266884770383307 # B[1569, [49, 7, 6, 7], [51, 8, 0, 8]] + 0.00118479186165786239 # B[1570, [49, 7, 6, 7], [52, 8, 2, 8]] + -0.000129238345120056067 # B[1571, [49, 7, 6, 7], [53, 8, 4, 8]] + -0.000383875224777865259 # B[1572, [49, 7, 6, 7], [54, 8, 6, 8]] + -0.000457194559055141767 # B[1573, [49, 7, 6, 7], [55, 8, 8, 8]] + -0.000450510261664234871 # B[1574, [50, 7, 7, 8], [50, 7, 7, 8]] + 7.52704593073999506e-05 # B[1575, [50, 7, 7, 8], [51, 8, 0, 8]] + -0.00128732840082427732 # B[1576, [50, 7, 7, 8], [52, 8, 2, 8]] + 0.000293225651298797269 # B[1577, [50, 7, 7, 8], [53, 8, 4, 8]] + -0.000306521733645761033 # B[1578, [50, 7, 7, 8], [54, 8, 6, 8]] + -0.000370268243746852549 # B[1579, [50, 7, 7, 8], [55, 8, 8, 8]] + -4.00747887657759705e-06 # B[1580, [51, 8, 0, 8], [51, 8, 0, 8]] + -0.000179079356204300821 # B[1581, [51, 8, 0, 8], [52, 8, 2, 8]] + -6.37205046857824975e-06 # B[1582, [51, 8, 0, 8], [53, 8, 4, 8]] + 5.20087282658288075e-05 # B[1583, [51, 8, 0, 8], [54, 8, 6, 8]] + 6.68015373273544988e-05 # B[1584, [51, 8, 0, 8], [55, 8, 8, 8]] + 0.00160592146390294661 # B[1585, [52, 8, 2, 8], [52, 8, 2, 8]] + 0.000454049229948232103 # B[1586, [52, 8, 2, 8], [53, 8, 4, 8]] + 0.00110675066334388339 # B[1587, [52, 8, 2, 8], [54, 8, 6, 8]] + -0.000191060465051852771 # B[1588, [52, 8, 2, 8], [55, 8, 8, 8]] + -0.000131765455753670314 # B[1589, [53, 8, 4, 8], [53, 8, 4, 8]] + -7.05704764431217685e-05 # B[1590, [53, 8, 4, 8], [54, 8, 6, 8]] + -1.82263105369812051e-05 # B[1591, [53, 8, 4, 8], [55, 8, 8, 8]] + -0.00032731873727259329 # B[1592, [54, 8, 6, 8], [54, 8, 6, 8]] + -0.000198178389384386089 # B[1593, [54, 8, 6, 8], [55, 8, 8, 8]] + -0.000136309758672861769 # B[1594, [55, 8, 8, 8], [55, 8, 8, 8]] + +# End of potential diff --git a/potentials/C_SNAP_2021.10.15.quadratic.snapparam b/potentials/C_SNAP_2021.10.15.quadratic.snapparam new file mode 100644 index 0000000000..26dddf627d --- /dev/null +++ b/potentials/C_SNAP_2021.10.15.quadratic.snapparam @@ -0,0 +1,10 @@ + + # required + rcutfac 2.7 + twojmax 8 + + # optional + rfac0 0.99363 + rmin0 0.0 + bzeroflag 0 + quadraticflag 1 From c95dcd7582bfbe004cd67cb34a2e62ab625aca65 Mon Sep 17 00:00:00 2001 From: jwillma2 <52575231+jwillma2@users.noreply.github.com> Date: Tue, 23 May 2023 12:58:19 -0400 Subject: [PATCH 248/448] Delete C_Willman_PRB2022.quadratic.snapcoeff --- .../C_Willman_PRB2022.quadratic.snapcoeff | 1602 ----------------- 1 file changed, 1602 deletions(-) delete mode 100644 potentials/C_Willman_PRB2022.quadratic.snapcoeff diff --git a/potentials/C_Willman_PRB2022.quadratic.snapcoeff b/potentials/C_Willman_PRB2022.quadratic.snapcoeff deleted file mode 100644 index d5e6b79acb..0000000000 --- a/potentials/C_Willman_PRB2022.quadratic.snapcoeff +++ /dev/null @@ -1,1602 +0,0 @@ -# fitsnap fit generated on 2021-10-15 08:21:38.396384 -#UNITS: metal CONTRIBUTOR: Ivan Oleynik CITATION: Jonathan T. Willman, Kien Nguyen-Cong, Ashley S. Williams, Anatoly B. Belonoshko, Stan G. Moore, Aidan P. Thompson, Mitchell A. Wood, and Ivan I. Oleynik, "Machine learning interatomic potential for simulations of carbon at extreme conditions" Phys. Rev. B 106, L180101 (2022) -1 1596 -C 0.5 1.0 - -2.7758927591660334 # B[0] - 0.00859216942217639126 # B[1, 0, 0, 0] - 0.16638458601459194 # B[2, 1, 0, 1] - 0.22261822339506554 # B[3, 1, 1, 2] - 0.257355166247009937 # B[4, 2, 0, 2] - 0.802105904460230779 # B[5, 2, 1, 3] - 0.227216469467176801 # B[6, 2, 2, 2] - 0.494646284119575508 # B[7, 2, 2, 4] - 0.276718638025069574 # B[8, 3, 0, 3] - 1.09101782892605392 # B[9, 3, 1, 4] - 0.775283725099378151 # B[10, 3, 2, 3] - -0.232869556477520168 # B[11, 3, 2, 5] - 0.188466708736270222 # B[12, 3, 3, 4] - -0.213463540195325957 # B[13, 3, 3, 6] - 0.285049005401720568 # B[14, 4, 0, 4] - -0.248039138369940321 # B[15, 4, 1, 5] - -0.017694405190132434 # B[16, 4, 2, 4] - -0.513770238875468355 # B[17, 4, 2, 6] - -0.603368424950793791 # B[18, 4, 3, 5] - -0.4245149972360448 # B[19, 4, 3, 7] - -0.149612637312833391 # B[20, 4, 4, 4] - -0.153415086019898006 # B[21, 4, 4, 6] - -0.14513624400298164 # B[22, 4, 4, 8] - -0.0460661393681677661 # B[23, 5, 0, 5] - -0.0512559726916635844 # B[24, 5, 1, 6] - -0.125285455697324882 # B[25, 5, 2, 5] - -0.297464016341802473 # B[26, 5, 2, 7] - -0.219930176940332595 # B[27, 5, 3, 6] - -0.195418601625407001 # B[28, 5, 3, 8] - -0.236454956825408069 # B[29, 5, 4, 5] - -0.247483318285177556 # B[30, 5, 4, 7] - 0.108404148378543994 # B[31, 5, 5, 6] - 0.102786344334006338 # B[32, 5, 5, 8] - -0.0174963987262215619 # B[33, 6, 0, 6] - -0.347663919737827065 # B[34, 6, 1, 7] - -0.308777238806140442 # B[35, 6, 2, 6] - -0.30366671620990171 # B[36, 6, 2, 8] - -0.190992135157848048 # B[37, 6, 3, 7] - -0.212717125362634818 # B[38, 6, 4, 6] - -0.127682310305149815 # B[39, 6, 4, 8] - 0.128955786755968027 # B[40, 6, 5, 7] - 0.108121871413745185 # B[41, 6, 6, 6] - 0.0951564970231452284 # B[42, 6, 6, 8] - -0.0443430969083889667 # B[43, 7, 0, 7] - 0.0394012265947801602 # B[44, 7, 1, 8] - 0.0238287662182333909 # B[45, 7, 2, 7] - -0.0703216614205220136 # B[46, 7, 3, 8] - -0.0229748587995626564 # B[47, 7, 4, 7] - 0.461615758896215367 # B[48, 7, 5, 8] - 0.032037855993324961 # B[49, 7, 6, 7] - 0.105399776101016598 # B[50, 7, 7, 8] - -0.0452778356788145764 # B[51, 8, 0, 8] - -0.0400452652333231421 # B[52, 8, 2, 8] - -0.152415456089667084 # B[53, 8, 4, 8] - 0.0303383368396002995 # B[54, 8, 6, 8] - 0.0660845112300222914 # B[55, 8, 8, 8] - 5.0022584003536763e-06 # B[55, [1, 0, 0, 0], [1, 0, 0, 0]] - 7.12434860521689133e-05 # B[56, [1, 0, 0, 0], [2, 1, 0, 1]] - 0.00410559459459784552 # B[57, [1, 0, 0, 0], [3, 1, 1, 2]] - -0.000152151102822628559 # B[58, [1, 0, 0, 0], [4, 2, 0, 2]] - -0.00104851962847402839 # B[59, [1, 0, 0, 0], [5, 2, 1, 3]] - 0.00174544590749468355 # B[60, [1, 0, 0, 0], [6, 2, 2, 2]] - -0.00039686396723943862 # B[61, [1, 0, 0, 0], [7, 2, 2, 4]] - 0.000344474173032960351 # B[62, [1, 0, 0, 0], [8, 3, 0, 3]] - 5.77832175303926235e-05 # B[63, [1, 0, 0, 0], [9, 3, 1, 4]] - 0.00124014860085090543 # B[64, [1, 0, 0, 0], [10, 3, 2, 3]] - 1.92520730655986946e-05 # B[65, [1, 0, 0, 0], [11, 3, 2, 5]] - -0.000659022869027497959 # B[66, [1, 0, 0, 0], [12, 3, 3, 4]] - -0.000296998157394604001 # B[67, [1, 0, 0, 0], [13, 3, 3, 6]] - 2.13348987737616014e-06 # B[68, [1, 0, 0, 0], [14, 4, 0, 4]] - -0.000377679899824956422 # B[69, [1, 0, 0, 0], [15, 4, 1, 5]] - 0.00045743496488695988 # B[70, [1, 0, 0, 0], [16, 4, 2, 4]] - -0.00047978616167941926 # B[71, [1, 0, 0, 0], [17, 4, 2, 6]] - -0.000346601408372410741 # B[72, [1, 0, 0, 0], [18, 4, 3, 5]] - -0.000216752459512900564 # B[73, [1, 0, 0, 0], [19, 4, 3, 7]] - -0.000153945954064437646 # B[74, [1, 0, 0, 0], [20, 4, 4, 4]] - 0.00029484781857681483 # B[75, [1, 0, 0, 0], [21, 4, 4, 6]] - 1.59236973873017051e-05 # B[76, [1, 0, 0, 0], [22, 4, 4, 8]] - -2.35544935613951623e-05 # B[77, [1, 0, 0, 0], [23, 5, 0, 5]] - 0.000492019807872501325 # B[78, [1, 0, 0, 0], [24, 5, 1, 6]] - 0.000376700986017126233 # B[79, [1, 0, 0, 0], [25, 5, 2, 5]] - -0.000185900021989794662 # B[80, [1, 0, 0, 0], [26, 5, 2, 7]] - 0.000219939447169378507 # B[81, [1, 0, 0, 0], [27, 5, 3, 6]] - -0.000192198129806066265 # B[82, [1, 0, 0, 0], [28, 5, 3, 8]] - 0.000175514531344928004 # B[83, [1, 0, 0, 0], [29, 5, 4, 5]] - 0.000261949015135925535 # B[84, [1, 0, 0, 0], [30, 5, 4, 7]] - 0.00021011408484750832 # B[85, [1, 0, 0, 0], [31, 5, 5, 6]] - -7.47807464450689352e-05 # B[86, [1, 0, 0, 0], [32, 5, 5, 8]] - -1.36809205491805752e-05 # B[87, [1, 0, 0, 0], [33, 6, 0, 6]] - 0.000493576806965066728 # B[88, [1, 0, 0, 0], [34, 6, 1, 7]] - 0.000216301405824667614 # B[89, [1, 0, 0, 0], [35, 6, 2, 6]] - -0.000364540437645548276 # B[90, [1, 0, 0, 0], [36, 6, 2, 8]] - -0.000251411532179113273 # B[91, [1, 0, 0, 0], [37, 6, 3, 7]] - 3.19331690196988927e-05 # B[92, [1, 0, 0, 0], [38, 6, 4, 6]] - -1.56092571080845843e-05 # B[93, [1, 0, 0, 0], [39, 6, 4, 8]] - 2.4859429830464963e-05 # B[94, [1, 0, 0, 0], [40, 6, 5, 7]] - -5.06306418207175257e-05 # B[95, [1, 0, 0, 0], [41, 6, 6, 6]] - -9.75742047871729079e-05 # B[96, [1, 0, 0, 0], [42, 6, 6, 8]] - -4.07774117821002591e-05 # B[97, [1, 0, 0, 0], [43, 7, 0, 7]] - 0.000169705539551909257 # B[98, [1, 0, 0, 0], [44, 7, 1, 8]] - 0.000261792097012429614 # B[99, [1, 0, 0, 0], [45, 7, 2, 7]] - 0.000235813389494382575 # B[100, [1, 0, 0, 0], [46, 7, 3, 8]] - 3.69194385055615637e-05 # B[101, [1, 0, 0, 0], [47, 7, 4, 7]] - 0.000101832840349036502 # B[102, [1, 0, 0, 0], [48, 7, 5, 8]] - 1.87768621704026417e-05 # B[103, [1, 0, 0, 0], [49, 7, 6, 7]] - 6.90123641682582889e-05 # B[104, [1, 0, 0, 0], [50, 7, 7, 8]] - 3.82281861928956967e-05 # B[105, [1, 0, 0, 0], [51, 8, 0, 8]] - 0.00044905358698343889 # B[106, [1, 0, 0, 0], [52, 8, 2, 8]] - 3.83170337754923374e-05 # B[107, [1, 0, 0, 0], [53, 8, 4, 8]] - -4.53472261485315942e-05 # B[108, [1, 0, 0, 0], [54, 8, 6, 8]] - -0.000105793544360549552 # B[109, [1, 0, 0, 0], [55, 8, 8, 8]] - -0.00542851209933992596 # B[110, [2, 1, 0, 1], [2, 1, 0, 1]] - -0.00800035055604917701 # B[111, [2, 1, 0, 1], [3, 1, 1, 2]] - 0.000279580761847972054 # B[112, [2, 1, 0, 1], [4, 2, 0, 2]] - -0.0132643544617690821 # B[113, [2, 1, 0, 1], [5, 2, 1, 3]] - -0.00300637860380324968 # B[114, [2, 1, 0, 1], [6, 2, 2, 2]] - 0.00343216933390476549 # B[115, [2, 1, 0, 1], [7, 2, 2, 4]] - 6.39026040622058672e-05 # B[116, [2, 1, 0, 1], [8, 3, 0, 3]] - -0.0124005148347727506 # B[117, [2, 1, 0, 1], [9, 3, 1, 4]] - -0.0036690465725984691 # B[118, [2, 1, 0, 1], [10, 3, 2, 3]] - -0.0066468850826254932 # B[119, [2, 1, 0, 1], [11, 3, 2, 5]] - -0.00518212543330048934 # B[120, [2, 1, 0, 1], [12, 3, 3, 4]] - -0.00269613907034030407 # B[121, [2, 1, 0, 1], [13, 3, 3, 6]] - -0.000330193583102013615 # B[122, [2, 1, 0, 1], [14, 4, 0, 4]] - -0.000429062486184235686 # B[123, [2, 1, 0, 1], [15, 4, 1, 5]] - -0.000991704717453613382 # B[124, [2, 1, 0, 1], [16, 4, 2, 4]] - 0.00152944521177345071 # B[125, [2, 1, 0, 1], [17, 4, 2, 6]] - -0.00660856033628089406 # B[126, [2, 1, 0, 1], [18, 4, 3, 5]] - 0.00146758746394204951 # B[127, [2, 1, 0, 1], [19, 4, 3, 7]] - -0.00161093753941019967 # B[128, [2, 1, 0, 1], [20, 4, 4, 4]] - -0.00101484284665418574 # B[129, [2, 1, 0, 1], [21, 4, 4, 6]] - 0.00150269420364470413 # B[130, [2, 1, 0, 1], [22, 4, 4, 8]] - -0.000251279508914979688 # B[131, [2, 1, 0, 1], [23, 5, 0, 5]] - 0.00427791921512100763 # B[132, [2, 1, 0, 1], [24, 5, 1, 6]] - -0.00312327633171666707 # B[133, [2, 1, 0, 1], [25, 5, 2, 5]] - 0.00145518956483171066 # B[134, [2, 1, 0, 1], [26, 5, 2, 7]] - -0.00296392629706135422 # B[135, [2, 1, 0, 1], [27, 5, 3, 6]] - 0.00106990236696331148 # B[136, [2, 1, 0, 1], [28, 5, 3, 8]] - 0.000140740776400729824 # B[137, [2, 1, 0, 1], [29, 5, 4, 5]] - -0.000704484148092703912 # B[138, [2, 1, 0, 1], [30, 5, 4, 7]] - 0.000555926138942124939 # B[139, [2, 1, 0, 1], [31, 5, 5, 6]] - 0.000749361142656781065 # B[140, [2, 1, 0, 1], [32, 5, 5, 8]] - -0.000275563231062828096 # B[141, [2, 1, 0, 1], [33, 6, 0, 6]] - 0.00404287546990938183 # B[142, [2, 1, 0, 1], [34, 6, 1, 7]] - -0.00329083016295819491 # B[143, [2, 1, 0, 1], [35, 6, 2, 6]] - 0.00374648670440783874 # B[144, [2, 1, 0, 1], [36, 6, 2, 8]] - -0.000931584323738718183 # B[145, [2, 1, 0, 1], [37, 6, 3, 7]] - 0.001545987588966576 # B[146, [2, 1, 0, 1], [38, 6, 4, 6]] - 0.000136630337825366203 # B[147, [2, 1, 0, 1], [39, 6, 4, 8]] - -0.000338191518470186761 # B[148, [2, 1, 0, 1], [40, 6, 5, 7]] - 0.000383732900037425575 # B[149, [2, 1, 0, 1], [41, 6, 6, 6]] - 0.000891911333988446714 # B[150, [2, 1, 0, 1], [42, 6, 6, 8]] - 0.000372325777048820861 # B[151, [2, 1, 0, 1], [43, 7, 0, 7]] - 0.00203975899324063559 # B[152, [2, 1, 0, 1], [44, 7, 1, 8]] - -0.00366168906366426058 # B[153, [2, 1, 0, 1], [45, 7, 2, 7]] - -0.00217927110231279971 # B[154, [2, 1, 0, 1], [46, 7, 3, 8]] - -0.000355180731966526532 # B[155, [2, 1, 0, 1], [47, 7, 4, 7]] - -0.00190295940654904624 # B[156, [2, 1, 0, 1], [48, 7, 5, 8]] - -0.00045640385432905474 # B[157, [2, 1, 0, 1], [49, 7, 6, 7]] - -0.00123273230096131864 # B[158, [2, 1, 0, 1], [50, 7, 7, 8]] - 2.61749541232737803e-06 # B[159, [2, 1, 0, 1], [51, 8, 0, 8]] - -0.00188736987570012403 # B[160, [2, 1, 0, 1], [52, 8, 2, 8]] - 0.000127235145614493401 # B[161, [2, 1, 0, 1], [53, 8, 4, 8]] - -0.000446185446234578786 # B[162, [2, 1, 0, 1], [54, 8, 6, 8]] - 3.06626149019382718e-05 # B[163, [2, 1, 0, 1], [55, 8, 8, 8]] - 0.00500803145405033512 # B[164, [3, 1, 1, 2], [3, 1, 1, 2]] - 0.0136537265129433767 # B[165, [3, 1, 1, 2], [4, 2, 0, 2]] - 0.00586793418015095231 # B[166, [3, 1, 1, 2], [5, 2, 1, 3]] - 0.0108897828563872673 # B[167, [3, 1, 1, 2], [6, 2, 2, 2]] - 0.000782326392446437181 # B[168, [3, 1, 1, 2], [7, 2, 2, 4]] - -0.00196905235294965193 # B[169, [3, 1, 1, 2], [8, 3, 0, 3]] - -0.00575620599927615263 # B[170, [3, 1, 1, 2], [9, 3, 1, 4]] - -0.0395084171352078836 # B[171, [3, 1, 1, 2], [10, 3, 2, 3]] - -0.0402914809330097226 # B[172, [3, 1, 1, 2], [11, 3, 2, 5]] - -0.031380925125560552 # B[173, [3, 1, 1, 2], [12, 3, 3, 4]] - 0.0074098991236085333 # B[174, [3, 1, 1, 2], [13, 3, 3, 6]] - -0.00144234945688183152 # B[175, [3, 1, 1, 2], [14, 4, 0, 4]] - -0.00715563010950572616 # B[176, [3, 1, 1, 2], [15, 4, 1, 5]] - -0.0068004389765142035 # B[177, [3, 1, 1, 2], [16, 4, 2, 4]] - -0.0397838555572563451 # B[178, [3, 1, 1, 2], [17, 4, 2, 6]] - 0.00335672059516798228 # B[179, [3, 1, 1, 2], [18, 4, 3, 5]] - 0.0148934683418572647 # B[180, [3, 1, 1, 2], [19, 4, 3, 7]] - -0.000967980016249102011 # B[181, [3, 1, 1, 2], [20, 4, 4, 4]] - 0.00772576295059950596 # B[182, [3, 1, 1, 2], [21, 4, 4, 6]] - -0.00450662666899595381 # B[183, [3, 1, 1, 2], [22, 4, 4, 8]] - -0.00395807515027411967 # B[184, [3, 1, 1, 2], [23, 5, 0, 5]] - 0.010414612350238486 # B[185, [3, 1, 1, 2], [24, 5, 1, 6]] - -0.00513372683983254804 # B[186, [3, 1, 1, 2], [25, 5, 2, 5]] - -0.0265398819124704963 # B[187, [3, 1, 1, 2], [26, 5, 2, 7]] - 0.00742434172938952544 # B[188, [3, 1, 1, 2], [27, 5, 3, 6]] - -0.00256386423704287481 # B[189, [3, 1, 1, 2], [28, 5, 3, 8]] - 0.00841179553194743718 # B[190, [3, 1, 1, 2], [29, 5, 4, 5]] - 0.00668617729586690451 # B[191, [3, 1, 1, 2], [30, 5, 4, 7]] - 0.000484464094046739568 # B[192, [3, 1, 1, 2], [31, 5, 5, 6]] - 0.00458460314168420216 # B[193, [3, 1, 1, 2], [32, 5, 5, 8]] - -0.00235318401641824212 # B[194, [3, 1, 1, 2], [33, 6, 0, 6]] - -0.000804392064641467762 # B[195, [3, 1, 1, 2], [34, 6, 1, 7]] - -0.000974349018272668323 # B[196, [3, 1, 1, 2], [35, 6, 2, 6]] - -0.0186467861443154748 # B[197, [3, 1, 1, 2], [36, 6, 2, 8]] - 0.0149394908128317495 # B[198, [3, 1, 1, 2], [37, 6, 3, 7]] - -0.001417773975968062 # B[199, [3, 1, 1, 2], [38, 6, 4, 6]] - 0.00708801668305296916 # B[200, [3, 1, 1, 2], [39, 6, 4, 8]] - 0.00422029817457212405 # B[201, [3, 1, 1, 2], [40, 6, 5, 7]] - 0.00110117813016081525 # B[202, [3, 1, 1, 2], [41, 6, 6, 6]] - -0.00187490884044745794 # B[203, [3, 1, 1, 2], [42, 6, 6, 8]] - -0.00530063898164105998 # B[204, [3, 1, 1, 2], [43, 7, 0, 7]] - 0.0156639815207892212 # B[205, [3, 1, 1, 2], [44, 7, 1, 8]] - 0.0118519420103458811 # B[206, [3, 1, 1, 2], [45, 7, 2, 7]] - 0.00375057568532275679 # B[207, [3, 1, 1, 2], [46, 7, 3, 8]] - 0.00757584350406629962 # B[208, [3, 1, 1, 2], [47, 7, 4, 7]] - 0.0106601777099339986 # B[209, [3, 1, 1, 2], [48, 7, 5, 8]] - -0.0041075690062942552 # B[210, [3, 1, 1, 2], [49, 7, 6, 7]] - 0.00248707997936048041 # B[211, [3, 1, 1, 2], [50, 7, 7, 8]] - -0.0025390217113529746 # B[212, [3, 1, 1, 2], [51, 8, 0, 8]] - 0.00498354453902482165 # B[213, [3, 1, 1, 2], [52, 8, 2, 8]] - 0.00383782774054214912 # B[214, [3, 1, 1, 2], [53, 8, 4, 8]] - 0.00318870204625110783 # B[215, [3, 1, 1, 2], [54, 8, 6, 8]] - -0.00078409267383599678 # B[216, [3, 1, 1, 2], [55, 8, 8, 8]] - 0.00411479420703600093 # B[217, [4, 2, 0, 2], [4, 2, 0, 2]] - -0.00352482696278418658 # B[218, [4, 2, 0, 2], [5, 2, 1, 3]] - 0.00293296373222708129 # B[219, [4, 2, 0, 2], [6, 2, 2, 2]] - -0.00169108240942662173 # B[220, [4, 2, 0, 2], [7, 2, 2, 4]] - -0.00166875839344953099 # B[221, [4, 2, 0, 2], [8, 3, 0, 3]] - -0.00303743189373234653 # B[222, [4, 2, 0, 2], [9, 3, 1, 4]] - -0.00360352002032471395 # B[223, [4, 2, 0, 2], [10, 3, 2, 3]] - -0.00844475258400314774 # B[224, [4, 2, 0, 2], [11, 3, 2, 5]] - -0.00267861760564082688 # B[225, [4, 2, 0, 2], [12, 3, 3, 4]] - 0.00249373694942188646 # B[226, [4, 2, 0, 2], [13, 3, 3, 6]] - 0.00129518789575956 # B[227, [4, 2, 0, 2], [14, 4, 0, 4]] - -0.000616706097657935626 # B[228, [4, 2, 0, 2], [15, 4, 1, 5]] - -0.00374793183827557257 # B[229, [4, 2, 0, 2], [16, 4, 2, 4]] - -0.00725453590077526286 # B[230, [4, 2, 0, 2], [17, 4, 2, 6]] - -0.00328165463874066426 # B[231, [4, 2, 0, 2], [18, 4, 3, 5]] - -0.00387910875571249565 # B[232, [4, 2, 0, 2], [19, 4, 3, 7]] - -0.000691443248665482221 # B[233, [4, 2, 0, 2], [20, 4, 4, 4]] - -0.00364575524119575139 # B[234, [4, 2, 0, 2], [21, 4, 4, 6]] - 0.000579213613942424974 # B[235, [4, 2, 0, 2], [22, 4, 4, 8]] - 0.000382530088889220486 # B[236, [4, 2, 0, 2], [23, 5, 0, 5]] - 0.000700082663528700608 # B[237, [4, 2, 0, 2], [24, 5, 1, 6]] - -0.00303645662419470708 # B[238, [4, 2, 0, 2], [25, 5, 2, 5]] - -0.00412449214914962191 # B[239, [4, 2, 0, 2], [26, 5, 2, 7]] - -0.000863747946010486305 # B[240, [4, 2, 0, 2], [27, 5, 3, 6]] - 0.000597171151136822748 # B[241, [4, 2, 0, 2], [28, 5, 3, 8]] - -0.00290482182317059953 # B[242, [4, 2, 0, 2], [29, 5, 4, 5]] - -0.00218615594313117554 # B[243, [4, 2, 0, 2], [30, 5, 4, 7]] - 0.00120270898159113111 # B[244, [4, 2, 0, 2], [31, 5, 5, 6]] - -0.000439562436330729364 # B[245, [4, 2, 0, 2], [32, 5, 5, 8]] - -0.000155002689849706443 # B[246, [4, 2, 0, 2], [33, 6, 0, 6]] - -0.00203784613220199399 # B[247, [4, 2, 0, 2], [34, 6, 1, 7]] - -0.00251933129878168221 # B[248, [4, 2, 0, 2], [35, 6, 2, 6]] - -0.00227857345941180406 # B[249, [4, 2, 0, 2], [36, 6, 2, 8]] - 0.00307391827986236085 # B[250, [4, 2, 0, 2], [37, 6, 3, 7]] - -0.000435707916552085118 # B[251, [4, 2, 0, 2], [38, 6, 4, 6]] - -0.00141960729594133419 # B[252, [4, 2, 0, 2], [39, 6, 4, 8]] - -0.000275734648504752638 # B[253, [4, 2, 0, 2], [40, 6, 5, 7]] - 0.000703286595409794617 # B[254, [4, 2, 0, 2], [41, 6, 6, 6]] - -5.55751922647368824e-05 # B[255, [4, 2, 0, 2], [42, 6, 6, 8]] - -0.000401816924228297345 # B[256, [4, 2, 0, 2], [43, 7, 0, 7]] - -0.000554714661495172429 # B[257, [4, 2, 0, 2], [44, 7, 1, 8]] - 0.00088244559527147267 # B[258, [4, 2, 0, 2], [45, 7, 2, 7]] - 0.000429487284537406104 # B[259, [4, 2, 0, 2], [46, 7, 3, 8]] - 0.000160720016534536374 # B[260, [4, 2, 0, 2], [47, 7, 4, 7]] - -0.000116046064898544729 # B[261, [4, 2, 0, 2], [48, 7, 5, 8]] - 0.00077812424584384446 # B[262, [4, 2, 0, 2], [49, 7, 6, 7]] - 0.0014223009786123353 # B[263, [4, 2, 0, 2], [50, 7, 7, 8]] - 5.45987148103492526e-05 # B[264, [4, 2, 0, 2], [51, 8, 0, 8]] - -0.00229888217343966316 # B[265, [4, 2, 0, 2], [52, 8, 2, 8]] - -0.00144376280980788169 # B[266, [4, 2, 0, 2], [53, 8, 4, 8]] - 0.000240138800657541986 # B[267, [4, 2, 0, 2], [54, 8, 6, 8]] - -4.09764373741731969e-05 # B[268, [4, 2, 0, 2], [55, 8, 8, 8]] - 0.0453826120189535706 # B[269, [5, 2, 1, 3], [5, 2, 1, 3]] - 0.00337080799390409615 # B[270, [5, 2, 1, 3], [6, 2, 2, 2]] - 0.0339316309546992961 # B[271, [5, 2, 1, 3], [7, 2, 2, 4]] - 0.00483677443671226039 # B[272, [5, 2, 1, 3], [8, 3, 0, 3]] - 0.00174954019608989774 # B[273, [5, 2, 1, 3], [9, 3, 1, 4]] - 0.00420306320210527603 # B[274, [5, 2, 1, 3], [10, 3, 2, 3]] - -0.0179939258962366969 # B[275, [5, 2, 1, 3], [11, 3, 2, 5]] - -0.01997198698308544 # B[276, [5, 2, 1, 3], [12, 3, 3, 4]] - -0.0136471344704570501 # B[277, [5, 2, 1, 3], [13, 3, 3, 6]] - -0.00203572867299816902 # B[278, [5, 2, 1, 3], [14, 4, 0, 4]] - 0.0113893698593142377 # B[279, [5, 2, 1, 3], [15, 4, 1, 5]] - -0.00283495847488346529 # B[280, [5, 2, 1, 3], [16, 4, 2, 4]] - -0.0209899506178404249 # B[281, [5, 2, 1, 3], [17, 4, 2, 6]] - 0.00307893999573658839 # B[282, [5, 2, 1, 3], [18, 4, 3, 5]] - 0.00625880909518397067 # B[283, [5, 2, 1, 3], [19, 4, 3, 7]] - 0.00109461945578659598 # B[284, [5, 2, 1, 3], [20, 4, 4, 4]] - 0.00213752786441095705 # B[285, [5, 2, 1, 3], [21, 4, 4, 6]] - -0.00379774849562602296 # B[286, [5, 2, 1, 3], [22, 4, 4, 8]] - -0.0013508169978871552 # B[287, [5, 2, 1, 3], [23, 5, 0, 5]] - 0.00921730935112183292 # B[288, [5, 2, 1, 3], [24, 5, 1, 6]] - -0.0029427132897584694 # B[289, [5, 2, 1, 3], [25, 5, 2, 5]] - 0.0013497580216050211 # B[290, [5, 2, 1, 3], [26, 5, 2, 7]] - -0.0130362734683665445 # B[291, [5, 2, 1, 3], [27, 5, 3, 6]] - 0.000858369129835153365 # B[292, [5, 2, 1, 3], [28, 5, 3, 8]] - 0.0129288669947052737 # B[293, [5, 2, 1, 3], [29, 5, 4, 5]] - -0.00373719468786774291 # B[294, [5, 2, 1, 3], [30, 5, 4, 7]] - -0.00885030928727506203 # B[295, [5, 2, 1, 3], [31, 5, 5, 6]] - 0.00285083482960970039 # B[296, [5, 2, 1, 3], [32, 5, 5, 8]] - 0.00351819863542377799 # B[297, [5, 2, 1, 3], [33, 6, 0, 6]] - -0.00783526064954031404 # B[298, [5, 2, 1, 3], [34, 6, 1, 7]] - -0.00257460837433342703 # B[299, [5, 2, 1, 3], [35, 6, 2, 6]] - -0.00421680657028429638 # B[300, [5, 2, 1, 3], [36, 6, 2, 8]] - -0.00918753516813325399 # B[301, [5, 2, 1, 3], [37, 6, 3, 7]] - -0.00316878171100497871 # B[302, [5, 2, 1, 3], [38, 6, 4, 6]] - 0.000939804682159322766 # B[303, [5, 2, 1, 3], [39, 6, 4, 8]] - -0.00618801787900946643 # B[304, [5, 2, 1, 3], [40, 6, 5, 7]] - -0.00623545765495540482 # B[305, [5, 2, 1, 3], [41, 6, 6, 6]] - 0.00519552954815065936 # B[306, [5, 2, 1, 3], [42, 6, 6, 8]] - 0.0042213652228506697 # B[307, [5, 2, 1, 3], [43, 7, 0, 7]] - 0.0113944611011103838 # B[308, [5, 2, 1, 3], [44, 7, 1, 8]] - -0.00104197865751114085 # B[309, [5, 2, 1, 3], [45, 7, 2, 7]] - -0.0087446191630695079 # B[310, [5, 2, 1, 3], [46, 7, 3, 8]] - -0.00196327596558909696 # B[311, [5, 2, 1, 3], [47, 7, 4, 7]] - -0.00447686867642808298 # B[312, [5, 2, 1, 3], [48, 7, 5, 8]] - -0.00474469665733750351 # B[313, [5, 2, 1, 3], [49, 7, 6, 7]] - -0.0059004868061462868 # B[314, [5, 2, 1, 3], [50, 7, 7, 8]] - 2.22874717926892923e-05 # B[315, [5, 2, 1, 3], [51, 8, 0, 8]] - -0.00154741089157206784 # B[316, [5, 2, 1, 3], [52, 8, 2, 8]] - 0.00417852330669051582 # B[317, [5, 2, 1, 3], [53, 8, 4, 8]] - 0.00134060860138395356 # B[318, [5, 2, 1, 3], [54, 8, 6, 8]] - -4.29219459423162489e-05 # B[319, [5, 2, 1, 3], [55, 8, 8, 8]] - 0.000319124100064731785 # B[320, [6, 2, 2, 2], [6, 2, 2, 2]] - -0.00839561599135440172 # B[321, [6, 2, 2, 2], [7, 2, 2, 4]] - -0.00326195850510992494 # B[322, [6, 2, 2, 2], [8, 3, 0, 3]] - 0.0194547426296311776 # B[323, [6, 2, 2, 2], [9, 3, 1, 4]] - -0.020516093722439413 # B[324, [6, 2, 2, 2], [10, 3, 2, 3]] - -0.00901624473884381043 # B[325, [6, 2, 2, 2], [11, 3, 2, 5]] - 0.0129026669830971837 # B[326, [6, 2, 2, 2], [12, 3, 3, 4]] - 0.00463182910296210636 # B[327, [6, 2, 2, 2], [13, 3, 3, 6]] - -0.00261498466108737743 # B[328, [6, 2, 2, 2], [14, 4, 0, 4]] - 0.0215819608660451426 # B[329, [6, 2, 2, 2], [15, 4, 1, 5]] - 0.000767688854520869957 # B[330, [6, 2, 2, 2], [16, 4, 2, 4]] - -0.00666111439578009716 # B[331, [6, 2, 2, 2], [17, 4, 2, 6]] - 0.0112705725443772303 # B[332, [6, 2, 2, 2], [18, 4, 3, 5]] - 0.00228839615631495127 # B[333, [6, 2, 2, 2], [19, 4, 3, 7]] - 0.00124148748415313414 # B[334, [6, 2, 2, 2], [20, 4, 4, 4]] - 0.00353391028977510834 # B[335, [6, 2, 2, 2], [21, 4, 4, 6]] - -0.00310464569903003834 # B[336, [6, 2, 2, 2], [22, 4, 4, 8]] - -0.001770681064288395 # B[337, [6, 2, 2, 2], [23, 5, 0, 5]] - 0.000554784469018851215 # B[338, [6, 2, 2, 2], [24, 5, 1, 6]] - -0.000102008183116791319 # B[339, [6, 2, 2, 2], [25, 5, 2, 5]] - -0.00128750706249572758 # B[340, [6, 2, 2, 2], [26, 5, 2, 7]] - 0.0046490656013451568 # B[341, [6, 2, 2, 2], [27, 5, 3, 6]] - 0.0034506831073765681 # B[342, [6, 2, 2, 2], [28, 5, 3, 8]] - 0.00501652811902741046 # B[343, [6, 2, 2, 2], [29, 5, 4, 5]] - -1.88389891915279224e-05 # B[344, [6, 2, 2, 2], [30, 5, 4, 7]] - -0.00246586719805504942 # B[345, [6, 2, 2, 2], [31, 5, 5, 6]] - -0.00339629261051872756 # B[346, [6, 2, 2, 2], [32, 5, 5, 8]] - -1.22729584505151552e-05 # B[347, [6, 2, 2, 2], [33, 6, 0, 6]] - -0.0055646406349652653 # B[348, [6, 2, 2, 2], [34, 6, 1, 7]] - 0.00216606634250279383 # B[349, [6, 2, 2, 2], [35, 6, 2, 6]] - -0.000140725603696151627 # B[350, [6, 2, 2, 2], [36, 6, 2, 8]] - -0.01190136261487338 # B[351, [6, 2, 2, 2], [37, 6, 3, 7]] - -0.000996588010308921109 # B[352, [6, 2, 2, 2], [38, 6, 4, 6]] - -0.0040124728576705895 # B[353, [6, 2, 2, 2], [39, 6, 4, 8]] - 0.000422679331586792552 # B[354, [6, 2, 2, 2], [40, 6, 5, 7]] - 0.000548939662545001959 # B[355, [6, 2, 2, 2], [41, 6, 6, 6]] - 0.00256895119228900404 # B[356, [6, 2, 2, 2], [42, 6, 6, 8]] - -0.000615139781019174688 # B[357, [6, 2, 2, 2], [43, 7, 0, 7]] - -0.00404941774617198578 # B[358, [6, 2, 2, 2], [44, 7, 1, 8]] - 0.00466754848324051064 # B[359, [6, 2, 2, 2], [45, 7, 2, 7]] - 0.00150461796185176488 # B[360, [6, 2, 2, 2], [46, 7, 3, 8]] - 0.0037489054114537468 # B[361, [6, 2, 2, 2], [47, 7, 4, 7]] - 0.00285804436398595782 # B[362, [6, 2, 2, 2], [48, 7, 5, 8]] - -0.00287521518361254919 # B[363, [6, 2, 2, 2], [49, 7, 6, 7]] - 0.000969520968104660755 # B[364, [6, 2, 2, 2], [50, 7, 7, 8]] - -0.000716125857042927043 # B[365, [6, 2, 2, 2], [51, 8, 0, 8]] - -0.00157385185114507437 # B[366, [6, 2, 2, 2], [52, 8, 2, 8]] - 0.002689243736875038 # B[367, [6, 2, 2, 2], [53, 8, 4, 8]] - -0.000661038690452418623 # B[368, [6, 2, 2, 2], [54, 8, 6, 8]] - 0.00157186481624649321 # B[369, [6, 2, 2, 2], [55, 8, 8, 8]] - -0.0134601349926017494 # B[370, [7, 2, 2, 4], [7, 2, 2, 4]] - -0.000918558149715113011 # B[371, [7, 2, 2, 4], [8, 3, 0, 3]] - -0.00377418701166061087 # B[372, [7, 2, 2, 4], [9, 3, 1, 4]] - 0.0148168734486278948 # B[373, [7, 2, 2, 4], [10, 3, 2, 3]] - -0.00535328606426562371 # B[374, [7, 2, 2, 4], [11, 3, 2, 5]] - 0.00804271469408427385 # B[375, [7, 2, 2, 4], [12, 3, 3, 4]] - 0.00136329663181449737 # B[376, [7, 2, 2, 4], [13, 3, 3, 6]] - 0.000218608555253111195 # B[377, [7, 2, 2, 4], [14, 4, 0, 4]] - 0.00767165886258287799 # B[378, [7, 2, 2, 4], [15, 4, 1, 5]] - -0.0022580429604385833 # B[379, [7, 2, 2, 4], [16, 4, 2, 4]] - -0.0050991924246220309 # B[380, [7, 2, 2, 4], [17, 4, 2, 6]] - -0.00308509180848093572 # B[381, [7, 2, 2, 4], [18, 4, 3, 5]] - -0.000900097231895549623 # B[382, [7, 2, 2, 4], [19, 4, 3, 7]] - -0.0063557020842957869 # B[383, [7, 2, 2, 4], [20, 4, 4, 4]] - -0.000409569358807882096 # B[384, [7, 2, 2, 4], [21, 4, 4, 6]] - 0.00254581400782049119 # B[385, [7, 2, 2, 4], [22, 4, 4, 8]] - 0.000657951401298526029 # B[386, [7, 2, 2, 4], [23, 5, 0, 5]] - -0.00940269729352927013 # B[387, [7, 2, 2, 4], [24, 5, 1, 6]] - 0.00333566383730494239 # B[388, [7, 2, 2, 4], [25, 5, 2, 5]] - 0.00896493308698088215 # B[389, [7, 2, 2, 4], [26, 5, 2, 7]] - 0.00132812590751918685 # B[390, [7, 2, 2, 4], [27, 5, 3, 6]] - -0.00127282140780485189 # B[391, [7, 2, 2, 4], [28, 5, 3, 8]] - -0.00435358176352772068 # B[392, [7, 2, 2, 4], [29, 5, 4, 5]] - -0.00226566527245459885 # B[393, [7, 2, 2, 4], [30, 5, 4, 7]] - 0.00326597657188156627 # B[394, [7, 2, 2, 4], [31, 5, 5, 6]] - -0.00247993076825692074 # B[395, [7, 2, 2, 4], [32, 5, 5, 8]] - -0.00138012806761597748 # B[396, [7, 2, 2, 4], [33, 6, 0, 6]] - -0.00296559266178312566 # B[397, [7, 2, 2, 4], [34, 6, 1, 7]] - -0.00345134318647404535 # B[398, [7, 2, 2, 4], [35, 6, 2, 6]] - 0.00604122282441024554 # B[399, [7, 2, 2, 4], [36, 6, 2, 8]] - -0.00602530276328681197 # B[400, [7, 2, 2, 4], [37, 6, 3, 7]] - 0.00113230868581531974 # B[401, [7, 2, 2, 4], [38, 6, 4, 6]] - 0.00132069580529702024 # B[402, [7, 2, 2, 4], [39, 6, 4, 8]] - -0.00355708848499901743 # B[403, [7, 2, 2, 4], [40, 6, 5, 7]] - 0.00103954578232134899 # B[404, [7, 2, 2, 4], [41, 6, 6, 6]] - 0.00138660655783935638 # B[405, [7, 2, 2, 4], [42, 6, 6, 8]] - 0.00122312383058832339 # B[406, [7, 2, 2, 4], [43, 7, 0, 7]] - 0.00122422070912251465 # B[407, [7, 2, 2, 4], [44, 7, 1, 8]] - -0.00497379521097694472 # B[408, [7, 2, 2, 4], [45, 7, 2, 7]] - -0.00811974704425355749 # B[409, [7, 2, 2, 4], [46, 7, 3, 8]] - 0.00114732010903773659 # B[410, [7, 2, 2, 4], [47, 7, 4, 7]] - -0.00569074628354063975 # B[411, [7, 2, 2, 4], [48, 7, 5, 8]] - 0.00235624642317577588 # B[412, [7, 2, 2, 4], [49, 7, 6, 7]] - 7.98437182146268919e-05 # B[413, [7, 2, 2, 4], [50, 7, 7, 8]] - 0.00113891921332402897 # B[414, [7, 2, 2, 4], [51, 8, 0, 8]] - -0.00492469555442132112 # B[415, [7, 2, 2, 4], [52, 8, 2, 8]] - 0.000792980352556455804 # B[416, [7, 2, 2, 4], [53, 8, 4, 8]] - 0.00153854887229367375 # B[417, [7, 2, 2, 4], [54, 8, 6, 8]] - -0.000881221748445243022 # B[418, [7, 2, 2, 4], [55, 8, 8, 8]] - -0.00136471788502227735 # B[419, [8, 3, 0, 3], [8, 3, 0, 3]] - 0.00246251727263488776 # B[420, [8, 3, 0, 3], [9, 3, 1, 4]] - 0.000996613519267240677 # B[421, [8, 3, 0, 3], [10, 3, 2, 3]] - -0.00207976146372090831 # B[422, [8, 3, 0, 3], [11, 3, 2, 5]] - -9.97509064182486305e-05 # B[423, [8, 3, 0, 3], [12, 3, 3, 4]] - 0.000656935135924852087 # B[424, [8, 3, 0, 3], [13, 3, 3, 6]] - -0.000492474229225159377 # B[425, [8, 3, 0, 3], [14, 4, 0, 4]] - 0.0032189163248994351 # B[426, [8, 3, 0, 3], [15, 4, 1, 5]] - -0.00115555104609991501 # B[427, [8, 3, 0, 3], [16, 4, 2, 4]] - -0.000101151026370576574 # B[428, [8, 3, 0, 3], [17, 4, 2, 6]] - 0.00020301152740384229 # B[429, [8, 3, 0, 3], [18, 4, 3, 5]] - -0.000285445107860462371 # B[430, [8, 3, 0, 3], [19, 4, 3, 7]] - 0.000462665925556146607 # B[431, [8, 3, 0, 3], [20, 4, 4, 4]] - -2.75652763320703015e-05 # B[432, [8, 3, 0, 3], [21, 4, 4, 6]] - -0.000358778647317398169 # B[433, [8, 3, 0, 3], [22, 4, 4, 8]] - -0.000397176131748222527 # B[434, [8, 3, 0, 3], [23, 5, 0, 5]] - -0.00026950177456114624 # B[435, [8, 3, 0, 3], [24, 5, 1, 6]] - 0.00119424632084062527 # B[436, [8, 3, 0, 3], [25, 5, 2, 5]] - 0.000922347152199163439 # B[437, [8, 3, 0, 3], [26, 5, 2, 7]] - -0.000340838509282952173 # B[438, [8, 3, 0, 3], [27, 5, 3, 6]] - 0.00128847730890532808 # B[439, [8, 3, 0, 3], [28, 5, 3, 8]] - -0.00044582191494569115 # B[440, [8, 3, 0, 3], [29, 5, 4, 5]] - -0.00114898350718379422 # B[441, [8, 3, 0, 3], [30, 5, 4, 7]] - -0.000530499767100067743 # B[442, [8, 3, 0, 3], [31, 5, 5, 6]] - 1.68864176486992895e-05 # B[443, [8, 3, 0, 3], [32, 5, 5, 8]] - -0.000312292146951373417 # B[444, [8, 3, 0, 3], [33, 6, 0, 6]] - -0.00186273440079770883 # B[445, [8, 3, 0, 3], [34, 6, 1, 7]] - -0.000475625961442131123 # B[446, [8, 3, 0, 3], [35, 6, 2, 6]] - 0.000505090975521763769 # B[447, [8, 3, 0, 3], [36, 6, 2, 8]] - 0.000128630083375533277 # B[448, [8, 3, 0, 3], [37, 6, 3, 7]] - -0.000431369283499544176 # B[449, [8, 3, 0, 3], [38, 6, 4, 6]] - 0.000461881443708941908 # B[450, [8, 3, 0, 3], [39, 6, 4, 8]] - 0.000867550860200114182 # B[451, [8, 3, 0, 3], [40, 6, 5, 7]] - 0.000179604539903628624 # B[452, [8, 3, 0, 3], [41, 6, 6, 6]] - -0.000405383988192370426 # B[453, [8, 3, 0, 3], [42, 6, 6, 8]] - -0.000305572243426546764 # B[454, [8, 3, 0, 3], [43, 7, 0, 7]] - -0.0010766931736053021 # B[455, [8, 3, 0, 3], [44, 7, 1, 8]] - 0.000701859051866787764 # B[456, [8, 3, 0, 3], [45, 7, 2, 7]] - -1.5413662061584954e-05 # B[457, [8, 3, 0, 3], [46, 7, 3, 8]] - 0.000428834666348756888 # B[458, [8, 3, 0, 3], [47, 7, 4, 7]] - 0.000468098667731533385 # B[459, [8, 3, 0, 3], [48, 7, 5, 8]] - 0.000158467988956009775 # B[460, [8, 3, 0, 3], [49, 7, 6, 7]] - 2.77948419442784408e-05 # B[461, [8, 3, 0, 3], [50, 7, 7, 8]] - -0.000282655955044820717 # B[462, [8, 3, 0, 3], [51, 8, 0, 8]] - 0.000100300940760145348 # B[463, [8, 3, 0, 3], [52, 8, 2, 8]] - 0.000314947671131902973 # B[464, [8, 3, 0, 3], [53, 8, 4, 8]] - 0.000144842823919437078 # B[465, [8, 3, 0, 3], [54, 8, 6, 8]] - 7.00050428864840146e-05 # B[466, [8, 3, 0, 3], [55, 8, 8, 8]] - 0.0118411448561217512 # B[467, [9, 3, 1, 4], [9, 3, 1, 4]] - 0.0158809314732707603 # B[468, [9, 3, 1, 4], [10, 3, 2, 3]] - -0.00690506493475962109 # B[469, [9, 3, 1, 4], [11, 3, 2, 5]] - 0.0085626937099196887 # B[470, [9, 3, 1, 4], [12, 3, 3, 4]] - -0.00387686964925252654 # B[471, [9, 3, 1, 4], [13, 3, 3, 6]] - 0.00015029200549142481 # B[472, [9, 3, 1, 4], [14, 4, 0, 4]] - -0.000142532963490632015 # B[473, [9, 3, 1, 4], [15, 4, 1, 5]] - 0.00921427022949583042 # B[474, [9, 3, 1, 4], [16, 4, 2, 4]] - -0.0112717231196791407 # B[475, [9, 3, 1, 4], [17, 4, 2, 6]] - -0.0122014182952103704 # B[476, [9, 3, 1, 4], [18, 4, 3, 5]] - -0.0111571557686284996 # B[477, [9, 3, 1, 4], [19, 4, 3, 7]] - -0.00276180055211498916 # B[478, [9, 3, 1, 4], [20, 4, 4, 4]] - -0.00444456405006457382 # B[479, [9, 3, 1, 4], [21, 4, 4, 6]] - -0.00248162623330630983 # B[480, [9, 3, 1, 4], [22, 4, 4, 8]] - 0.000238830840202226575 # B[481, [9, 3, 1, 4], [23, 5, 0, 5]] - 0.0106883008114137777 # B[482, [9, 3, 1, 4], [24, 5, 1, 6]] - -0.00176293319638371826 # B[483, [9, 3, 1, 4], [25, 5, 2, 5]] - -0.000706186990249144109 # B[484, [9, 3, 1, 4], [26, 5, 2, 7]] - -0.000957413082652629373 # B[485, [9, 3, 1, 4], [27, 5, 3, 6]] - -0.00485998335666546887 # B[486, [9, 3, 1, 4], [28, 5, 3, 8]] - -0.000739967956913101287 # B[487, [9, 3, 1, 4], [29, 5, 4, 5]] - -0.00656002591947351353 # B[488, [9, 3, 1, 4], [30, 5, 4, 7]] - -0.00191607250770065712 # B[489, [9, 3, 1, 4], [31, 5, 5, 6]] - -0.000375150046930213714 # B[490, [9, 3, 1, 4], [32, 5, 5, 8]] - 0.000379540253919751804 # B[491, [9, 3, 1, 4], [33, 6, 0, 6]] - 0.0103809997405371179 # B[492, [9, 3, 1, 4], [34, 6, 1, 7]] - -0.00167937900508645203 # B[493, [9, 3, 1, 4], [35, 6, 2, 6]] - -0.000942453027264282192 # B[494, [9, 3, 1, 4], [36, 6, 2, 8]] - -0.00358794660355351257 # B[495, [9, 3, 1, 4], [37, 6, 3, 7]] - 0.00367542903060237222 # B[496, [9, 3, 1, 4], [38, 6, 4, 6]] - -0.00605874518215254298 # B[497, [9, 3, 1, 4], [39, 6, 4, 8]] - -0.0053364107721741022 # B[498, [9, 3, 1, 4], [40, 6, 5, 7]] - -0.00220303686176452889 # B[499, [9, 3, 1, 4], [41, 6, 6, 6]] - 0.000240224733534942676 # B[500, [9, 3, 1, 4], [42, 6, 6, 8]] - 0.00118204722287629585 # B[501, [9, 3, 1, 4], [43, 7, 0, 7]] - 0.00391606544218769514 # B[502, [9, 3, 1, 4], [44, 7, 1, 8]] - -0.00190557542057654024 # B[503, [9, 3, 1, 4], [45, 7, 2, 7]] - -0.0010749256928406746 # B[504, [9, 3, 1, 4], [46, 7, 3, 8]] - 6.24186835188134462e-05 # B[505, [9, 3, 1, 4], [47, 7, 4, 7]] - -0.00250872188348977114 # B[506, [9, 3, 1, 4], [48, 7, 5, 8]] - -0.00164710314956706405 # B[507, [9, 3, 1, 4], [49, 7, 6, 7]] - -0.0029144992153610676 # B[508, [9, 3, 1, 4], [50, 7, 7, 8]] - 0.000712015267242259442 # B[509, [9, 3, 1, 4], [51, 8, 0, 8]] - -0.00179539873092394715 # B[510, [9, 3, 1, 4], [52, 8, 2, 8]] - 0.00203000698298521493 # B[511, [9, 3, 1, 4], [53, 8, 4, 8]] - -0.00103477100047664442 # B[512, [9, 3, 1, 4], [54, 8, 6, 8]] - -0.000727628763147338854 # B[513, [9, 3, 1, 4], [55, 8, 8, 8]] - 0.0163451466486591972 # B[514, [10, 3, 2, 3], [10, 3, 2, 3]] - -0.00145259448176927441 # B[515, [10, 3, 2, 3], [11, 3, 2, 5]] - -0.00808947571520425568 # B[516, [10, 3, 2, 3], [12, 3, 3, 4]] - -0.00693599935022420205 # B[517, [10, 3, 2, 3], [13, 3, 3, 6]] - -0.00419683318703741731 # B[518, [10, 3, 2, 3], [14, 4, 0, 4]] - 0.00927666204585274323 # B[519, [10, 3, 2, 3], [15, 4, 1, 5]] - -0.0138962541759877663 # B[520, [10, 3, 2, 3], [16, 4, 2, 4]] - 0.0115061801390417759 # B[521, [10, 3, 2, 3], [17, 4, 2, 6]] - 0.0118559077356181798 # B[522, [10, 3, 2, 3], [18, 4, 3, 5]] - 0.00193270595871023604 # B[523, [10, 3, 2, 3], [19, 4, 3, 7]] - 0.00156708209719190472 # B[524, [10, 3, 2, 3], [20, 4, 4, 4]] - 0.0030286948486105119 # B[525, [10, 3, 2, 3], [21, 4, 4, 6]] - -6.03736466163237034e-05 # B[526, [10, 3, 2, 3], [22, 4, 4, 8]] - -0.00147218391304548835 # B[527, [10, 3, 2, 3], [23, 5, 0, 5]] - 0.000931966019926808685 # B[528, [10, 3, 2, 3], [24, 5, 1, 6]] - 0.0153667638164197012 # B[529, [10, 3, 2, 3], [25, 5, 2, 5]] - -0.0023105273691670326 # B[530, [10, 3, 2, 3], [26, 5, 2, 7]] - 0.0018873267014898696 # B[531, [10, 3, 2, 3], [27, 5, 3, 6]] - -0.00221592978134090707 # B[532, [10, 3, 2, 3], [28, 5, 3, 8]] - 0.00175823978838723916 # B[533, [10, 3, 2, 3], [29, 5, 4, 5]] - 0.00134986143361107494 # B[534, [10, 3, 2, 3], [30, 5, 4, 7]] - -0.00280444330034939227 # B[535, [10, 3, 2, 3], [31, 5, 5, 6]] - -0.000446159575940244073 # B[536, [10, 3, 2, 3], [32, 5, 5, 8]] - 0.000126573802730074736 # B[537, [10, 3, 2, 3], [33, 6, 0, 6]] - 7.95217271451070795e-05 # B[538, [10, 3, 2, 3], [34, 6, 1, 7]] - -0.000615992203402992468 # B[539, [10, 3, 2, 3], [35, 6, 2, 6]] - -0.0106304231235931409 # B[540, [10, 3, 2, 3], [36, 6, 2, 8]] - -0.00513102234934090934 # B[541, [10, 3, 2, 3], [37, 6, 3, 7]] - 0.00086364506858761271 # B[542, [10, 3, 2, 3], [38, 6, 4, 6]] - -0.00427816275089007263 # B[543, [10, 3, 2, 3], [39, 6, 4, 8]] - -0.00709876751806875171 # B[544, [10, 3, 2, 3], [40, 6, 5, 7]] - -0.00107679083671011894 # B[545, [10, 3, 2, 3], [41, 6, 6, 6]] - -0.0014022801302571164 # B[546, [10, 3, 2, 3], [42, 6, 6, 8]] - 0.00032001340322446864 # B[547, [10, 3, 2, 3], [43, 7, 0, 7]] - 0.0099494513037338677 # B[548, [10, 3, 2, 3], [44, 7, 1, 8]] - 0.00657164457459321564 # B[549, [10, 3, 2, 3], [45, 7, 2, 7]] - -0.00193909086513409032 # B[550, [10, 3, 2, 3], [46, 7, 3, 8]] - -0.000661327911070458407 # B[551, [10, 3, 2, 3], [47, 7, 4, 7]] - -0.00236609840279333045 # B[552, [10, 3, 2, 3], [48, 7, 5, 8]] - 0.000323126961361372422 # B[553, [10, 3, 2, 3], [49, 7, 6, 7]] - 0.00156411007472663857 # B[554, [10, 3, 2, 3], [50, 7, 7, 8]] - -0.000413410696562647312 # B[555, [10, 3, 2, 3], [51, 8, 0, 8]] - 0.00151556635054790959 # B[556, [10, 3, 2, 3], [52, 8, 2, 8]] - 0.0032252808357782943 # B[557, [10, 3, 2, 3], [53, 8, 4, 8]] - 0.00431814581620697767 # B[558, [10, 3, 2, 3], [54, 8, 6, 8]] - 0.000198535493268348594 # B[559, [10, 3, 2, 3], [55, 8, 8, 8]] - 0.0156540432654675432 # B[560, [11, 3, 2, 5], [11, 3, 2, 5]] - 0.00979845476873780416 # B[561, [11, 3, 2, 5], [12, 3, 3, 4]] - 0.00873265456764509701 # B[562, [11, 3, 2, 5], [13, 3, 3, 6]] - -0.00355250352643814854 # B[563, [11, 3, 2, 5], [14, 4, 0, 4]] - 0.0197388975583387243 # B[564, [11, 3, 2, 5], [15, 4, 1, 5]] - 0.0158965586216084157 # B[565, [11, 3, 2, 5], [16, 4, 2, 4]] - 0.0126440348146513917 # B[566, [11, 3, 2, 5], [17, 4, 2, 6]] - 0.00588822462217037865 # B[567, [11, 3, 2, 5], [18, 4, 3, 5]] - 0.00465829809814364074 # B[568, [11, 3, 2, 5], [19, 4, 3, 7]] - 0.00460100330976275125 # B[569, [11, 3, 2, 5], [20, 4, 4, 4]] - 0.00507979510261629894 # B[570, [11, 3, 2, 5], [21, 4, 4, 6]] - -0.000978147842247499566 # B[571, [11, 3, 2, 5], [22, 4, 4, 8]] - 0.000175648698607325238 # B[572, [11, 3, 2, 5], [23, 5, 0, 5]] - 0.00701365729786882983 # B[573, [11, 3, 2, 5], [24, 5, 1, 6]] - 0.0124121871279893672 # B[574, [11, 3, 2, 5], [25, 5, 2, 5]] - 0.0133268604743271169 # B[575, [11, 3, 2, 5], [26, 5, 2, 7]] - -0.00306906262974302943 # B[576, [11, 3, 2, 5], [27, 5, 3, 6]] - 0.00411586711144847073 # B[577, [11, 3, 2, 5], [28, 5, 3, 8]] - -0.00483702208096517539 # B[578, [11, 3, 2, 5], [29, 5, 4, 5]] - 0.000232830853394127776 # B[579, [11, 3, 2, 5], [30, 5, 4, 7]] - -0.00500644765401524715 # B[580, [11, 3, 2, 5], [31, 5, 5, 6]] - -0.000732991087538808345 # B[581, [11, 3, 2, 5], [32, 5, 5, 8]] - 0.0028290195015726223 # B[582, [11, 3, 2, 5], [33, 6, 0, 6]] - 0.000660043236562475252 # B[583, [11, 3, 2, 5], [34, 6, 1, 7]] - 0.00858014820620479901 # B[584, [11, 3, 2, 5], [35, 6, 2, 6]] - 0.00979420830127970127 # B[585, [11, 3, 2, 5], [36, 6, 2, 8]] - -0.00276929529868128257 # B[586, [11, 3, 2, 5], [37, 6, 3, 7]] - -0.00462592209123751513 # B[587, [11, 3, 2, 5], [38, 6, 4, 6]] - 0.000957159367659247626 # B[588, [11, 3, 2, 5], [39, 6, 4, 8]] - -0.00289923459154850169 # B[589, [11, 3, 2, 5], [40, 6, 5, 7]] - -0.00605668820795574915 # B[590, [11, 3, 2, 5], [41, 6, 6, 6]] - -0.00571070540762017888 # B[591, [11, 3, 2, 5], [42, 6, 6, 8]] - 0.00247733408975375075 # B[592, [11, 3, 2, 5], [43, 7, 0, 7]] - 0.00452000165177812024 # B[593, [11, 3, 2, 5], [44, 7, 1, 8]] - 0.00267833963693382693 # B[594, [11, 3, 2, 5], [45, 7, 2, 7]] - -0.00558917145621175976 # B[595, [11, 3, 2, 5], [46, 7, 3, 8]] - -0.00228097422335522999 # B[596, [11, 3, 2, 5], [47, 7, 4, 7]] - -0.00366604043706369575 # B[597, [11, 3, 2, 5], [48, 7, 5, 8]] - -0.00340088281218112534 # B[598, [11, 3, 2, 5], [49, 7, 6, 7]] - -0.00355022426643257852 # B[599, [11, 3, 2, 5], [50, 7, 7, 8]] - 0.00124080314205340242 # B[600, [11, 3, 2, 5], [51, 8, 0, 8]] - 0.00287261267197001097 # B[601, [11, 3, 2, 5], [52, 8, 2, 8]] - 0.000744815191487350516 # B[602, [11, 3, 2, 5], [53, 8, 4, 8]] - -0.000112288931147085103 # B[603, [11, 3, 2, 5], [54, 8, 6, 8]] - -0.000128712309023326903 # B[604, [11, 3, 2, 5], [55, 8, 8, 8]] - -0.00238666366477884723 # B[605, [12, 3, 3, 4], [12, 3, 3, 4]] - 0.000248696286071804773 # B[606, [12, 3, 3, 4], [13, 3, 3, 6]] - -0.000479775127143412111 # B[607, [12, 3, 3, 4], [14, 4, 0, 4]] - 0.00175952173341571141 # B[608, [12, 3, 3, 4], [15, 4, 1, 5]] - 0.000197368498788095745 # B[609, [12, 3, 3, 4], [16, 4, 2, 4]] - 0.00726401135600521306 # B[610, [12, 3, 3, 4], [17, 4, 2, 6]] - -0.00118096336629036625 # B[611, [12, 3, 3, 4], [18, 4, 3, 5]] - 0.00702896514440041337 # B[612, [12, 3, 3, 4], [19, 4, 3, 7]] - -0.00236026619914155369 # B[613, [12, 3, 3, 4], [20, 4, 4, 4]] - -0.00341152672753146672 # B[614, [12, 3, 3, 4], [21, 4, 4, 6]] - 0.00348613231611557411 # B[615, [12, 3, 3, 4], [22, 4, 4, 8]] - 0.00244457707345889508 # B[616, [12, 3, 3, 4], [23, 5, 0, 5]] - -0.000822727235681003019 # B[617, [12, 3, 3, 4], [24, 5, 1, 6]] - -0.00248763810919495551 # B[618, [12, 3, 3, 4], [25, 5, 2, 5]] - 0.00796413115978647848 # B[619, [12, 3, 3, 4], [26, 5, 2, 7]] - -0.00179317048488774472 # B[620, [12, 3, 3, 4], [27, 5, 3, 6]] - 0.00454384820995466787 # B[621, [12, 3, 3, 4], [28, 5, 3, 8]] - -0.00425365149530766012 # B[622, [12, 3, 3, 4], [29, 5, 4, 5]] - -0.000569152560526600682 # B[623, [12, 3, 3, 4], [30, 5, 4, 7]] - -0.00506501220127485163 # B[624, [12, 3, 3, 4], [31, 5, 5, 6]] - -0.00142637122228714969 # B[625, [12, 3, 3, 4], [32, 5, 5, 8]] - 0.00190739239349446005 # B[626, [12, 3, 3, 4], [33, 6, 0, 6]] - 0.00215429853006474104 # B[627, [12, 3, 3, 4], [34, 6, 1, 7]] - 0.00512135793044871807 # B[628, [12, 3, 3, 4], [35, 6, 2, 6]] - 0.00479344551680733165 # B[629, [12, 3, 3, 4], [36, 6, 2, 8]] - -0.000813733007282164966 # B[630, [12, 3, 3, 4], [37, 6, 3, 7]] - -0.00162747725274282884 # B[631, [12, 3, 3, 4], [38, 6, 4, 6]] - -0.00440004969635155417 # B[632, [12, 3, 3, 4], [39, 6, 4, 8]] - -0.00939941153506137356 # B[633, [12, 3, 3, 4], [40, 6, 5, 7]] - -0.00314893787689287524 # B[634, [12, 3, 3, 4], [41, 6, 6, 6]] - -0.00125776748984993136 # B[635, [12, 3, 3, 4], [42, 6, 6, 8]] - 0.00129112127843685615 # B[636, [12, 3, 3, 4], [43, 7, 0, 7]] - 0.00564724346615860621 # B[637, [12, 3, 3, 4], [44, 7, 1, 8]] - -0.0018460571659526942 # B[638, [12, 3, 3, 4], [45, 7, 2, 7]] - -0.000300525523225368685 # B[639, [12, 3, 3, 4], [46, 7, 3, 8]] - -0.00277157581435865698 # B[640, [12, 3, 3, 4], [47, 7, 4, 7]] - -0.00975210406554173105 # B[641, [12, 3, 3, 4], [48, 7, 5, 8]] - -0.00233845213984289896 # B[642, [12, 3, 3, 4], [49, 7, 6, 7]] - -0.00138723239922117561 # B[643, [12, 3, 3, 4], [50, 7, 7, 8]] - 0.000864866797073243071 # B[644, [12, 3, 3, 4], [51, 8, 0, 8]] - -0.000747563068773752452 # B[645, [12, 3, 3, 4], [52, 8, 2, 8]] - 0.000965474694725087373 # B[646, [12, 3, 3, 4], [53, 8, 4, 8]] - -0.00140612646390263218 # B[647, [12, 3, 3, 4], [54, 8, 6, 8]] - -0.00149643617894318522 # B[648, [12, 3, 3, 4], [55, 8, 8, 8]] - 0.00149153681612450295 # B[649, [13, 3, 3, 6], [13, 3, 3, 6]] - -0.000954556711257832646 # B[650, [13, 3, 3, 6], [14, 4, 0, 4]] - 0.00120983585813713799 # B[651, [13, 3, 3, 6], [15, 4, 1, 5]] - 0.00300317867570911888 # B[652, [13, 3, 3, 6], [16, 4, 2, 4]] - 0.00236443796053106663 # B[653, [13, 3, 3, 6], [17, 4, 2, 6]] - 0.00415524139600132597 # B[654, [13, 3, 3, 6], [18, 4, 3, 5]] - -0.000123573851697839077 # B[655, [13, 3, 3, 6], [19, 4, 3, 7]] - 0.000470359195248265527 # B[656, [13, 3, 3, 6], [20, 4, 4, 4]] - 0.000635927641249957321 # B[657, [13, 3, 3, 6], [21, 4, 4, 6]] - 0.000747673754939660613 # B[658, [13, 3, 3, 6], [22, 4, 4, 8]] - 0.00074188846631736971 # B[659, [13, 3, 3, 6], [23, 5, 0, 5]] - 0.00463957097737913854 # B[660, [13, 3, 3, 6], [24, 5, 1, 6]] - -0.00271105182543343939 # B[661, [13, 3, 3, 6], [25, 5, 2, 5]] - 6.90411348413036419e-06 # B[662, [13, 3, 3, 6], [26, 5, 2, 7]] - 0.000911354980270381865 # B[663, [13, 3, 3, 6], [27, 5, 3, 6]] - -0.0028545746938972022 # B[664, [13, 3, 3, 6], [28, 5, 3, 8]] - -1.76062828863947363e-05 # B[665, [13, 3, 3, 6], [29, 5, 4, 5]] - -1.51206672011107435e-05 # B[666, [13, 3, 3, 6], [30, 5, 4, 7]] - -0.000798318879555708766 # B[667, [13, 3, 3, 6], [31, 5, 5, 6]] - -0.0015978026047660434 # B[668, [13, 3, 3, 6], [32, 5, 5, 8]] - 0.00034244751324807865 # B[669, [13, 3, 3, 6], [33, 6, 0, 6]] - 0.00338996797689858353 # B[670, [13, 3, 3, 6], [34, 6, 1, 7]] - 0.000289281476490772793 # B[671, [13, 3, 3, 6], [35, 6, 2, 6]] - -0.000559772151149058594 # B[672, [13, 3, 3, 6], [36, 6, 2, 8]] - -0.000650724286175463629 # B[673, [13, 3, 3, 6], [37, 6, 3, 7]] - 0.00148244897292096334 # B[674, [13, 3, 3, 6], [38, 6, 4, 6]] - 0.000183404639618602733 # B[675, [13, 3, 3, 6], [39, 6, 4, 8]] - -0.00185779692530890772 # B[676, [13, 3, 3, 6], [40, 6, 5, 7]] - -0.000708322215432564961 # B[677, [13, 3, 3, 6], [41, 6, 6, 6]] - -0.000491831969715535167 # B[678, [13, 3, 3, 6], [42, 6, 6, 8]] - 0.000833818016036214082 # B[679, [13, 3, 3, 6], [43, 7, 0, 7]] - -0.00256922900730601443 # B[680, [13, 3, 3, 6], [44, 7, 1, 8]] - -0.00112433206588518839 # B[681, [13, 3, 3, 6], [45, 7, 2, 7]] - 6.43716101358243753e-05 # B[682, [13, 3, 3, 6], [46, 7, 3, 8]] - -0.00126304972485289518 # B[683, [13, 3, 3, 6], [47, 7, 4, 7]] - -0.00210937996313975001 # B[684, [13, 3, 3, 6], [48, 7, 5, 8]] - -0.00126022676030809744 # B[685, [13, 3, 3, 6], [49, 7, 6, 7]] - -0.000555039709846411045 # B[686, [13, 3, 3, 6], [50, 7, 7, 8]] - 0.000790824100586496465 # B[687, [13, 3, 3, 6], [51, 8, 0, 8]] - -0.000844206812343649936 # B[688, [13, 3, 3, 6], [52, 8, 2, 8]] - 0.000195900027714517901 # B[689, [13, 3, 3, 6], [53, 8, 4, 8]] - -0.000823274415849936658 # B[690, [13, 3, 3, 6], [54, 8, 6, 8]] - -0.000330474595809105917 # B[691, [13, 3, 3, 6], [55, 8, 8, 8]] - -3.04835503155357485e-05 # B[692, [14, 4, 0, 4], [14, 4, 0, 4]] - -0.000825475145007361147 # B[693, [14, 4, 0, 4], [15, 4, 1, 5]] - -0.00244887111925138484 # B[694, [14, 4, 0, 4], [16, 4, 2, 4]] - -0.00122050568127611732 # B[695, [14, 4, 0, 4], [17, 4, 2, 6]] - -0.00226655265247485693 # B[696, [14, 4, 0, 4], [18, 4, 3, 5]] - -0.000767631950688907327 # B[697, [14, 4, 0, 4], [19, 4, 3, 7]] - -0.000547575812124723171 # B[698, [14, 4, 0, 4], [20, 4, 4, 4]] - -0.00121783548699544442 # B[699, [14, 4, 0, 4], [21, 4, 4, 6]] - 6.68947985199286332e-05 # B[700, [14, 4, 0, 4], [22, 4, 4, 8]] - -9.6030771921717939e-05 # B[701, [14, 4, 0, 4], [23, 5, 0, 5]] - -0.000544408900336967871 # B[702, [14, 4, 0, 4], [24, 5, 1, 6]] - -0.00139019051437529293 # B[703, [14, 4, 0, 4], [25, 5, 2, 5]] - -0.000281919324988699413 # B[704, [14, 4, 0, 4], [26, 5, 2, 7]] - -0.00125721115437776171 # B[705, [14, 4, 0, 4], [27, 5, 3, 6]] - -0.000282797770993010317 # B[706, [14, 4, 0, 4], [28, 5, 3, 8]] - -0.00139320549871079641 # B[707, [14, 4, 0, 4], [29, 5, 4, 5]] - -0.000628813518841068401 # B[708, [14, 4, 0, 4], [30, 5, 4, 7]] - -0.000607292163329276047 # B[709, [14, 4, 0, 4], [31, 5, 5, 6]] - 0.000242807689929189566 # B[710, [14, 4, 0, 4], [32, 5, 5, 8]] - -0.000100536983796830487 # B[711, [14, 4, 0, 4], [33, 6, 0, 6]] - 0.00111838401982674706 # B[712, [14, 4, 0, 4], [34, 6, 1, 7]] - -0.0012014113032742873 # B[713, [14, 4, 0, 4], [35, 6, 2, 6]] - -1.32311363260466386e-05 # B[714, [14, 4, 0, 4], [36, 6, 2, 8]] - 0.000753146180409180327 # B[715, [14, 4, 0, 4], [37, 6, 3, 7]] - -0.000270332227596856156 # B[716, [14, 4, 0, 4], [38, 6, 4, 6]] - -0.000293750660311472775 # B[717, [14, 4, 0, 4], [39, 6, 4, 8]] - 6.52480591955099942e-05 # B[718, [14, 4, 0, 4], [40, 6, 5, 7]] - -4.70588815947581285e-05 # B[719, [14, 4, 0, 4], [41, 6, 6, 6]] - 0.000244731448919628669 # B[720, [14, 4, 0, 4], [42, 6, 6, 8]] - -9.3149326930830334e-05 # B[721, [14, 4, 0, 4], [43, 7, 0, 7]] - 0.000731947904616598796 # B[722, [14, 4, 0, 4], [44, 7, 1, 8]] - -0.00107463735030771668 # B[723, [14, 4, 0, 4], [45, 7, 2, 7]] - 0.000139861959076940934 # B[724, [14, 4, 0, 4], [46, 7, 3, 8]] - 0.000101877532936889281 # B[725, [14, 4, 0, 4], [47, 7, 4, 7]] - -0.000196888502333611437 # B[726, [14, 4, 0, 4], [48, 7, 5, 8]] - 6.12030178565765859e-05 # B[727, [14, 4, 0, 4], [49, 7, 6, 7]] - -0.000223986590912481076 # B[728, [14, 4, 0, 4], [50, 7, 7, 8]] - -6.56819431667232667e-05 # B[729, [14, 4, 0, 4], [51, 8, 0, 8]] - -0.000970632773483491584 # B[730, [14, 4, 0, 4], [52, 8, 2, 8]] - -0.000182189294658170395 # B[731, [14, 4, 0, 4], [53, 8, 4, 8]] - -3.45215935849477185e-05 # B[732, [14, 4, 0, 4], [54, 8, 6, 8]] - 6.19739521221795986e-05 # B[733, [14, 4, 0, 4], [55, 8, 8, 8]] - 0.000242753902013392972 # B[734, [15, 4, 1, 5], [15, 4, 1, 5]] - 0.00729727211034517358 # B[735, [15, 4, 1, 5], [16, 4, 2, 4]] - -0.0024545495000649507 # B[736, [15, 4, 1, 5], [17, 4, 2, 6]] - -0.00265559618939786597 # B[737, [15, 4, 1, 5], [18, 4, 3, 5]] - 0.00473045463551583639 # B[738, [15, 4, 1, 5], [19, 4, 3, 7]] - -0.000140785797905494323 # B[739, [15, 4, 1, 5], [20, 4, 4, 4]] - 0.00179841698526277474 # B[740, [15, 4, 1, 5], [21, 4, 4, 6]] - 0.00129773534161339073 # B[741, [15, 4, 1, 5], [22, 4, 4, 8]] - 0.00172905697138841467 # B[742, [15, 4, 1, 5], [23, 5, 0, 5]] - -0.00408304027381215483 # B[743, [15, 4, 1, 5], [24, 5, 1, 6]] - -0.00205043992851699228 # B[744, [15, 4, 1, 5], [25, 5, 2, 5]] - 0.000756591579123801249 # B[745, [15, 4, 1, 5], [26, 5, 2, 7]] - -0.00421238291006168549 # B[746, [15, 4, 1, 5], [27, 5, 3, 6]] - -0.00196911327032830725 # B[747, [15, 4, 1, 5], [28, 5, 3, 8]] - 0.000729488918071528446 # B[748, [15, 4, 1, 5], [29, 5, 4, 5]] - -0.00177843604064341788 # B[749, [15, 4, 1, 5], [30, 5, 4, 7]] - -0.00130376966915328159 # B[750, [15, 4, 1, 5], [31, 5, 5, 6]] - -0.00198695656227435707 # B[751, [15, 4, 1, 5], [32, 5, 5, 8]] - 0.000608914142072050635 # B[752, [15, 4, 1, 5], [33, 6, 0, 6]] - -0.00109469344681823767 # B[753, [15, 4, 1, 5], [34, 6, 1, 7]] - -0.00451953523789613495 # B[754, [15, 4, 1, 5], [35, 6, 2, 6]] - 0.00279449892877900279 # B[755, [15, 4, 1, 5], [36, 6, 2, 8]] - -0.00435984465194903283 # B[756, [15, 4, 1, 5], [37, 6, 3, 7]] - 0.00275969130186590542 # B[757, [15, 4, 1, 5], [38, 6, 4, 6]] - 0.00154021904971430755 # B[758, [15, 4, 1, 5], [39, 6, 4, 8]] - -0.00146163413862035289 # B[759, [15, 4, 1, 5], [40, 6, 5, 7]] - -0.000333421796264918996 # B[760, [15, 4, 1, 5], [41, 6, 6, 6]] - -0.00139958818201657261 # B[761, [15, 4, 1, 5], [42, 6, 6, 8]] - 0.000750502250600797172 # B[762, [15, 4, 1, 5], [43, 7, 0, 7]] - 0.00476052216726493421 # B[763, [15, 4, 1, 5], [44, 7, 1, 8]] - -0.00155321215408361565 # B[764, [15, 4, 1, 5], [45, 7, 2, 7]] - -0.00351167160511536933 # B[765, [15, 4, 1, 5], [46, 7, 3, 8]] - 0.00268907735535169144 # B[766, [15, 4, 1, 5], [47, 7, 4, 7]] - -0.00296394481906553462 # B[767, [15, 4, 1, 5], [48, 7, 5, 8]] - -0.00115945739998543369 # B[768, [15, 4, 1, 5], [49, 7, 6, 7]] - -0.0011498694923236445 # B[769, [15, 4, 1, 5], [50, 7, 7, 8]] - 0.000691127444573572114 # B[770, [15, 4, 1, 5], [51, 8, 0, 8]] - 0.00149148321917135169 # B[771, [15, 4, 1, 5], [52, 8, 2, 8]] - 0.00226549729687968923 # B[772, [15, 4, 1, 5], [53, 8, 4, 8]] - -0.00127955154911817224 # B[773, [15, 4, 1, 5], [54, 8, 6, 8]] - -0.0006680598304007173 # B[774, [15, 4, 1, 5], [55, 8, 8, 8]] - 0.00773393138113156846 # B[775, [16, 4, 2, 4], [16, 4, 2, 4]] - 0.00481567776445743917 # B[776, [16, 4, 2, 4], [17, 4, 2, 6]] - 0.00646602315581837339 # B[777, [16, 4, 2, 4], [18, 4, 3, 5]] - 0.00401373256364237051 # B[778, [16, 4, 2, 4], [19, 4, 3, 7]] - -0.000224833927917125753 # B[779, [16, 4, 2, 4], [20, 4, 4, 4]] - 0.0030532060451974926 # B[780, [16, 4, 2, 4], [21, 4, 4, 6]] - -0.000126777823410560014 # B[781, [16, 4, 2, 4], [22, 4, 4, 8]] - 0.00109512376860463863 # B[782, [16, 4, 2, 4], [23, 5, 0, 5]] - 0.0014906978453806609 # B[783, [16, 4, 2, 4], [24, 5, 1, 6]] - 0.00278609484035531206 # B[784, [16, 4, 2, 4], [25, 5, 2, 5]] - 0.00720611209490516682 # B[785, [16, 4, 2, 4], [26, 5, 2, 7]] - 0.00230880055683394415 # B[786, [16, 4, 2, 4], [27, 5, 3, 6]] - 0.00492114792718315389 # B[787, [16, 4, 2, 4], [28, 5, 3, 8]] - 0.00102265649585190407 # B[788, [16, 4, 2, 4], [29, 5, 4, 5]] - -0.000348239317084679881 # B[789, [16, 4, 2, 4], [30, 5, 4, 7]] - -0.00394431438420023671 # B[790, [16, 4, 2, 4], [31, 5, 5, 6]] - -0.00362914461095884553 # B[791, [16, 4, 2, 4], [32, 5, 5, 8]] - 0.000172019923347470349 # B[792, [16, 4, 2, 4], [33, 6, 0, 6]] - -0.000316455135754767445 # B[793, [16, 4, 2, 4], [34, 6, 1, 7]] - 0.00107098215861984453 # B[794, [16, 4, 2, 4], [35, 6, 2, 6]] - -0.000907131668137324478 # B[795, [16, 4, 2, 4], [36, 6, 2, 8]] - -0.000367695081353409058 # B[796, [16, 4, 2, 4], [37, 6, 3, 7]] - 0.00181370580350630889 # B[797, [16, 4, 2, 4], [38, 6, 4, 6]] - 0.000820930060826967692 # B[798, [16, 4, 2, 4], [39, 6, 4, 8]] - -0.00466238776474962348 # B[799, [16, 4, 2, 4], [40, 6, 5, 7]] - -0.0024305728850557008 # B[800, [16, 4, 2, 4], [41, 6, 6, 6]] - -0.00165013696151081928 # B[801, [16, 4, 2, 4], [42, 6, 6, 8]] - 0.000760058338755045804 # B[802, [16, 4, 2, 4], [43, 7, 0, 7]] - -0.00203289214112462729 # B[803, [16, 4, 2, 4], [44, 7, 1, 8]] - -0.00103057221789182719 # B[804, [16, 4, 2, 4], [45, 7, 2, 7]] - 0.00188720556649034019 # B[805, [16, 4, 2, 4], [46, 7, 3, 8]] - -0.000348979964538542048 # B[806, [16, 4, 2, 4], [47, 7, 4, 7]] - -0.00595514004121479486 # B[807, [16, 4, 2, 4], [48, 7, 5, 8]] - -0.00122307692783891336 # B[808, [16, 4, 2, 4], [49, 7, 6, 7]] - -0.00161626528708522232 # B[809, [16, 4, 2, 4], [50, 7, 7, 8]] - 0.000683658453003721522 # B[810, [16, 4, 2, 4], [51, 8, 0, 8]] - 0.000169503544911074264 # B[811, [16, 4, 2, 4], [52, 8, 2, 8]] - 0.00163132840171071117 # B[812, [16, 4, 2, 4], [53, 8, 4, 8]] - -0.000633742642666999118 # B[813, [16, 4, 2, 4], [54, 8, 6, 8]] - -0.000861029784191980584 # B[814, [16, 4, 2, 4], [55, 8, 8, 8]] - 0.0101724317893582689 # B[815, [17, 4, 2, 6], [17, 4, 2, 6]] - 0.00963074903115390332 # B[816, [17, 4, 2, 6], [18, 4, 3, 5]] - 0.00792776812488414986 # B[817, [17, 4, 2, 6], [19, 4, 3, 7]] - 0.00129789596639547263 # B[818, [17, 4, 2, 6], [20, 4, 4, 4]] - 0.0025280260724625768 # B[819, [17, 4, 2, 6], [21, 4, 4, 6]] - -0.00130604081814601758 # B[820, [17, 4, 2, 6], [22, 4, 4, 8]] - 0.00061656245411057832 # B[821, [17, 4, 2, 6], [23, 5, 0, 5]] - 0.00256026791937838134 # B[822, [17, 4, 2, 6], [24, 5, 1, 6]] - 0.00833728674660196879 # B[823, [17, 4, 2, 6], [25, 5, 2, 5]] - 0.00819332084025456604 # B[824, [17, 4, 2, 6], [26, 5, 2, 7]] - 0.00199258058679730159 # B[825, [17, 4, 2, 6], [27, 5, 3, 6]] - -0.00235687406293394464 # B[826, [17, 4, 2, 6], [28, 5, 3, 8]] - 0.00172306590551023903 # B[827, [17, 4, 2, 6], [29, 5, 4, 5]] - 0.00273320921325834404 # B[828, [17, 4, 2, 6], [30, 5, 4, 7]] - 0.00124490813870011289 # B[829, [17, 4, 2, 6], [31, 5, 5, 6]] - -0.00239829497882970916 # B[830, [17, 4, 2, 6], [32, 5, 5, 8]] - 0.000403489881901454572 # B[831, [17, 4, 2, 6], [33, 6, 0, 6]] - 0.0115977289566935714 # B[832, [17, 4, 2, 6], [34, 6, 1, 7]] - 0.00631330244272786285 # B[833, [17, 4, 2, 6], [35, 6, 2, 6]] - 0.00745951676374975552 # B[834, [17, 4, 2, 6], [36, 6, 2, 8]] - 0.00129555462014044158 # B[835, [17, 4, 2, 6], [37, 6, 3, 7]] - 0.0031708889242759988 # B[836, [17, 4, 2, 6], [38, 6, 4, 6]] - 0.00314059501950873093 # B[837, [17, 4, 2, 6], [39, 6, 4, 8]] - -0.00157311519106628078 # B[838, [17, 4, 2, 6], [40, 6, 5, 7]] - -0.000535633835711041804 # B[839, [17, 4, 2, 6], [41, 6, 6, 6]] - -0.00106218347026977491 # B[840, [17, 4, 2, 6], [42, 6, 6, 8]] - 0.00171130648037900839 # B[841, [17, 4, 2, 6], [43, 7, 0, 7]] - 0.00318381348777509654 # B[842, [17, 4, 2, 6], [44, 7, 1, 8]] - 0.00121186975917000981 # B[843, [17, 4, 2, 6], [45, 7, 2, 7]] - -0.00505226933268299559 # B[844, [17, 4, 2, 6], [46, 7, 3, 8]] - 0.000505489038324865442 # B[845, [17, 4, 2, 6], [47, 7, 4, 7]] - -0.00260650572816220009 # B[846, [17, 4, 2, 6], [48, 7, 5, 8]] - -0.00458388666826989831 # B[847, [17, 4, 2, 6], [49, 7, 6, 7]] - -0.0030323259618317824 # B[848, [17, 4, 2, 6], [50, 7, 7, 8]] - 0.000919810997489799165 # B[849, [17, 4, 2, 6], [51, 8, 0, 8]] - 0.00153843620323466154 # B[850, [17, 4, 2, 6], [52, 8, 2, 8]] - 0.00177452104337356975 # B[851, [17, 4, 2, 6], [53, 8, 4, 8]] - -0.00133363365246129796 # B[852, [17, 4, 2, 6], [54, 8, 6, 8]] - 0.000497168699576265929 # B[853, [17, 4, 2, 6], [55, 8, 8, 8]] - 0.00916493227652732945 # B[854, [18, 4, 3, 5], [18, 4, 3, 5]] - 0.00662893191875722591 # B[855, [18, 4, 3, 5], [19, 4, 3, 7]] - 0.00102473567933248147 # B[856, [18, 4, 3, 5], [20, 4, 4, 4]] - 0.000661293664462594619 # B[857, [18, 4, 3, 5], [21, 4, 4, 6]] - 0.00302383517430961438 # B[858, [18, 4, 3, 5], [22, 4, 4, 8]] - 0.00182134236384280147 # B[859, [18, 4, 3, 5], [23, 5, 0, 5]] - 0.00481003527044247467 # B[860, [18, 4, 3, 5], [24, 5, 1, 6]] - 0.00472221587821478311 # B[861, [18, 4, 3, 5], [25, 5, 2, 5]] - 0.00204855894682247092 # B[862, [18, 4, 3, 5], [26, 5, 2, 7]] - 0.00108437129165206425 # B[863, [18, 4, 3, 5], [27, 5, 3, 6]] - 0.000188071259560827417 # B[864, [18, 4, 3, 5], [28, 5, 3, 8]] - 0.000402244806083140727 # B[865, [18, 4, 3, 5], [29, 5, 4, 5]] - 0.00350511561101824257 # B[866, [18, 4, 3, 5], [30, 5, 4, 7]] - -0.00196731170271619883 # B[867, [18, 4, 3, 5], [31, 5, 5, 6]] - -0.000854471064769226317 # B[868, [18, 4, 3, 5], [32, 5, 5, 8]] - 0.00163753590726098495 # B[869, [18, 4, 3, 5], [33, 6, 0, 6]] - 0.00678767470498069323 # B[870, [18, 4, 3, 5], [34, 6, 1, 7]] - 0.00671898362129526739 # B[871, [18, 4, 3, 5], [35, 6, 2, 6]] - 0.00504150139406711259 # B[872, [18, 4, 3, 5], [36, 6, 2, 8]] - -0.00150058947564556469 # B[873, [18, 4, 3, 5], [37, 6, 3, 7]] - 0.00126561580055304518 # B[874, [18, 4, 3, 5], [38, 6, 4, 6]] - -0.000556565865268397481 # B[875, [18, 4, 3, 5], [39, 6, 4, 8]] - -0.00527488386402661519 # B[876, [18, 4, 3, 5], [40, 6, 5, 7]] - -0.00214157468754809163 # B[877, [18, 4, 3, 5], [41, 6, 6, 6]] - -0.0020431148178264337 # B[878, [18, 4, 3, 5], [42, 6, 6, 8]] - 0.00142704628054338232 # B[879, [18, 4, 3, 5], [43, 7, 0, 7]] - 0.00368882624306161085 # B[880, [18, 4, 3, 5], [44, 7, 1, 8]] - -0.000742447358153045661 # B[881, [18, 4, 3, 5], [45, 7, 2, 7]] - -0.00158678830901623838 # B[882, [18, 4, 3, 5], [46, 7, 3, 8]] - -0.00107876302160130055 # B[883, [18, 4, 3, 5], [47, 7, 4, 7]] - -0.00701537311445033646 # B[884, [18, 4, 3, 5], [48, 7, 5, 8]] - -0.00184801443295596127 # B[885, [18, 4, 3, 5], [49, 7, 6, 7]] - -0.00127678697871524667 # B[886, [18, 4, 3, 5], [50, 7, 7, 8]] - 0.00105641109188138113 # B[887, [18, 4, 3, 5], [51, 8, 0, 8]] - 0.000718098622203026428 # B[888, [18, 4, 3, 5], [52, 8, 2, 8]] - 0.00219486004289275692 # B[889, [18, 4, 3, 5], [53, 8, 4, 8]] - -0.00158748993130468905 # B[890, [18, 4, 3, 5], [54, 8, 6, 8]] - -0.00105128398142791644 # B[891, [18, 4, 3, 5], [55, 8, 8, 8]] - -0.00705876763301777586 # B[892, [19, 4, 3, 7], [19, 4, 3, 7]] - 0.00377186011578763136 # B[893, [19, 4, 3, 7], [20, 4, 4, 4]] - 0.00351225097737749986 # B[894, [19, 4, 3, 7], [21, 4, 4, 6]] - -0.00323798036048509805 # B[895, [19, 4, 3, 7], [22, 4, 4, 8]] - 0.00126225430824061444 # B[896, [19, 4, 3, 7], [23, 5, 0, 5]] - -0.00132900767543010258 # B[897, [19, 4, 3, 7], [24, 5, 1, 6]] - 0.000212743875668733318 # B[898, [19, 4, 3, 7], [25, 5, 2, 5]] - -8.93559293989563963e-05 # B[899, [19, 4, 3, 7], [26, 5, 2, 7]] - 0.00401415269432878544 # B[900, [19, 4, 3, 7], [27, 5, 3, 6]] - -0.00422923196125859352 # B[901, [19, 4, 3, 7], [28, 5, 3, 8]] - 0.00252733635050122335 # B[902, [19, 4, 3, 7], [29, 5, 4, 5]] - -0.00020969110581340808 # B[903, [19, 4, 3, 7], [30, 5, 4, 7]] - -0.000969147769818896193 # B[904, [19, 4, 3, 7], [31, 5, 5, 6]] - -0.00249817386761041864 # B[905, [19, 4, 3, 7], [32, 5, 5, 8]] - 7.71120512828363247e-05 # B[906, [19, 4, 3, 7], [33, 6, 0, 6]] - 0.00560302176075209817 # B[907, [19, 4, 3, 7], [34, 6, 1, 7]] - 0.00342833731167378752 # B[908, [19, 4, 3, 7], [35, 6, 2, 6]] - 0.00116548365936076578 # B[909, [19, 4, 3, 7], [36, 6, 2, 8]] - 0.00499590856190199745 # B[910, [19, 4, 3, 7], [37, 6, 3, 7]] - 0.00391644837067879614 # B[911, [19, 4, 3, 7], [38, 6, 4, 6]] - 0.00116606811408420229 # B[912, [19, 4, 3, 7], [39, 6, 4, 8]] - -0.000563820914290556058 # B[913, [19, 4, 3, 7], [40, 6, 5, 7]] - -0.000251464925992161276 # B[914, [19, 4, 3, 7], [41, 6, 6, 6]] - -0.000718753250305587815 # B[915, [19, 4, 3, 7], [42, 6, 6, 8]] - 0.000453024387943248494 # B[916, [19, 4, 3, 7], [43, 7, 0, 7]] - -0.00146422451962339994 # B[917, [19, 4, 3, 7], [44, 7, 1, 8]] - 0.00271974781140060795 # B[918, [19, 4, 3, 7], [45, 7, 2, 7]] - 0.00151707017829591159 # B[919, [19, 4, 3, 7], [46, 7, 3, 8]] - 0.00202377896423465691 # B[920, [19, 4, 3, 7], [47, 7, 4, 7]] - -0.00131185948123999779 # B[921, [19, 4, 3, 7], [48, 7, 5, 8]] - 0.000239464941185672797 # B[922, [19, 4, 3, 7], [49, 7, 6, 7]] - -0.000667571478871501964 # B[923, [19, 4, 3, 7], [50, 7, 7, 8]] - 0.000666789360176615192 # B[924, [19, 4, 3, 7], [51, 8, 0, 8]] - 0.00179543252151156355 # B[925, [19, 4, 3, 7], [52, 8, 2, 8]] - 0.000954396542852647967 # B[926, [19, 4, 3, 7], [53, 8, 4, 8]] - 0.000593331439814590023 # B[927, [19, 4, 3, 7], [54, 8, 6, 8]] - -0.000292670120459602445 # B[928, [19, 4, 3, 7], [55, 8, 8, 8]] - -0.000303353861178074294 # B[929, [20, 4, 4, 4], [20, 4, 4, 4]] - -6.41585335468541906e-05 # B[930, [20, 4, 4, 4], [21, 4, 4, 6]] - 0.00145464895340288725 # B[931, [20, 4, 4, 4], [22, 4, 4, 8]] - 0.000557677559397141802 # B[932, [20, 4, 4, 4], [23, 5, 0, 5]] - 0.00214733001664968188 # B[933, [20, 4, 4, 4], [24, 5, 1, 6]] - 0.000196804226194771757 # B[934, [20, 4, 4, 4], [25, 5, 2, 5]] - 0.00169621771662652795 # B[935, [20, 4, 4, 4], [26, 5, 2, 7]] - -0.00126951106424718924 # B[936, [20, 4, 4, 4], [27, 5, 3, 6]] - 0.00156201190059711802 # B[937, [20, 4, 4, 4], [28, 5, 3, 8]] - -0.000188505112089858498 # B[938, [20, 4, 4, 4], [29, 5, 4, 5]] - 0.00101485096974841295 # B[939, [20, 4, 4, 4], [30, 5, 4, 7]] - -0.000254023094278113288 # B[940, [20, 4, 4, 4], [31, 5, 5, 6]] - -0.000332430225508446864 # B[941, [20, 4, 4, 4], [32, 5, 5, 8]] - 0.000393172799404761797 # B[942, [20, 4, 4, 4], [33, 6, 0, 6]] - -0.000945851456653874594 # B[943, [20, 4, 4, 4], [34, 6, 1, 7]] - 0.000937118523093692299 # B[944, [20, 4, 4, 4], [35, 6, 2, 6]] - 0.00108463610451345858 # B[945, [20, 4, 4, 4], [36, 6, 2, 8]] - -0.00167878968186336089 # B[946, [20, 4, 4, 4], [37, 6, 3, 7]] - 0.000109649976457827647 # B[947, [20, 4, 4, 4], [38, 6, 4, 6]] - 0.000205908523746248934 # B[948, [20, 4, 4, 4], [39, 6, 4, 8]] - -0.000952641271225448949 # B[949, [20, 4, 4, 4], [40, 6, 5, 7]] - -0.000386842165161269298 # B[950, [20, 4, 4, 4], [41, 6, 6, 6]] - -0.000662992329463731739 # B[951, [20, 4, 4, 4], [42, 6, 6, 8]] - 0.000368522676488847178 # B[952, [20, 4, 4, 4], [43, 7, 0, 7]] - -0.000181924614212486402 # B[953, [20, 4, 4, 4], [44, 7, 1, 8]] - -0.00119374010493299761 # B[954, [20, 4, 4, 4], [45, 7, 2, 7]] - -0.000775398926021152179 # B[955, [20, 4, 4, 4], [46, 7, 3, 8]] - -0.000670782103704289923 # B[956, [20, 4, 4, 4], [47, 7, 4, 7]] - -0.00192682764111087456 # B[957, [20, 4, 4, 4], [48, 7, 5, 8]] - -0.000648663865567958298 # B[958, [20, 4, 4, 4], [49, 7, 6, 7]] - -0.000387954189232417312 # B[959, [20, 4, 4, 4], [50, 7, 7, 8]] - 0.000302370648048068055 # B[960, [20, 4, 4, 4], [51, 8, 0, 8]] - -0.00085980088667597307 # B[961, [20, 4, 4, 4], [52, 8, 2, 8]] - 0.000568399123124077588 # B[962, [20, 4, 4, 4], [53, 8, 4, 8]] - -0.000482151590861096269 # B[963, [20, 4, 4, 4], [54, 8, 6, 8]] - -0.000405828455879983507 # B[964, [20, 4, 4, 4], [55, 8, 8, 8]] - 0.00165997230068267755 # B[965, [21, 4, 4, 6], [21, 4, 4, 6]] - 0.000963896255597472551 # B[966, [21, 4, 4, 6], [22, 4, 4, 8]] - 0.0002094521100325826 # B[967, [21, 4, 4, 6], [23, 5, 0, 5]] - 0.000534879644705995444 # B[968, [21, 4, 4, 6], [24, 5, 1, 6]] - 0.00292236533791157905 # B[969, [21, 4, 4, 6], [25, 5, 2, 5]] - 0.00151524368635043427 # B[970, [21, 4, 4, 6], [26, 5, 2, 7]] - -0.00101689007388491501 # B[971, [21, 4, 4, 6], [27, 5, 3, 6]] - 0.000738459806183821427 # B[972, [21, 4, 4, 6], [28, 5, 3, 8]] - 0.00148643764242684627 # B[973, [21, 4, 4, 6], [29, 5, 4, 5]] - 0.0011556877894129472 # B[974, [21, 4, 4, 6], [30, 5, 4, 7]] - -0.000208381440186615127 # B[975, [21, 4, 4, 6], [31, 5, 5, 6]] - -0.00143743030752817389 # B[976, [21, 4, 4, 6], [32, 5, 5, 8]] - -0.00016600302639456152 # B[977, [21, 4, 4, 6], [33, 6, 0, 6]] - 0.00172160125073629253 # B[978, [21, 4, 4, 6], [34, 6, 1, 7]] - 0.00344812165058533751 # B[979, [21, 4, 4, 6], [35, 6, 2, 6]] - 0.000544104512334869089 # B[980, [21, 4, 4, 6], [36, 6, 2, 8]] - -0.00182558144376257503 # B[981, [21, 4, 4, 6], [37, 6, 3, 7]] - 0.00101065848983370246 # B[982, [21, 4, 4, 6], [38, 6, 4, 6]] - 0.00103400096073465869 # B[983, [21, 4, 4, 6], [39, 6, 4, 8]] - -0.000235944095127582111 # B[984, [21, 4, 4, 6], [40, 6, 5, 7]] - 0.000154580830205655606 # B[985, [21, 4, 4, 6], [41, 6, 6, 6]] - -0.000488680460493023505 # B[986, [21, 4, 4, 6], [42, 6, 6, 8]] - 3.83739714257189113e-05 # B[987, [21, 4, 4, 6], [43, 7, 0, 7]] - -0.000275037336268196993 # B[988, [21, 4, 4, 6], [44, 7, 1, 8]] - 0.0017878021157122859 # B[989, [21, 4, 4, 6], [45, 7, 2, 7]] - -0.00110857713686632331 # B[990, [21, 4, 4, 6], [46, 7, 3, 8]] - -0.000126074852562767237 # B[991, [21, 4, 4, 6], [47, 7, 4, 7]] - -0.00125862858469075189 # B[992, [21, 4, 4, 6], [48, 7, 5, 8]] - -0.000277638160776805254 # B[993, [21, 4, 4, 6], [49, 7, 6, 7]] - 0.000163335859971639602 # B[994, [21, 4, 4, 6], [50, 7, 7, 8]] - 0.000151747507838979889 # B[995, [21, 4, 4, 6], [51, 8, 0, 8]] - 0.00156180455186682998 # B[996, [21, 4, 4, 6], [52, 8, 2, 8]] - 0.00112614353705531994 # B[997, [21, 4, 4, 6], [53, 8, 4, 8]] - -0.000376140365477903652 # B[998, [21, 4, 4, 6], [54, 8, 6, 8]] - -0.000378786757414536351 # B[999, [21, 4, 4, 6], [55, 8, 8, 8]] - -0.00186381195965971969 # B[1000, [22, 4, 4, 8], [22, 4, 4, 8]] - 0.000334060235611270684 # B[1001, [22, 4, 4, 8], [23, 5, 0, 5]] - -0.000182139490643212255 # B[1002, [22, 4, 4, 8], [24, 5, 1, 6]] - -0.000866414678376911532 # B[1003, [22, 4, 4, 8], [25, 5, 2, 5]] - -0.000713836573909394211 # B[1004, [22, 4, 4, 8], [26, 5, 2, 7]] - 0.00340359387460056721 # B[1005, [22, 4, 4, 8], [27, 5, 3, 6]] - -0.0025631762232975969 # B[1006, [22, 4, 4, 8], [28, 5, 3, 8]] - 0.00154837338005092001 # B[1007, [22, 4, 4, 8], [29, 5, 4, 5]] - -0.000713785025005329171 # B[1008, [22, 4, 4, 8], [30, 5, 4, 7]] - -6.17852167664190155e-06 # B[1009, [22, 4, 4, 8], [31, 5, 5, 6]] - -0.000925788250245492385 # B[1010, [22, 4, 4, 8], [32, 5, 5, 8]] - -0.000220618203180443506 # B[1011, [22, 4, 4, 8], [33, 6, 0, 6]] - 0.00158760304062654546 # B[1012, [22, 4, 4, 8], [34, 6, 1, 7]] - -0.00201296543384867077 # B[1013, [22, 4, 4, 8], [35, 6, 2, 6]] - -0.000153111573438037551 # B[1014, [22, 4, 4, 8], [36, 6, 2, 8]] - 0.001936342943994784 # B[1015, [22, 4, 4, 8], [37, 6, 3, 7]] - 0.0014724303902098404 # B[1016, [22, 4, 4, 8], [38, 6, 4, 6]] - 0.000412977919829218137 # B[1017, [22, 4, 4, 8], [39, 6, 4, 8]] - 0.000243129124011996767 # B[1018, [22, 4, 4, 8], [40, 6, 5, 7]] - 0.000433542078585167322 # B[1019, [22, 4, 4, 8], [41, 6, 6, 6]] - 5.87712210821707964e-05 # B[1020, [22, 4, 4, 8], [42, 6, 6, 8]] - -2.13873587015245281e-05 # B[1021, [22, 4, 4, 8], [43, 7, 0, 7]] - -0.00121671500578664389 # B[1022, [22, 4, 4, 8], [44, 7, 1, 8]] - 0.00185443425860575776 # B[1023, [22, 4, 4, 8], [45, 7, 2, 7]] - 0.00153976874095648406 # B[1024, [22, 4, 4, 8], [46, 7, 3, 8]] - 0.00100585852984078766 # B[1025, [22, 4, 4, 8], [47, 7, 4, 7]] - 0.000146502145157426621 # B[1026, [22, 4, 4, 8], [48, 7, 5, 8]] - 0.00026572798098887726 # B[1027, [22, 4, 4, 8], [49, 7, 6, 7]] - 0.000239744529446223043 # B[1028, [22, 4, 4, 8], [50, 7, 7, 8]] - 3.13331575558552233e-05 # B[1029, [22, 4, 4, 8], [51, 8, 0, 8]] - 0.0005761629631739415 # B[1030, [22, 4, 4, 8], [52, 8, 2, 8]] - 0.00020451472183747807 # B[1031, [22, 4, 4, 8], [53, 8, 4, 8]] - 0.000761501707699011737 # B[1032, [22, 4, 4, 8], [54, 8, 6, 8]] - 4.7608269104475881e-05 # B[1033, [22, 4, 4, 8], [55, 8, 8, 8]] - 0.00010288893231941848 # B[1034, [23, 5, 0, 5], [23, 5, 0, 5]] - -0.000598160679614365143 # B[1035, [23, 5, 0, 5], [24, 5, 1, 6]] - -0.000125600887517359969 # B[1036, [23, 5, 0, 5], [25, 5, 2, 5]] - -0.000541602347577959872 # B[1037, [23, 5, 0, 5], [26, 5, 2, 7]] - 0.000138742295315047448 # B[1038, [23, 5, 0, 5], [27, 5, 3, 6]] - 0.000320496112291311641 # B[1039, [23, 5, 0, 5], [28, 5, 3, 8]] - 9.77076363189860464e-05 # B[1040, [23, 5, 0, 5], [29, 5, 4, 5]] - -0.00018519393057754574 # B[1041, [23, 5, 0, 5], [30, 5, 4, 7]] - -0.000314308790209320843 # B[1042, [23, 5, 0, 5], [31, 5, 5, 6]] - -2.03507196530547385e-05 # B[1043, [23, 5, 0, 5], [32, 5, 5, 8]] - -8.76692912155085935e-08 # B[1044, [23, 5, 0, 5], [33, 6, 0, 6]] - -0.000208914241663854874 # B[1045, [23, 5, 0, 5], [34, 6, 1, 7]] - 0.000289191305925793653 # B[1046, [23, 5, 0, 5], [35, 6, 2, 6]] - 0.000292827060287376498 # B[1047, [23, 5, 0, 5], [36, 6, 2, 8]] - -0.000195999965143696386 # B[1048, [23, 5, 0, 5], [37, 6, 3, 7]] - 0.000122837407081860615 # B[1049, [23, 5, 0, 5], [38, 6, 4, 6]] - 0.000238061673948679331 # B[1050, [23, 5, 0, 5], [39, 6, 4, 8]] - 6.23458911314621333e-06 # B[1051, [23, 5, 0, 5], [40, 6, 5, 7]] - 0.000153645644536796327 # B[1052, [23, 5, 0, 5], [41, 6, 6, 6]] - 0.000208144485879115104 # B[1053, [23, 5, 0, 5], [42, 6, 6, 8]] - 0.000107382317423423967 # B[1054, [23, 5, 0, 5], [43, 7, 0, 7]] - -3.16437877474207152e-05 # B[1055, [23, 5, 0, 5], [44, 7, 1, 8]] - 5.2567890411161361e-05 # B[1056, [23, 5, 0, 5], [45, 7, 2, 7]] - -0.000407365287815795313 # B[1057, [23, 5, 0, 5], [46, 7, 3, 8]] - -0.000277007442936893014 # B[1058, [23, 5, 0, 5], [47, 7, 4, 7]] - -0.000163960409271388802 # B[1059, [23, 5, 0, 5], [48, 7, 5, 8]] - -0.00018222236229294142 # B[1060, [23, 5, 0, 5], [49, 7, 6, 7]] - -8.93725149996096868e-05 # B[1061, [23, 5, 0, 5], [50, 7, 7, 8]] - -4.59835267753172516e-05 # B[1062, [23, 5, 0, 5], [51, 8, 0, 8]] - -3.00980967951527262e-05 # B[1063, [23, 5, 0, 5], [52, 8, 2, 8]] - -0.00011786089545340328 # B[1064, [23, 5, 0, 5], [53, 8, 4, 8]] - 6.24840877215676604e-05 # B[1065, [23, 5, 0, 5], [54, 8, 6, 8]] - 0.000151333518371397913 # B[1066, [23, 5, 0, 5], [55, 8, 8, 8]] - -0.00373509601310103353 # B[1067, [24, 5, 1, 6], [24, 5, 1, 6]] - 0.00250350668234289742 # B[1068, [24, 5, 1, 6], [25, 5, 2, 5]] - -0.00141763987470412255 # B[1069, [24, 5, 1, 6], [26, 5, 2, 7]] - -0.000458490741576836162 # B[1070, [24, 5, 1, 6], [27, 5, 3, 6]] - 0.000169432811229417585 # B[1071, [24, 5, 1, 6], [28, 5, 3, 8]] - -0.000531768848310092699 # B[1072, [24, 5, 1, 6], [29, 5, 4, 5]] - 0.0019269207337581605 # B[1073, [24, 5, 1, 6], [30, 5, 4, 7]] - 0.000623468915929115824 # B[1074, [24, 5, 1, 6], [31, 5, 5, 6]] - 0.000262459747020924762 # B[1075, [24, 5, 1, 6], [32, 5, 5, 8]] - 0.000319464830252011445 # B[1076, [24, 5, 1, 6], [33, 6, 0, 6]] - 0.00250974732963905444 # B[1077, [24, 5, 1, 6], [34, 6, 1, 7]] - 0.00423653007687384807 # B[1078, [24, 5, 1, 6], [35, 6, 2, 6]] - 0.00144771358428595707 # B[1079, [24, 5, 1, 6], [36, 6, 2, 8]] - 0.00255496505633429419 # B[1080, [24, 5, 1, 6], [37, 6, 3, 7]] - -0.000923899857380450218 # B[1081, [24, 5, 1, 6], [38, 6, 4, 6]] - -0.000308666389289608337 # B[1082, [24, 5, 1, 6], [39, 6, 4, 8]] - 0.00222537659577300671 # B[1083, [24, 5, 1, 6], [40, 6, 5, 7]] - -0.00107541311587263343 # B[1084, [24, 5, 1, 6], [41, 6, 6, 6]] - -0.00278767944085371068 # B[1085, [24, 5, 1, 6], [42, 6, 6, 8]] - -0.000867530969177243705 # B[1086, [24, 5, 1, 6], [43, 7, 0, 7]] - 0.00357297895621819196 # B[1087, [24, 5, 1, 6], [44, 7, 1, 8]] - 0.00383976572090019216 # B[1088, [24, 5, 1, 6], [45, 7, 2, 7]] - -0.000580234942856992786 # B[1089, [24, 5, 1, 6], [46, 7, 3, 8]] - 0.00102888910081111798 # B[1090, [24, 5, 1, 6], [47, 7, 4, 7]] - 0.00132107614311613355 # B[1091, [24, 5, 1, 6], [48, 7, 5, 8]] - 0.00101848252621374036 # B[1092, [24, 5, 1, 6], [49, 7, 6, 7]] - 0.00160018234143227862 # B[1093, [24, 5, 1, 6], [50, 7, 7, 8]] - -5.52824024903572631e-05 # B[1094, [24, 5, 1, 6], [51, 8, 0, 8]] - 4.59186780197786033e-05 # B[1095, [24, 5, 1, 6], [52, 8, 2, 8]] - -0.000153436254581188554 # B[1096, [24, 5, 1, 6], [53, 8, 4, 8]] - -0.000546750998621967597 # B[1097, [24, 5, 1, 6], [54, 8, 6, 8]] - 0.000595956738118895348 # B[1098, [24, 5, 1, 6], [55, 8, 8, 8]] - 0.0083807047595118693 # B[1099, [25, 5, 2, 5], [25, 5, 2, 5]] - -0.000170544318645505719 # B[1100, [25, 5, 2, 5], [26, 5, 2, 7]] - 0.00235544441902155004 # B[1101, [25, 5, 2, 5], [27, 5, 3, 6]] - -0.00340197827063909962 # B[1102, [25, 5, 2, 5], [28, 5, 3, 8]] - 0.00311335525578198104 # B[1103, [25, 5, 2, 5], [29, 5, 4, 5]] - 0.00185214714164834123 # B[1104, [25, 5, 2, 5], [30, 5, 4, 7]] - -0.00328905913600528992 # B[1105, [25, 5, 2, 5], [31, 5, 5, 6]] - -0.00141866010082636025 # B[1106, [25, 5, 2, 5], [32, 5, 5, 8]] - 0.000176317033907393006 # B[1107, [25, 5, 2, 5], [33, 6, 0, 6]] - 0.00648328973805229608 # B[1108, [25, 5, 2, 5], [34, 6, 1, 7]] - 4.8980528358618259e-05 # B[1109, [25, 5, 2, 5], [35, 6, 2, 6]] - -0.00616971046300731144 # B[1110, [25, 5, 2, 5], [36, 6, 2, 8]] - -0.00135942372726050205 # B[1111, [25, 5, 2, 5], [37, 6, 3, 7]] - 0.000572735024796908881 # B[1112, [25, 5, 2, 5], [38, 6, 4, 6]] - -0.00229752149848994405 # B[1113, [25, 5, 2, 5], [39, 6, 4, 8]] - 0.0003485310815041524 # B[1114, [25, 5, 2, 5], [40, 6, 5, 7]] - -0.0011437361439647427 # B[1115, [25, 5, 2, 5], [41, 6, 6, 6]] - -0.000604819873822432311 # B[1116, [25, 5, 2, 5], [42, 6, 6, 8]] - 9.06237770597643696e-05 # B[1117, [25, 5, 2, 5], [43, 7, 0, 7]] - -0.000382141545017884894 # B[1118, [25, 5, 2, 5], [44, 7, 1, 8]] - -0.000842464094047663554 # B[1119, [25, 5, 2, 5], [45, 7, 2, 7]] - 0.000461973830441065811 # B[1120, [25, 5, 2, 5], [46, 7, 3, 8]] - 2.86192620363814355e-06 # B[1121, [25, 5, 2, 5], [47, 7, 4, 7]] - -0.0023436531447123838 # B[1122, [25, 5, 2, 5], [48, 7, 5, 8]] - 0.00134025173860287308 # B[1123, [25, 5, 2, 5], [49, 7, 6, 7]] - -0.000520013981518205846 # B[1124, [25, 5, 2, 5], [50, 7, 7, 8]] - 0.000515782740310496285 # B[1125, [25, 5, 2, 5], [51, 8, 0, 8]] - 0.00421651313615256564 # B[1126, [25, 5, 2, 5], [52, 8, 2, 8]] - 0.000755327719218409519 # B[1127, [25, 5, 2, 5], [53, 8, 4, 8]] - 0.000182937308412391315 # B[1128, [25, 5, 2, 5], [54, 8, 6, 8]] - 8.10383680097163071e-05 # B[1129, [25, 5, 2, 5], [55, 8, 8, 8]] - 0.000177735296666065024 # B[1130, [26, 5, 2, 7], [26, 5, 2, 7]] - -0.000642334677407747565 # B[1131, [26, 5, 2, 7], [27, 5, 3, 6]] - 0.000205172894139061396 # B[1132, [26, 5, 2, 7], [28, 5, 3, 8]] - -0.000537004220752698019 # B[1133, [26, 5, 2, 7], [29, 5, 4, 5]] - 5.14115941491347442e-05 # B[1134, [26, 5, 2, 7], [30, 5, 4, 7]] - 0.000417673445165051005 # B[1135, [26, 5, 2, 7], [31, 5, 5, 6]] - 0.00158446769775330391 # B[1136, [26, 5, 2, 7], [32, 5, 5, 8]] - 0.00121383407410429606 # B[1137, [26, 5, 2, 7], [33, 6, 0, 6]] - -0.00111992976945914785 # B[1138, [26, 5, 2, 7], [34, 6, 1, 7]] - 0.00398972286341117699 # B[1139, [26, 5, 2, 7], [35, 6, 2, 6]] - 0.00454565411209783762 # B[1140, [26, 5, 2, 7], [36, 6, 2, 8]] - -0.00300928796618537761 # B[1141, [26, 5, 2, 7], [37, 6, 3, 7]] - -0.00280024702462813163 # B[1142, [26, 5, 2, 7], [38, 6, 4, 6]] - 0.00182097597359056305 # B[1143, [26, 5, 2, 7], [39, 6, 4, 8]] - 0.00247143387165752772 # B[1144, [26, 5, 2, 7], [40, 6, 5, 7]] - -0.00143698477566456435 # B[1145, [26, 5, 2, 7], [41, 6, 6, 6]] - -0.00105878554545993375 # B[1146, [26, 5, 2, 7], [42, 6, 6, 8]] - 0.000650619036842032747 # B[1147, [26, 5, 2, 7], [43, 7, 0, 7]] - 8.72947879012740853e-05 # B[1148, [26, 5, 2, 7], [44, 7, 1, 8]] - -0.0002084941102769855 # B[1149, [26, 5, 2, 7], [45, 7, 2, 7]] - -0.000924608969529588931 # B[1150, [26, 5, 2, 7], [46, 7, 3, 8]] - -0.000320719808114693777 # B[1151, [26, 5, 2, 7], [47, 7, 4, 7]] - 0.00241998856780361801 # B[1152, [26, 5, 2, 7], [48, 7, 5, 8]] - -0.00171923440812344827 # B[1153, [26, 5, 2, 7], [49, 7, 6, 7]] - -0.000301390241580377569 # B[1154, [26, 5, 2, 7], [50, 7, 7, 8]] - -6.37461557401481499e-05 # B[1155, [26, 5, 2, 7], [51, 8, 0, 8]] - 0.00161644303684405446 # B[1156, [26, 5, 2, 7], [52, 8, 2, 8]] - 0.00104379414920739667 # B[1157, [26, 5, 2, 7], [53, 8, 4, 8]] - -0.00119795702190159808 # B[1158, [26, 5, 2, 7], [54, 8, 6, 8]] - 0.000604059138156293803 # B[1159, [26, 5, 2, 7], [55, 8, 8, 8]] - 0.000513459633959805622 # B[1160, [27, 5, 3, 6], [27, 5, 3, 6]] - -0.000172334638360790993 # B[1161, [27, 5, 3, 6], [28, 5, 3, 8]] - 1.60719061511648345e-05 # B[1162, [27, 5, 3, 6], [29, 5, 4, 5]] - 0.00440279299288983371 # B[1163, [27, 5, 3, 6], [30, 5, 4, 7]] - 0.000549761981236742206 # B[1164, [27, 5, 3, 6], [31, 5, 5, 6]] - 0.000424619689378998542 # B[1165, [27, 5, 3, 6], [32, 5, 5, 8]] - 0.000247367934895610653 # B[1166, [27, 5, 3, 6], [33, 6, 0, 6]] - 0.00400569055534595944 # B[1167, [27, 5, 3, 6], [34, 6, 1, 7]] - 0.00274378194299987679 # B[1168, [27, 5, 3, 6], [35, 6, 2, 6]] - 0.00368141326251353665 # B[1169, [27, 5, 3, 6], [36, 6, 2, 8]] - 0.00160469169395054817 # B[1170, [27, 5, 3, 6], [37, 6, 3, 7]] - 0.000105807739550402985 # B[1171, [27, 5, 3, 6], [38, 6, 4, 6]] - -0.000682801438033796976 # B[1172, [27, 5, 3, 6], [39, 6, 4, 8]] - -0.00121964915110857504 # B[1173, [27, 5, 3, 6], [40, 6, 5, 7]] - -0.000817665263990522556 # B[1174, [27, 5, 3, 6], [41, 6, 6, 6]] - 0.000534593784435832137 # B[1175, [27, 5, 3, 6], [42, 6, 6, 8]] - 0.000116542343021167755 # B[1176, [27, 5, 3, 6], [43, 7, 0, 7]] - 0.00351267154418699948 # B[1177, [27, 5, 3, 6], [44, 7, 1, 8]] - -0.00189934642995405814 # B[1178, [27, 5, 3, 6], [45, 7, 2, 7]] - 0.000751906974843792597 # B[1179, [27, 5, 3, 6], [46, 7, 3, 8]] - -0.000446808189773967301 # B[1180, [27, 5, 3, 6], [47, 7, 4, 7]] - -0.00324699511848197502 # B[1181, [27, 5, 3, 6], [48, 7, 5, 8]] - 2.53540837371335481e-05 # B[1182, [27, 5, 3, 6], [49, 7, 6, 7]] - 7.5273388360289073e-07 # B[1183, [27, 5, 3, 6], [50, 7, 7, 8]] - 0.00023346363571073725 # B[1184, [27, 5, 3, 6], [51, 8, 0, 8]] - 0.000490008984593369619 # B[1185, [27, 5, 3, 6], [52, 8, 2, 8]] - 0.000205260233742234413 # B[1186, [27, 5, 3, 6], [53, 8, 4, 8]] - -7.84984665939646165e-05 # B[1187, [27, 5, 3, 6], [54, 8, 6, 8]] - -0.000299454037036409743 # B[1188, [27, 5, 3, 6], [55, 8, 8, 8]] - -0.00411961786705090406 # B[1189, [28, 5, 3, 8], [28, 5, 3, 8]] - 0.00256764268592788759 # B[1190, [28, 5, 3, 8], [29, 5, 4, 5]] - -0.000267820435572239945 # B[1191, [28, 5, 3, 8], [30, 5, 4, 7]] - 0.000545048575291992229 # B[1192, [28, 5, 3, 8], [31, 5, 5, 6]] - -0.000141236037433873154 # B[1193, [28, 5, 3, 8], [32, 5, 5, 8]] - -8.17647193563642016e-05 # B[1194, [28, 5, 3, 8], [33, 6, 0, 6]] - 0.00184594470809960887 # B[1195, [28, 5, 3, 8], [34, 6, 1, 7]] - 0.000715653691449843685 # B[1196, [28, 5, 3, 8], [35, 6, 2, 6]] - -0.000371782729873919304 # B[1197, [28, 5, 3, 8], [36, 6, 2, 8]] - 0.00184451560473704312 # B[1198, [28, 5, 3, 8], [37, 6, 3, 7]] - 0.00298992898894900189 # B[1199, [28, 5, 3, 8], [38, 6, 4, 6]] - 0.00087474408278464047 # B[1200, [28, 5, 3, 8], [39, 6, 4, 8]] - 0.00115889056554823421 # B[1201, [28, 5, 3, 8], [40, 6, 5, 7]] - -0.000209440071593354482 # B[1202, [28, 5, 3, 8], [41, 6, 6, 6]] - 0.000707847416081031772 # B[1203, [28, 5, 3, 8], [42, 6, 6, 8]] - 0.00025922895119332573 # B[1204, [28, 5, 3, 8], [43, 7, 0, 7]] - -0.00210744601505012327 # B[1205, [28, 5, 3, 8], [44, 7, 1, 8]] - -0.00187401632149015486 # B[1206, [28, 5, 3, 8], [45, 7, 2, 7]] - 0.000616682247583759391 # B[1207, [28, 5, 3, 8], [46, 7, 3, 8]] - 0.00142526179781785924 # B[1208, [28, 5, 3, 8], [47, 7, 4, 7]] - -9.1619163886703936e-06 # B[1209, [28, 5, 3, 8], [48, 7, 5, 8]] - -0.000300978843055903222 # B[1210, [28, 5, 3, 8], [49, 7, 6, 7]] - -0.000124034381208077554 # B[1211, [28, 5, 3, 8], [50, 7, 7, 8]] - 0.000249158311162858692 # B[1212, [28, 5, 3, 8], [51, 8, 0, 8]] - -0.000970252220622513538 # B[1213, [28, 5, 3, 8], [52, 8, 2, 8]] - 0.000840312328335843066 # B[1214, [28, 5, 3, 8], [53, 8, 4, 8]] - 0.000145361901756495965 # B[1215, [28, 5, 3, 8], [54, 8, 6, 8]] - 0.00013163551986085896 # B[1216, [28, 5, 3, 8], [55, 8, 8, 8]] - 0.00265810885844912576 # B[1217, [29, 5, 4, 5], [29, 5, 4, 5]] - 0.00191793603428468823 # B[1218, [29, 5, 4, 5], [30, 5, 4, 7]] - 0.000446118694394436605 # B[1219, [29, 5, 4, 5], [31, 5, 5, 6]] - -9.59445098255573559e-05 # B[1220, [29, 5, 4, 5], [32, 5, 5, 8]] - 0.000369255428727587043 # B[1221, [29, 5, 4, 5], [33, 6, 0, 6]] - -0.000553149628059141762 # B[1222, [29, 5, 4, 5], [34, 6, 1, 7]] - 0.00315275275750991242 # B[1223, [29, 5, 4, 5], [35, 6, 2, 6]] - 0.00138540352181828336 # B[1224, [29, 5, 4, 5], [36, 6, 2, 8]] - 0.000776256233303879162 # B[1225, [29, 5, 4, 5], [37, 6, 3, 7]] - 0.000594477884906325672 # B[1226, [29, 5, 4, 5], [38, 6, 4, 6]] - 0.000757712543509288586 # B[1227, [29, 5, 4, 5], [39, 6, 4, 8]] - -0.000917903532807641184 # B[1228, [29, 5, 4, 5], [40, 6, 5, 7]] - -0.000915313398456763742 # B[1229, [29, 5, 4, 5], [41, 6, 6, 6]] - -0.00116732293566375843 # B[1230, [29, 5, 4, 5], [42, 6, 6, 8]] - 0.000172432189541951719 # B[1231, [29, 5, 4, 5], [43, 7, 0, 7]] - 0.000845370011774060912 # B[1232, [29, 5, 4, 5], [44, 7, 1, 8]] - 0.00178029205661471915 # B[1233, [29, 5, 4, 5], [45, 7, 2, 7]] - 0.00129739636685697463 # B[1234, [29, 5, 4, 5], [46, 7, 3, 8]] - 0.000282865369400489564 # B[1235, [29, 5, 4, 5], [47, 7, 4, 7]] - -0.00178988233479955398 # B[1236, [29, 5, 4, 5], [48, 7, 5, 8]] - 0.00023603474784275949 # B[1237, [29, 5, 4, 5], [49, 7, 6, 7]] - -0.000461436431325358207 # B[1238, [29, 5, 4, 5], [50, 7, 7, 8]] - 0.000234131705926524103 # B[1239, [29, 5, 4, 5], [51, 8, 0, 8]] - 0.00216254821351878363 # B[1240, [29, 5, 4, 5], [52, 8, 2, 8]] - 0.000831658742681578439 # B[1241, [29, 5, 4, 5], [53, 8, 4, 8]] - -0.00046318901257626742 # B[1242, [29, 5, 4, 5], [54, 8, 6, 8]] - -0.000607580535321294163 # B[1243, [29, 5, 4, 5], [55, 8, 8, 8]] - 0.00158347719827001653 # B[1244, [30, 5, 4, 7], [30, 5, 4, 7]] - 0.00120733638068271261 # B[1245, [30, 5, 4, 7], [31, 5, 5, 6]] - -0.000191610125195333311 # B[1246, [30, 5, 4, 7], [32, 5, 5, 8]] - -0.000363280761575070915 # B[1247, [30, 5, 4, 7], [33, 6, 0, 6]] - 0.0015080393447339897 # B[1248, [30, 5, 4, 7], [34, 6, 1, 7]] - 0.00144737958774105498 # B[1249, [30, 5, 4, 7], [35, 6, 2, 6]] - -0.000191256340607337365 # B[1250, [30, 5, 4, 7], [36, 6, 2, 8]] - 0.00324542123326504103 # B[1251, [30, 5, 4, 7], [37, 6, 3, 7]] - 0.00135369467391198949 # B[1252, [30, 5, 4, 7], [38, 6, 4, 6]] - 0.00077393986417062131 # B[1253, [30, 5, 4, 7], [39, 6, 4, 8]] - 0.00187057819081324836 # B[1254, [30, 5, 4, 7], [40, 6, 5, 7]] - 4.06728949024891956e-05 # B[1255, [30, 5, 4, 7], [41, 6, 6, 6]] - -0.000100060243024913467 # B[1256, [30, 5, 4, 7], [42, 6, 6, 8]] - -0.000170624797097965186 # B[1257, [30, 5, 4, 7], [43, 7, 0, 7]] - -0.00157200294852092963 # B[1258, [30, 5, 4, 7], [44, 7, 1, 8]] - -5.099465391029262e-05 # B[1259, [30, 5, 4, 7], [45, 7, 2, 7]] - 0.00166973065524506255 # B[1260, [30, 5, 4, 7], [46, 7, 3, 8]] - 0.000976468235486894175 # B[1261, [30, 5, 4, 7], [47, 7, 4, 7]] - -0.000570830124590235299 # B[1262, [30, 5, 4, 7], [48, 7, 5, 8]] - 0.000667250794893839427 # B[1263, [30, 5, 4, 7], [49, 7, 6, 7]] - -0.000273376565753529832 # B[1264, [30, 5, 4, 7], [50, 7, 7, 8]] - 0.000206233716860107844 # B[1265, [30, 5, 4, 7], [51, 8, 0, 8]] - 0.00260342927157033218 # B[1266, [30, 5, 4, 7], [52, 8, 2, 8]] - 0.000943954042545826558 # B[1267, [30, 5, 4, 7], [53, 8, 4, 8]] - -0.00022781927635321525 # B[1268, [30, 5, 4, 7], [54, 8, 6, 8]] - -0.000448456045604168733 # B[1269, [30, 5, 4, 7], [55, 8, 8, 8]] - 0.00102985782764508475 # B[1270, [31, 5, 5, 6], [31, 5, 5, 6]] - -8.89908688742153606e-05 # B[1271, [31, 5, 5, 6], [32, 5, 5, 8]] - -0.000162481274467801695 # B[1272, [31, 5, 5, 6], [33, 6, 0, 6]] - 0.00263772603538907271 # B[1273, [31, 5, 5, 6], [34, 6, 1, 7]] - -0.00223528099165903275 # B[1274, [31, 5, 5, 6], [35, 6, 2, 6]] - 0.000441657599119526373 # B[1275, [31, 5, 5, 6], [36, 6, 2, 8]] - 0.00165514785004864176 # B[1276, [31, 5, 5, 6], [37, 6, 3, 7]] - 0.000898928585103351413 # B[1277, [31, 5, 5, 6], [38, 6, 4, 6]] - -0.00026071204606309753 # B[1278, [31, 5, 5, 6], [39, 6, 4, 8]] - -0.000251612913047311385 # B[1279, [31, 5, 5, 6], [40, 6, 5, 7]] - -0.00022773870089292346 # B[1280, [31, 5, 5, 6], [41, 6, 6, 6]] - -0.000449951686975022525 # B[1281, [31, 5, 5, 6], [42, 6, 6, 8]] - -0.000252400784021909741 # B[1282, [31, 5, 5, 6], [43, 7, 0, 7]] - 0.000574433272355396977 # B[1283, [31, 5, 5, 6], [44, 7, 1, 8]] - -0.0014040949400035245 # B[1284, [31, 5, 5, 6], [45, 7, 2, 7]] - 0.00124516802775002586 # B[1285, [31, 5, 5, 6], [46, 7, 3, 8]] - 0.000875572292146320832 # B[1286, [31, 5, 5, 6], [47, 7, 4, 7]] - -0.000509730931921630048 # B[1287, [31, 5, 5, 6], [48, 7, 5, 8]] - 0.000422266146488117777 # B[1288, [31, 5, 5, 6], [49, 7, 6, 7]] - -0.000239146684560266956 # B[1289, [31, 5, 5, 6], [50, 7, 7, 8]] - 9.95899703990707486e-05 # B[1290, [31, 5, 5, 6], [51, 8, 0, 8]] - -0.0020784147827535588 # B[1291, [31, 5, 5, 6], [52, 8, 2, 8]] - 0.000735684723224858811 # B[1292, [31, 5, 5, 6], [53, 8, 4, 8]] - -0.000248804810033285279 # B[1293, [31, 5, 5, 6], [54, 8, 6, 8]] - -0.000598263607047986451 # B[1294, [31, 5, 5, 6], [55, 8, 8, 8]] - 0.000131065920905359436 # B[1295, [32, 5, 5, 8], [32, 5, 5, 8]] - 0.000100196796943449913 # B[1296, [32, 5, 5, 8], [33, 6, 0, 6]] - -0.00173991171955805834 # B[1297, [32, 5, 5, 8], [34, 6, 1, 7]] - -0.000490539010579770906 # B[1298, [32, 5, 5, 8], [35, 6, 2, 6]] - 0.000676191083650941674 # B[1299, [32, 5, 5, 8], [36, 6, 2, 8]] - 0.000446932761165407325 # B[1300, [32, 5, 5, 8], [37, 6, 3, 7]] - -0.000153107558622965576 # B[1301, [32, 5, 5, 8], [38, 6, 4, 6]] - 1.67752859932734574e-05 # B[1302, [32, 5, 5, 8], [39, 6, 4, 8]] - 0.000215146896189506113 # B[1303, [32, 5, 5, 8], [40, 6, 5, 7]] - -0.000188466441880926362 # B[1304, [32, 5, 5, 8], [41, 6, 6, 6]] - -4.80917708388720055e-06 # B[1305, [32, 5, 5, 8], [42, 6, 6, 8]] - -5.04429979448911547e-05 # B[1306, [32, 5, 5, 8], [43, 7, 0, 7]] - -0.000494944862407609067 # B[1307, [32, 5, 5, 8], [44, 7, 1, 8]] - -0.000424473825928651724 # B[1308, [32, 5, 5, 8], [45, 7, 2, 7]] - 0.000417544384337296959 # B[1309, [32, 5, 5, 8], [46, 7, 3, 8]] - 0.000431586591455488614 # B[1310, [32, 5, 5, 8], [47, 7, 4, 7]] - 0.000187341827588022357 # B[1311, [32, 5, 5, 8], [48, 7, 5, 8]] - -6.87669988055673864e-05 # B[1312, [32, 5, 5, 8], [49, 7, 6, 7]] - 0.000147867669408649482 # B[1313, [32, 5, 5, 8], [50, 7, 7, 8]] - -7.32201679551347517e-06 # B[1314, [32, 5, 5, 8], [51, 8, 0, 8]] - -0.000392519615947300787 # B[1315, [32, 5, 5, 8], [52, 8, 2, 8]] - 8.78465325612771269e-05 # B[1316, [32, 5, 5, 8], [53, 8, 4, 8]] - -6.3960070015590606e-05 # B[1317, [32, 5, 5, 8], [54, 8, 6, 8]] - -7.97839909379757101e-06 # B[1318, [32, 5, 5, 8], [55, 8, 8, 8]] - 3.95695067041609838e-05 # B[1319, [33, 6, 0, 6], [33, 6, 0, 6]] - -0.000611658005184461534 # B[1320, [33, 6, 0, 6], [34, 6, 1, 7]] - -0.000277914808470863806 # B[1321, [33, 6, 0, 6], [35, 6, 2, 6]] - 0.000987938388973043716 # B[1322, [33, 6, 0, 6], [36, 6, 2, 8]] - 0.000198558948919527745 # B[1323, [33, 6, 0, 6], [37, 6, 3, 7]] - 9.76274805398642809e-05 # B[1324, [33, 6, 0, 6], [38, 6, 4, 6]] - 9.92197766131464043e-05 # B[1325, [33, 6, 0, 6], [39, 6, 4, 8]] - -4.16996931875308896e-05 # B[1326, [33, 6, 0, 6], [40, 6, 5, 7]] - -5.3495059095630057e-05 # B[1327, [33, 6, 0, 6], [41, 6, 6, 6]] - 1.0720822351671655e-05 # B[1328, [33, 6, 0, 6], [42, 6, 6, 8]] - 0.000114464898537391946 # B[1329, [33, 6, 0, 6], [43, 7, 0, 7]] - -0.00033593422820483651 # B[1330, [33, 6, 0, 6], [44, 7, 1, 8]] - -0.00061665800523461739 # B[1331, [33, 6, 0, 6], [45, 7, 2, 7]] - -0.000258302532232180387 # B[1332, [33, 6, 0, 6], [46, 7, 3, 8]] - 3.78181072490033077e-05 # B[1333, [33, 6, 0, 6], [47, 7, 4, 7]] - -0.000326273283142861775 # B[1334, [33, 6, 0, 6], [48, 7, 5, 8]] - 1.74277156155672186e-05 # B[1335, [33, 6, 0, 6], [49, 7, 6, 7]] - -0.000206600107910874173 # B[1336, [33, 6, 0, 6], [50, 7, 7, 8]] - 2.12855018918572947e-05 # B[1337, [33, 6, 0, 6], [51, 8, 0, 8]] - -0.000696835386532819456 # B[1338, [33, 6, 0, 6], [52, 8, 2, 8]] - 8.06841007746916805e-05 # B[1339, [33, 6, 0, 6], [53, 8, 4, 8]] - 1.96129469472779844e-05 # B[1340, [33, 6, 0, 6], [54, 8, 6, 8]] - 7.35114191380559223e-05 # B[1341, [33, 6, 0, 6], [55, 8, 8, 8]] - 0.00360109138862139185 # B[1342, [34, 6, 1, 7], [34, 6, 1, 7]] - 0.00304872474261531218 # B[1343, [34, 6, 1, 7], [35, 6, 2, 6]] - -0.00546316824530662139 # B[1344, [34, 6, 1, 7], [36, 6, 2, 8]] - 0.000721988419001898946 # B[1345, [34, 6, 1, 7], [37, 6, 3, 7]] - -0.00254968694435141717 # B[1346, [34, 6, 1, 7], [38, 6, 4, 6]] - -0.00102187793811427596 # B[1347, [34, 6, 1, 7], [39, 6, 4, 8]] - 0.000977866285507509106 # B[1348, [34, 6, 1, 7], [40, 6, 5, 7]] - 0.00129156024637028417 # B[1349, [34, 6, 1, 7], [41, 6, 6, 6]] - 8.43980229575398005e-05 # B[1350, [34, 6, 1, 7], [42, 6, 6, 8]] - -0.000854491821273548058 # B[1351, [34, 6, 1, 7], [43, 7, 0, 7]] - -0.00229655360277009144 # B[1352, [34, 6, 1, 7], [44, 7, 1, 8]] - 0.00392740594657482126 # B[1353, [34, 6, 1, 7], [45, 7, 2, 7]] - 0.00282086313880587115 # B[1354, [34, 6, 1, 7], [46, 7, 3, 8]] - -0.00269367822401865922 # B[1355, [34, 6, 1, 7], [47, 7, 4, 7]] - 0.00120544917432826269 # B[1356, [34, 6, 1, 7], [48, 7, 5, 8]] - 0.00137213082032611872 # B[1357, [34, 6, 1, 7], [49, 7, 6, 7]] - 0.00278774897747785522 # B[1358, [34, 6, 1, 7], [50, 7, 7, 8]] - -1.00075929411755707e-05 # B[1359, [34, 6, 1, 7], [51, 8, 0, 8]] - 0.00331402709384703321 # B[1360, [34, 6, 1, 7], [52, 8, 2, 8]] - -0.00220016465090739841 # B[1361, [34, 6, 1, 7], [53, 8, 4, 8]] - 0.000794479619849004434 # B[1362, [34, 6, 1, 7], [54, 8, 6, 8]] - 0.000207117210070053084 # B[1363, [34, 6, 1, 7], [55, 8, 8, 8]] - 0.000547206364960122621 # B[1364, [35, 6, 2, 6], [35, 6, 2, 6]] - 0.00243529980905243717 # B[1365, [35, 6, 2, 6], [36, 6, 2, 8]] - 0.000346076245330416421 # B[1366, [35, 6, 2, 6], [37, 6, 3, 7]] - 0.00220550296989585788 # B[1367, [35, 6, 2, 6], [38, 6, 4, 6]] - 0.00101934408216735467 # B[1368, [35, 6, 2, 6], [39, 6, 4, 8]] - 6.76995447894471192e-05 # B[1369, [35, 6, 2, 6], [40, 6, 5, 7]] - -4.61734905116591154e-05 # B[1370, [35, 6, 2, 6], [41, 6, 6, 6]] - 0.000809543629624515093 # B[1371, [35, 6, 2, 6], [42, 6, 6, 8]] - 0.000219078295465409238 # B[1372, [35, 6, 2, 6], [43, 7, 0, 7]] - -0.00316872925249137884 # B[1373, [35, 6, 2, 6], [44, 7, 1, 8]] - 0.000676713636760976206 # B[1374, [35, 6, 2, 6], [45, 7, 2, 7]] - -0.00100477918211841141 # B[1375, [35, 6, 2, 6], [46, 7, 3, 8]] - 0.000400524978896980161 # B[1376, [35, 6, 2, 6], [47, 7, 4, 7]] - -0.00197634098305848622 # B[1377, [35, 6, 2, 6], [48, 7, 5, 8]] - 0.000367979983554051621 # B[1378, [35, 6, 2, 6], [49, 7, 6, 7]] - -0.00126672502130457942 # B[1379, [35, 6, 2, 6], [50, 7, 7, 8]] - 0.000161373464169148675 # B[1380, [35, 6, 2, 6], [51, 8, 0, 8]] - 0.00258770627559228462 # B[1381, [35, 6, 2, 6], [52, 8, 2, 8]] - 0.000816135012742828661 # B[1382, [35, 6, 2, 6], [53, 8, 4, 8]] - -3.28991122771973843e-05 # B[1383, [35, 6, 2, 6], [54, 8, 6, 8]] - -4.18127338362338707e-05 # B[1384, [35, 6, 2, 6], [55, 8, 8, 8]] - 0.00658745572292138409 # B[1385, [36, 6, 2, 8], [36, 6, 2, 8]] - -0.00238764687643479301 # B[1386, [36, 6, 2, 8], [37, 6, 3, 7]] - -0.000831950910425274803 # B[1387, [36, 6, 2, 8], [38, 6, 4, 6]] - 0.00351737364404769177 # B[1388, [36, 6, 2, 8], [39, 6, 4, 8]] - -0.00276293358095670936 # B[1389, [36, 6, 2, 8], [40, 6, 5, 7]] - -0.00115031008308692437 # B[1390, [36, 6, 2, 8], [41, 6, 6, 6]] - -0.000921624256609663434 # B[1391, [36, 6, 2, 8], [42, 6, 6, 8]] - 0.000810924380859275734 # B[1392, [36, 6, 2, 8], [43, 7, 0, 7]] - -0.00488922361819911239 # B[1393, [36, 6, 2, 8], [44, 7, 1, 8]] - 0.00170426259508682162 # B[1394, [36, 6, 2, 8], [45, 7, 2, 7]] - -0.000698037236981145087 # B[1395, [36, 6, 2, 8], [46, 7, 3, 8]] - -0.00159293071425275958 # B[1396, [36, 6, 2, 8], [47, 7, 4, 7]] - 0.00145526568566858513 # B[1397, [36, 6, 2, 8], [48, 7, 5, 8]] - -0.0034526631911915729 # B[1398, [36, 6, 2, 8], [49, 7, 6, 7]] - 0.00136118079841816148 # B[1399, [36, 6, 2, 8], [50, 7, 7, 8]] - -0.000519558666561149851 # B[1400, [36, 6, 2, 8], [51, 8, 0, 8]] - -0.00125430728243427136 # B[1401, [36, 6, 2, 8], [52, 8, 2, 8]] - 0.000225746730173992209 # B[1402, [36, 6, 2, 8], [53, 8, 4, 8]] - 0.000144081610870761424 # B[1403, [36, 6, 2, 8], [54, 8, 6, 8]] - 0.000848192939185923693 # B[1404, [36, 6, 2, 8], [55, 8, 8, 8]] - 0.00209760366601450393 # B[1405, [37, 6, 3, 7], [37, 6, 3, 7]] - -0.00114098142783233825 # B[1406, [37, 6, 3, 7], [38, 6, 4, 6]] - -0.00012482798433224862 # B[1407, [37, 6, 3, 7], [39, 6, 4, 8]] - 0.000414303981445450498 # B[1408, [37, 6, 3, 7], [40, 6, 5, 7]] - -2.06949976952613968e-05 # B[1409, [37, 6, 3, 7], [41, 6, 6, 6]] - 0.000986658381613915447 # B[1410, [37, 6, 3, 7], [42, 6, 6, 8]] - 0.000196361012595618056 # B[1411, [37, 6, 3, 7], [43, 7, 0, 7]] - 0.000421620511108736218 # B[1412, [37, 6, 3, 7], [44, 7, 1, 8]] - -0.00121366957406692996 # B[1413, [37, 6, 3, 7], [45, 7, 2, 7]] - 0.000319772245183778947 # B[1414, [37, 6, 3, 7], [46, 7, 3, 8]] - -0.00189440310525268441 # B[1415, [37, 6, 3, 7], [47, 7, 4, 7]] - -0.000420808921505540223 # B[1416, [37, 6, 3, 7], [48, 7, 5, 8]] - -0.000833056882638676111 # B[1417, [37, 6, 3, 7], [49, 7, 6, 7]] - -0.000210394181928773294 # B[1418, [37, 6, 3, 7], [50, 7, 7, 8]] - 4.67415997983874898e-05 # B[1419, [37, 6, 3, 7], [51, 8, 0, 8]] - -0.000629437221263145228 # B[1420, [37, 6, 3, 7], [52, 8, 2, 8]] - -0.000561739301858470846 # B[1421, [37, 6, 3, 7], [53, 8, 4, 8]] - -0.000244403089656959616 # B[1422, [37, 6, 3, 7], [54, 8, 6, 8]] - 0.000170058213410727299 # B[1423, [37, 6, 3, 7], [55, 8, 8, 8]] - 0.000190580820336867102 # B[1424, [38, 6, 4, 6], [38, 6, 4, 6]] - -5.17086422710446442e-05 # B[1425, [38, 6, 4, 6], [39, 6, 4, 8]] - -0.000870479233908965505 # B[1426, [38, 6, 4, 6], [40, 6, 5, 7]] - 8.56431173592298034e-05 # B[1427, [38, 6, 4, 6], [41, 6, 6, 6]] - -0.000219028113680014638 # B[1428, [38, 6, 4, 6], [42, 6, 6, 8]] - 6.99094597341239771e-05 # B[1429, [38, 6, 4, 6], [43, 7, 0, 7]] - -0.00217214753267054063 # B[1430, [38, 6, 4, 6], [44, 7, 1, 8]] - 0.00103452950595812193 # B[1431, [38, 6, 4, 6], [45, 7, 2, 7]] - 0.000131158053198399821 # B[1432, [38, 6, 4, 6], [46, 7, 3, 8]] - -0.000991288929959081421 # B[1433, [38, 6, 4, 6], [47, 7, 4, 7]] - -0.000321058899826150157 # B[1434, [38, 6, 4, 6], [48, 7, 5, 8]] - -0.000126379357764709599 # B[1435, [38, 6, 4, 6], [49, 7, 6, 7]] - 0.000513859397020456632 # B[1436, [38, 6, 4, 6], [50, 7, 7, 8]] - -2.72482190626921472e-05 # B[1437, [38, 6, 4, 6], [51, 8, 0, 8]] - 0.000742781076179950886 # B[1438, [38, 6, 4, 6], [52, 8, 2, 8]] - -9.17701606060090935e-05 # B[1439, [38, 6, 4, 6], [53, 8, 4, 8]] - 1.49768390447675703e-05 # B[1440, [38, 6, 4, 6], [54, 8, 6, 8]] - -5.94521118466549703e-05 # B[1441, [38, 6, 4, 6], [55, 8, 8, 8]] - 0.00161400415689978271 # B[1442, [39, 6, 4, 8], [39, 6, 4, 8]] - -0.000149892220376375129 # B[1443, [39, 6, 4, 8], [40, 6, 5, 7]] - -0.000242832088631229209 # B[1444, [39, 6, 4, 8], [41, 6, 6, 6]] - -4.23223006292567511e-05 # B[1445, [39, 6, 4, 8], [42, 6, 6, 8]] - 0.000145544599928226076 # B[1446, [39, 6, 4, 8], [43, 7, 0, 7]] - -0.000846976149028450323 # B[1447, [39, 6, 4, 8], [44, 7, 1, 8]] - 0.000313402576083809947 # B[1448, [39, 6, 4, 8], [45, 7, 2, 7]] - -0.00105304559168569421 # B[1449, [39, 6, 4, 8], [46, 7, 3, 8]] - -0.000563622717067245593 # B[1450, [39, 6, 4, 8], [47, 7, 4, 7]] - -0.000176248327800098206 # B[1451, [39, 6, 4, 8], [48, 7, 5, 8]] - -0.000523005481859822874 # B[1452, [39, 6, 4, 8], [49, 7, 6, 7]] - 0.000327425878709725754 # B[1453, [39, 6, 4, 8], [50, 7, 7, 8]] - -0.000214075091648432969 # B[1454, [39, 6, 4, 8], [51, 8, 0, 8]] - 0.000892962890338189208 # B[1455, [39, 6, 4, 8], [52, 8, 2, 8]] - 0.000483016760753301674 # B[1456, [39, 6, 4, 8], [53, 8, 4, 8]] - 0.000385986009520520711 # B[1457, [39, 6, 4, 8], [54, 8, 6, 8]] - 0.000210387221014841225 # B[1458, [39, 6, 4, 8], [55, 8, 8, 8]] - 0.000423894835630976054 # B[1459, [40, 6, 5, 7], [40, 6, 5, 7]] - 2.52152593651043533e-05 # B[1460, [40, 6, 5, 7], [41, 6, 6, 6]] - 0.0001406783760301792 # B[1461, [40, 6, 5, 7], [42, 6, 6, 8]] - -0.000402862939603353815 # B[1462, [40, 6, 5, 7], [43, 7, 0, 7]] - -0.000764679971924708997 # B[1463, [40, 6, 5, 7], [44, 7, 1, 8]] - 0.000690122720081854865 # B[1464, [40, 6, 5, 7], [45, 7, 2, 7]] - 0.00135911524951161378 # B[1465, [40, 6, 5, 7], [46, 7, 3, 8]] - 5.52075818169902449e-06 # B[1466, [40, 6, 5, 7], [47, 7, 4, 7]] - -0.000149902773226399076 # B[1467, [40, 6, 5, 7], [48, 7, 5, 8]] - 0.000389894625400750289 # B[1468, [40, 6, 5, 7], [49, 7, 6, 7]] - 0.000257807843360047251 # B[1469, [40, 6, 5, 7], [50, 7, 7, 8]] - -3.67912373811542237e-05 # B[1470, [40, 6, 5, 7], [51, 8, 0, 8]] - -0.000174743024771516643 # B[1471, [40, 6, 5, 7], [52, 8, 2, 8]] - 0.000276798622678277838 # B[1472, [40, 6, 5, 7], [53, 8, 4, 8]] - 0.000152459620483783032 # B[1473, [40, 6, 5, 7], [54, 8, 6, 8]] - -0.000616599602238733502 # B[1474, [40, 6, 5, 7], [55, 8, 8, 8]] - -5.12324624723156652e-05 # B[1475, [41, 6, 6, 6], [41, 6, 6, 6]] - -4.23334509430418893e-05 # B[1476, [41, 6, 6, 6], [42, 6, 6, 8]] - -0.000111212733055157664 # B[1477, [41, 6, 6, 6], [43, 7, 0, 7]] - 0.000882360189618891337 # B[1478, [41, 6, 6, 6], [44, 7, 1, 8]] - -0.000581964842687935843 # B[1479, [41, 6, 6, 6], [45, 7, 2, 7]] - 0.000211138997961872465 # B[1480, [41, 6, 6, 6], [46, 7, 3, 8]] - 7.79906436828414068e-05 # B[1481, [41, 6, 6, 6], [47, 7, 4, 7]] - -0.000201461425275273331 # B[1482, [41, 6, 6, 6], [48, 7, 5, 8]] - 6.87828589884392771e-05 # B[1483, [41, 6, 6, 6], [49, 7, 6, 7]] - 0.000150653067204437052 # B[1484, [41, 6, 6, 6], [50, 7, 7, 8]] - 3.87532549918634395e-05 # B[1485, [41, 6, 6, 6], [51, 8, 0, 8]] - 0.000361299779465781672 # B[1486, [41, 6, 6, 6], [52, 8, 2, 8]] - -0.000217385549744270783 # B[1487, [41, 6, 6, 6], [53, 8, 4, 8]] - 6.09508622621875856e-05 # B[1488, [41, 6, 6, 6], [54, 8, 6, 8]] - -0.000174447165900721429 # B[1489, [41, 6, 6, 6], [55, 8, 8, 8]] - 4.08451735536830007e-05 # B[1490, [42, 6, 6, 8], [42, 6, 6, 8]] - -0.000100109250872669128 # B[1491, [42, 6, 6, 8], [43, 7, 0, 7]] - 0.000543796967600337564 # B[1492, [42, 6, 6, 8], [44, 7, 1, 8]] - 0.000744432946735457124 # B[1493, [42, 6, 6, 8], [45, 7, 2, 7]] - 0.0010803210667922683 # B[1494, [42, 6, 6, 8], [46, 7, 3, 8]] - 0.000151445105968722347 # B[1495, [42, 6, 6, 8], [47, 7, 4, 7]] - -0.000100848877598445907 # B[1496, [42, 6, 6, 8], [48, 7, 5, 8]] - -0.000109088350721993355 # B[1497, [42, 6, 6, 8], [49, 7, 6, 7]] - -0.000287924009882135207 # B[1498, [42, 6, 6, 8], [50, 7, 7, 8]] - 1.48405987461727729e-05 # B[1499, [42, 6, 6, 8], [51, 8, 0, 8]] - 0.00133229142431166023 # B[1500, [42, 6, 6, 8], [52, 8, 2, 8]] - -0.00019157481902659472 # B[1501, [42, 6, 6, 8], [53, 8, 4, 8]] - -0.000214414469154704246 # B[1502, [42, 6, 6, 8], [54, 8, 6, 8]] - -0.000145460173238021184 # B[1503, [42, 6, 6, 8], [55, 8, 8, 8]] - 0.000122164068846408735 # B[1504, [43, 7, 0, 7], [43, 7, 0, 7]] - -0.000271198052548764657 # B[1505, [43, 7, 0, 7], [44, 7, 1, 8]] - -7.53020792218089818e-05 # B[1506, [43, 7, 0, 7], [45, 7, 2, 7]] - -0.000522043739406908344 # B[1507, [43, 7, 0, 7], [46, 7, 3, 8]] - -4.818852612961666e-05 # B[1508, [43, 7, 0, 7], [47, 7, 4, 7]] - -0.000220542438614808323 # B[1509, [43, 7, 0, 7], [48, 7, 5, 8]] - -0.000160998835878327362 # B[1510, [43, 7, 0, 7], [49, 7, 6, 7]] - -2.41628428966911279e-05 # B[1511, [43, 7, 0, 7], [50, 7, 7, 8]] - -1.41474469189661889e-05 # B[1512, [43, 7, 0, 7], [51, 8, 0, 8]] - -0.000160534811881916234 # B[1513, [43, 7, 0, 7], [52, 8, 2, 8]] - -1.73735621299461046e-05 # B[1514, [43, 7, 0, 7], [53, 8, 4, 8]] - 4.73251016045242445e-05 # B[1515, [43, 7, 0, 7], [54, 8, 6, 8]] - 0.000182463508348683356 # B[1516, [43, 7, 0, 7], [55, 8, 8, 8]] - -0.000629134879565343137 # B[1517, [44, 7, 1, 8], [44, 7, 1, 8]] - -0.00207361578267727673 # B[1518, [44, 7, 1, 8], [45, 7, 2, 7]] - 0.0031686999001355326 # B[1519, [44, 7, 1, 8], [46, 7, 3, 8]] - -0.000405403647932546952 # B[1520, [44, 7, 1, 8], [47, 7, 4, 7]] - -0.000111251617971438489 # B[1521, [44, 7, 1, 8], [48, 7, 5, 8]] - 0.0014482690523848242 # B[1522, [44, 7, 1, 8], [49, 7, 6, 7]] - 0.000818892450912583197 # B[1523, [44, 7, 1, 8], [50, 7, 7, 8]] - 0.000100422502558870572 # B[1524, [44, 7, 1, 8], [51, 8, 0, 8]] - -0.000412863674396233161 # B[1525, [44, 7, 1, 8], [52, 8, 2, 8]] - -0.000905494278120194153 # B[1526, [44, 7, 1, 8], [53, 8, 4, 8]] - 0.00126932173443552359 # B[1527, [44, 7, 1, 8], [54, 8, 6, 8]] - -0.000374814469421512735 # B[1528, [44, 7, 1, 8], [55, 8, 8, 8]] - -0.00330341133748704441 # B[1529, [45, 7, 2, 7], [45, 7, 2, 7]] - 0.00131616674488897398 # B[1530, [45, 7, 2, 7], [46, 7, 3, 8]] - -0.000483635326292886428 # B[1531, [45, 7, 2, 7], [47, 7, 4, 7]] - -0.00177550615332965067 # B[1532, [45, 7, 2, 7], [48, 7, 5, 8]] - 0.00226091969304176299 # B[1533, [45, 7, 2, 7], [49, 7, 6, 7]] - -0.00142635978155006456 # B[1534, [45, 7, 2, 7], [50, 7, 7, 8]] - 0.000289476939908078768 # B[1535, [45, 7, 2, 7], [51, 8, 0, 8]] - 0.000582488578419503846 # B[1536, [45, 7, 2, 7], [52, 8, 2, 8]] - -0.000228795123723987606 # B[1537, [45, 7, 2, 7], [53, 8, 4, 8]] - 0.000478658611037000373 # B[1538, [45, 7, 2, 7], [54, 8, 6, 8]] - -0.00101956994563059782 # B[1539, [45, 7, 2, 7], [55, 8, 8, 8]] - 0.00268648192223141895 # B[1540, [46, 7, 3, 8], [46, 7, 3, 8]] - 0.000515570689344949529 # B[1541, [46, 7, 3, 8], [47, 7, 4, 7]] - 0.000903689215066725768 # B[1542, [46, 7, 3, 8], [48, 7, 5, 8]] - 0.00180650309403464215 # B[1543, [46, 7, 3, 8], [49, 7, 6, 7]] - -7.48574841450792838e-05 # B[1544, [46, 7, 3, 8], [50, 7, 7, 8]] - -2.90930360741237237e-05 # B[1545, [46, 7, 3, 8], [51, 8, 0, 8]] - 0.00139057844941538594 # B[1546, [46, 7, 3, 8], [52, 8, 2, 8]] - -0.000263907165716330272 # B[1547, [46, 7, 3, 8], [53, 8, 4, 8]] - -5.74521512815137289e-05 # B[1548, [46, 7, 3, 8], [54, 8, 6, 8]] - -0.00030234445629373323 # B[1549, [46, 7, 3, 8], [55, 8, 8, 8]] - -0.000842080339294604824 # B[1550, [47, 7, 4, 7], [47, 7, 4, 7]] - -1.8677234631915389e-05 # B[1551, [47, 7, 4, 7], [48, 7, 5, 8]] - 0.000150434033167294937 # B[1552, [47, 7, 4, 7], [49, 7, 6, 7]] - 0.000201922161197246736 # B[1553, [47, 7, 4, 7], [50, 7, 7, 8]] - 5.63689077359152968e-05 # B[1554, [47, 7, 4, 7], [51, 8, 0, 8]] - 0.000490229079971716761 # B[1555, [47, 7, 4, 7], [52, 8, 2, 8]] - -0.00019335269881828529 # B[1556, [47, 7, 4, 7], [53, 8, 4, 8]] - -0.000118664083374402096 # B[1557, [47, 7, 4, 7], [54, 8, 6, 8]] - -0.000397263359111398734 # B[1558, [47, 7, 4, 7], [55, 8, 8, 8]] - -0.000724261739409587726 # B[1559, [48, 7, 5, 8], [48, 7, 5, 8]] - 0.000186853474209224685 # B[1560, [48, 7, 5, 8], [49, 7, 6, 7]] - -0.000533321040010020266 # B[1561, [48, 7, 5, 8], [50, 7, 7, 8]] - 9.95102706208284005e-08 # B[1562, [48, 7, 5, 8], [51, 8, 0, 8]] - -0.00093755398196557671 # B[1563, [48, 7, 5, 8], [52, 8, 2, 8]] - 0.000483236780374178207 # B[1564, [48, 7, 5, 8], [53, 8, 4, 8]] - -5.03524206302112531e-05 # B[1565, [48, 7, 5, 8], [54, 8, 6, 8]] - -0.000586245052440398373 # B[1566, [48, 7, 5, 8], [55, 8, 8, 8]] - -0.000207118017941997773 # B[1567, [49, 7, 6, 7], [49, 7, 6, 7]] - -9.40116364012005823e-05 # B[1568, [49, 7, 6, 7], [50, 7, 7, 8]] - 0.000124266884770383307 # B[1569, [49, 7, 6, 7], [51, 8, 0, 8]] - 0.00118479186165786239 # B[1570, [49, 7, 6, 7], [52, 8, 2, 8]] - -0.000129238345120056067 # B[1571, [49, 7, 6, 7], [53, 8, 4, 8]] - -0.000383875224777865259 # B[1572, [49, 7, 6, 7], [54, 8, 6, 8]] - -0.000457194559055141767 # B[1573, [49, 7, 6, 7], [55, 8, 8, 8]] - -0.000450510261664234871 # B[1574, [50, 7, 7, 8], [50, 7, 7, 8]] - 7.52704593073999506e-05 # B[1575, [50, 7, 7, 8], [51, 8, 0, 8]] - -0.00128732840082427732 # B[1576, [50, 7, 7, 8], [52, 8, 2, 8]] - 0.000293225651298797269 # B[1577, [50, 7, 7, 8], [53, 8, 4, 8]] - -0.000306521733645761033 # B[1578, [50, 7, 7, 8], [54, 8, 6, 8]] - -0.000370268243746852549 # B[1579, [50, 7, 7, 8], [55, 8, 8, 8]] - -4.00747887657759705e-06 # B[1580, [51, 8, 0, 8], [51, 8, 0, 8]] - -0.000179079356204300821 # B[1581, [51, 8, 0, 8], [52, 8, 2, 8]] - -6.37205046857824975e-06 # B[1582, [51, 8, 0, 8], [53, 8, 4, 8]] - 5.20087282658288075e-05 # B[1583, [51, 8, 0, 8], [54, 8, 6, 8]] - 6.68015373273544988e-05 # B[1584, [51, 8, 0, 8], [55, 8, 8, 8]] - 0.00160592146390294661 # B[1585, [52, 8, 2, 8], [52, 8, 2, 8]] - 0.000454049229948232103 # B[1586, [52, 8, 2, 8], [53, 8, 4, 8]] - 0.00110675066334388339 # B[1587, [52, 8, 2, 8], [54, 8, 6, 8]] - -0.000191060465051852771 # B[1588, [52, 8, 2, 8], [55, 8, 8, 8]] - -0.000131765455753670314 # B[1589, [53, 8, 4, 8], [53, 8, 4, 8]] - -7.05704764431217685e-05 # B[1590, [53, 8, 4, 8], [54, 8, 6, 8]] - -1.82263105369812051e-05 # B[1591, [53, 8, 4, 8], [55, 8, 8, 8]] - -0.00032731873727259329 # B[1592, [54, 8, 6, 8], [54, 8, 6, 8]] - -0.000198178389384386089 # B[1593, [54, 8, 6, 8], [55, 8, 8, 8]] - -0.000136309758672861769 # B[1594, [55, 8, 8, 8], [55, 8, 8, 8]] - -# End of potential From 2855f18d027a7c5be6c664929428e46a8a01b592 Mon Sep 17 00:00:00 2001 From: jwillma2 <52575231+jwillma2@users.noreply.github.com> Date: Tue, 23 May 2023 12:58:34 -0400 Subject: [PATCH 249/448] Delete C_Willman_PRB2022.quadratic.snapparam --- potentials/C_Willman_PRB2022.quadratic.snapparam | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 potentials/C_Willman_PRB2022.quadratic.snapparam diff --git a/potentials/C_Willman_PRB2022.quadratic.snapparam b/potentials/C_Willman_PRB2022.quadratic.snapparam deleted file mode 100644 index 26dddf627d..0000000000 --- a/potentials/C_Willman_PRB2022.quadratic.snapparam +++ /dev/null @@ -1,10 +0,0 @@ - - # required - rcutfac 2.7 - twojmax 8 - - # optional - rfac0 0.99363 - rmin0 0.0 - bzeroflag 0 - quadraticflag 1 From 0692ed3bd72bfbd9f0524baa8ea45dadefb08407 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Wed, 24 May 2023 11:47:15 +0300 Subject: [PATCH 250/448] @evoyiatzis Include method for angle contribution & variables to compute_stress_mop.h --- src/EXTRA-COMPUTE/compute_stress_mop.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.h b/src/EXTRA-COMPUTE/compute_stress_mop.h index c9f95c1996..d1074e002a 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.h +++ b/src/EXTRA-COMPUTE/compute_stress_mop.h @@ -39,12 +39,14 @@ class ComputeStressMop : public Compute { private: void compute_pairs(); void compute_bonds(); + void compute_angles(); int me, nvalues, dir; int *which; double *values_local, *values_global; double *bond_local, *bond_global; + double *angle_local, *angle_global; double pos, pos1, dt, nktv2p, ftm2v; double area; class NeighList *list; From df708a67a5f56f6ac64bd03ac2f6b8f3033f1cb4 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Wed, 24 May 2023 11:55:08 +0300 Subject: [PATCH 251/448] Code for angle contribution to stress/mop --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 186 ++++++++++++++++++++++- 1 file changed, 184 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 8391622242..139c5b5903 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -18,6 +18,7 @@ #include "compute_stress_mop.h" +#include "angle.h" #include "atom.h" #include "atom_vec.h" #include "bond.h" @@ -123,6 +124,8 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : values_local = values_global = vector = nullptr; bond_local = nullptr; bond_global = nullptr; + angle_local = nullptr; + angle_global = nullptr; // this fix produces a global vector @@ -131,6 +134,8 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : memory->create(values_global,nvalues,"stress/mop/spatial:values_global"); memory->create(bond_local,nvalues,"stress/mop/spatial:bond_local"); memory->create(bond_global,nvalues,"stress/mop/spatial:bond_global"); + memory->create(angle_local,nvalues,"stress/mop/spatial:angle_local"); + memory->create(angle_global,nvalues,"stress/mop/spatial:angle_global"); size_vector = nvalues; vector_flag = 1; @@ -149,6 +154,8 @@ ComputeStressMop::~ComputeStressMop() memory->destroy(values_global); memory->destroy(bond_local); memory->destroy(bond_global); + memory->destroy(angle_local); + memory->destroy(angle_global); memory->destroy(vector); } @@ -197,7 +204,8 @@ void ComputeStressMop::init() //if (force->bond!=nullptr) // error->warning(FLERR,"compute stress/mop does not account for bond potentials"); if (force->angle!=nullptr) - error->warning(FLERR,"compute stress/mop does not account for angle potentials"); + if (force->angle->born_matrix_enable == 0) + error->warning(FLERR,"compute stress/mop does not account for angle potentials"); if (force->dihedral!=nullptr) error->warning(FLERR,"compute stress/mop does not account for dihedral potentials"); if (force->improper!=nullptr) @@ -239,8 +247,14 @@ void ComputeStressMop::compute_vector() // sum bond contribution over all procs MPI_Allreduce(bond_local,bond_global,nvalues,MPI_DOUBLE,MPI_SUM,world); + //Compute angle contribution on separate procs + compute_angles(); + + // sum angle contribution over all procs + MPI_Allreduce(angle_local,angle_global,nvalues,MPI_DOUBLE,MPI_SUM,world); + for (int m=0; mx; + tagint *tag = atom->tag; + int *num_angle = atom->num_angle; + tagint **angle_atom1 = atom->angle_atom1; + tagint **angle_atom2 = atom->angle_atom2; + tagint **angle_atom3 = atom->angle_atom3; + int **angle_type = atom->angle_type; + int *mask = atom->mask; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int nlocal = atom->nlocal; + int molecular = atom->molecular; + + // loop over all atoms and their angles + + Angle *angle = force->angle; + + double duang, du2ang; + double dx[3] {0}; + double dx_left[3] {0}; + double dx_right[3] {0}; + double x_angle_left[3] {0}; + double x_angle_middle[3] {0}; + double x_angle_right[3] {0}; + double dcos_theta[3] {0}; + double local_contribution[3] {0}; + + // initialization + for (int i {0}; i < nvalues; i++) angle_local[i] = 0.0; + + for (atom2 = 0; atom2 < nlocal; atom2++) { + if (!(mask[atom2] & groupbit)) continue; + + if (molecular == 1) + na = num_angle[atom2]; + else { + if (molindex[atom2] < 0) continue; + imol = molindex[atom2]; + iatom = molatom[atom2]; + na = onemols[imol]->num_angle[iatom]; + } + + for (int i = 0; i < na; i++) { + if (molecular == 1) { + if (tag[atom2] != angle_atom2[atom2][i]) continue; + atype = angle_type[atom2][i]; + atom1 = atom->map(angle_atom1[atom2][i]); + atom3 = atom->map(angle_atom3[atom2][i]); + } else { + if (tag[atom2] != onemols[imol]->angle_atom2[atom2][i]) continue; + atype = onemols[imol]->angle_type[atom2][i]; + tagprev = tag[atom2] - iatom - 1; + atom1 = atom->map(onemols[imol]->angle_atom1[atom2][i] + tagprev); + atom3 = atom->map(onemols[imol]->angle_atom3[atom2][i] + tagprev); + } + + if (atom1 < 0 || !(mask[atom1] & groupbit)) continue; + if (atom3 < 0 || !(mask[atom3] & groupbit)) continue; + if (atype <= 0) continue; + + // minimum image of atom1 with respect to the plane of interest + dx[0] = x[atom1][0]; + dx[1] = x[atom1][1]; + dx[2] = x[atom1][2]; + dx[dir] -= pos; + domain->minimum_image(dx[0], dx[1], dx[2]); + x_angle_left[0] = dx[0]; + x_angle_left[1] = dx[1]; + x_angle_left[2] = dx[2]; + x_angle_left[dir] += pos; + // minimum image of atom2 with respect to atom1 + dx_left[0] = x[atom2][0] - x_angle_left[0]; + dx_left[1] = x[atom2][1] - x_angle_left[1]; + dx_left[2] = x[atom2][2] - x_angle_left[2]; + domain->minimum_image(dx_left[0], dx_left[1], dx_left[2]); + x_angle_middle[0] = x_angle_left[0] + dx_left[0]; + x_angle_middle[1] = x_angle_left[1] + dx_left[1]; + x_angle_middle[2] = x_angle_left[2] + dx_left[2]; + + // minimum image of atom3 with respect to atom2 + dx_right[0] = x[atom3][0] - x_angle_middle[0]; + dx_right[1] = x[atom3][1] - x_angle_middle[1]; + dx_right[2] = x[atom3][2] - x_angle_middle[2]; + domain->minimum_image(dx_right[0], dx_right[1], dx_right[2]); + x_angle_right[0] = x_angle_middle[0] + dx_right[0]; + x_angle_right[1] = x_angle_middle[1] + dx_right[1]; + x_angle_right[2] = x_angle_middle[2] + dx_right[2]; + + // check if any bond vector crosses the plane of interest + double tau_right = (x_angle_right[dir] - pos) / (x_angle_right[dir] - x_angle_middle[dir]); + double tau_left = (x_angle_middle[dir] - pos) / (x_angle_middle[dir] - x_angle_left[dir]); + bool right_cross = ((tau_right >=0) && (tau_right <= 1)); + bool left_cross = ((tau_left >=0) && (tau_left <= 1)); + + // no bonds crossing the plane + if (!right_cross && !left_cross) continue; + + // compute the cos(theta) of the angle + r1 = sqrt(dx_left[0]*dx_left[0] + dx_left[1]*dx_left[1] + dx_left[2]*dx_left[2]); + r2 = sqrt(dx_right[0]*dx_right[0] + dx_right[1]*dx_right[1] + dx_right[2]*dx_right[2]); + cos_theta = (dx_right[0]*dx_left[0] + dx_right[1]*dx_left[1] + dx_right[2]*dx_left[2])/(r1*r2); + + if (cos_theta > 1.0) cos_theta = 1.0; + if (cos_theta < -1.0) cos_theta = -1.0; + + // The method returns derivative with regards to cos(theta) + angle->born_matrix(atype, atom1, atom2, atom3, duang, du2ang); + // only right bond crossing the plane + if (right_cross && !left_cross) + { + dcos_theta[0] = (dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; + dcos_theta[1] = (dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; + dcos_theta[2] = (dx_right[1]*cos_theta/r2 - dx_left[2]/r1)/r2; + } + + // only left bond crossing the plane + if (!right_cross && left_cross) + { + dcos_theta[0] = -(dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; + dcos_theta[1] = -(dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; + dcos_theta[2] = -(dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; + } + + // both bonds crossing the plane + if (right_cross && left_cross) + { + // due to right bond + dcos_theta[0] = -(dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; + dcos_theta[1] = -(dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; + dcos_theta[2] = -(dx_right[1]*cos_theta/r2 - dx_left[2]/r1)/r2; + + // due to left bond + dcos_theta[0] += (dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; + dcos_theta[1] += (dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; + dcos_theta[2] += (dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; + } + + // final contribution of the given angle term + local_contribution[0] += duang*dcos_theta[0]/area*nktv2p; + local_contribution[1] += duang*dcos_theta[1]/area*nktv2p; + local_contribution[2] += duang*dcos_theta[2]/area*nktv2p; + } + } + // loop over the keywords and if necessary add the angle contribution + int m {0}; + while (m Date: Wed, 24 May 2023 16:24:33 +0300 Subject: [PATCH 252/448] fixing bug with sign for angle contribution in compute_stress_mop.cpp --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 139c5b5903..ff7c6d9e1b 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -705,14 +705,14 @@ void ComputeStressMop::compute_angles() if (right_cross && left_cross) { // due to right bond - dcos_theta[0] = -(dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; - dcos_theta[1] = -(dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; - dcos_theta[2] = -(dx_right[1]*cos_theta/r2 - dx_left[2]/r1)/r2; + dcos_theta[0] = (dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; + dcos_theta[1] = (dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; + dcos_theta[2] = (dx_right[1]*cos_theta/r2 - dx_left[2]/r1)/r2; // due to left bond - dcos_theta[0] += (dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; - dcos_theta[1] += (dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; - dcos_theta[2] += (dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; + dcos_theta[0] -= (dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; + dcos_theta[1] -= (dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; + dcos_theta[2] -= (dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; } // final contribution of the given angle term From c7c8b065a259979e7fcd3b6ccc777d3068a68d52 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Wed, 24 May 2023 16:49:35 +0300 Subject: [PATCH 253/448] fixing bug with sign issue for bond contribution in compute_stress_mop.cpp --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index ff7c6d9e1b..2454f93b7a 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -546,9 +546,10 @@ void ComputeStressMop::compute_bonds() rsq = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; bond->single(btype, rsq, atom1, atom2, fpair); - local_contribution[0] += fpair*dx[0]/area*nktv2p; - local_contribution[1] += fpair*dx[1]/area*nktv2p; - local_contribution[2] += fpair*dx[2]/area*nktv2p; + double sgn = copysign(1.0, x_bond_1[dir] - pos); + local_contribution[0] += sgn*fpair*dx[0]/area*nktv2p; + local_contribution[1] += sgn*fpair*dx[1]/area*nktv2p; + local_contribution[2] += sgn*fpair*dx[2]/area*nktv2p; } } } From 9ee40cceef79043d8c6c8c41e41093e227f97ff6 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Wed, 24 May 2023 17:01:13 +0300 Subject: [PATCH 254/448] fixing indexing issue and more sign problems for angle contributions --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 27 +++++++++++++----------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 2454f93b7a..63d671eee7 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -689,31 +689,34 @@ void ComputeStressMop::compute_angles() // only right bond crossing the plane if (right_cross && !left_cross) { - dcos_theta[0] = (dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; - dcos_theta[1] = (dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; - dcos_theta[2] = (dx_right[1]*cos_theta/r2 - dx_left[2]/r1)/r2; + double sgn = copysign(1.0, x_angle_right[dir] - pos); + dcos_theta[0] = sgn*(dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; + dcos_theta[1] = sgn*(dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; + dcos_theta[2] = sgn*(dx_right[2]*cos_theta/r2 - dx_left[2]/r1)/r2; } // only left bond crossing the plane if (!right_cross && left_cross) { - dcos_theta[0] = -(dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; - dcos_theta[1] = -(dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; - dcos_theta[2] = -(dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; + double sgn = copysign(1.0, x_angle_left[dir] - pos); + dcos_theta[0] = -sgn*(dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; + dcos_theta[1] = -sgn*(dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; + dcos_theta[2] = -sgn*(dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; } // both bonds crossing the plane if (right_cross && left_cross) { // due to right bond - dcos_theta[0] = (dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; - dcos_theta[1] = (dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; - dcos_theta[2] = (dx_right[1]*cos_theta/r2 - dx_left[2]/r1)/r2; + double sgn = copysign(1.0, x_angle_middle[dir] - pos); + dcos_theta[0] = -sgn*(dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; + dcos_theta[1] = -sgn*(dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; + dcos_theta[2] = -sgn*(dx_right[2]*cos_theta/r2 - dx_left[2]/r1)/r2; // due to left bond - dcos_theta[0] -= (dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; - dcos_theta[1] -= (dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; - dcos_theta[2] -= (dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; + dcos_theta[0] += sgn*(dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; + dcos_theta[1] += sgn*(dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; + dcos_theta[2] += sgn*(dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; } // final contribution of the given angle term From ecca46acf9fd283e2c40e57a3135618c9108a9eb Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Tue, 9 May 2023 17:11:06 +0200 Subject: [PATCH 255/448] Include bond interactions in force --- .../compute_stress_cartesian.cpp | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index 53ff70c561..d2b9fe7bd7 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -14,6 +14,7 @@ #include "compute_stress_cartesian.h" #include "atom.h" +#include "bond.h" #include "citeme.h" #include "comm.h" #include "domain.h" @@ -365,6 +366,38 @@ void ComputeStressCartesian::compute_array() } } + // Loop over all bonds + for (int i_bond = 0; i_bond < neighbor->nbondlist; i_bond++) { + // i == atom1, j == atom2 + int i = neighbor->bondlist[i_bond][0]; + int j = neighbor->bondlist[i_bond][1]; + int type = neighbor->bondlist[i_bond][2]; + + // Skip if one of both atoms is not in group + if (!(atom->mask[i] & groupbit)) continue; + if (!(atom->mask[j] & groupbit)) continue; + + // if newton_bond is off and atom2 is a ghost atom, only compute this on one processor + if (!force->newton_bond && j >= atom->nlocal) { + if (tag[i] > tag[j]) { + if ((tag[i] + tag[j]) % 2 == 0) continue; + } else if (tag[i] < tag[j]) { + if ((tag[i] < tag[j]) % 2 == 1) continue; + } + } + + double dx = x[j][0] - x[i][0]; + double dy = x[j][1] - x[i][1]; + double dz = x[j][2] - x[i][2]; + double rsq = dx*dx + dy*dy + dz*dz; + double xi = x[i][dir1] - boxlo[dir1]; + double yi = x[i][dir2] - boxlo[dir2]; + + double fbond; + force->bond->single(type, rsq, i, j, fbond); + compute_pressure(fbond, xi, yi, dx, dy, dz); + } + // normalize pressure for (bin = 0; bin < nbins1 * nbins2; bin++) { tdens[bin] *= invV; From e246864682f00655749a3a251965f82a81dae3d3 Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Wed, 24 May 2023 16:17:20 +0200 Subject: [PATCH 256/448] Refactor compute_array() and compute_pressure(): Remove unnecessary copies of variables, declare variables locally so they are properly scoped --- .../compute_stress_cartesian.cpp | 136 +++++++----------- 1 file changed, 52 insertions(+), 84 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index d2b9fe7bd7..2f6e75b528 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -230,35 +230,16 @@ void ComputeStressCartesian::init_list(int /* id */, NeighList *ptr) void ComputeStressCartesian::compute_array() { - int i, j, ii, jj, inum, jnum, itype, jtype; - int bin, bin1, bin2; - tagint itag, jtag; - double xtmp, ytmp, ztmp, delx, dely, delz; - double rsq, fpair, factor_coul, factor_lj; - int *ilist, *jlist, *numneigh, **firstneigh; - double **x = atom->x; double **v = atom->v; - double *mass = atom->mass; tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - int nlocal = atom->nlocal; - double *special_coul = force->special_coul; - double *special_lj = force->special_lj; - int newton_pair = force->newton_pair; double *boxlo = domain->boxlo; // invoke half neighbor list (will copy or build if necessary) neighbor->build_one(list); - inum = list->inum; - ilist = list->ilist; - numneigh = list->numneigh; - firstneigh = list->firstneigh; - // Zero arrays - for (bin = 0; bin < nbins1 * nbins2; bin++) { + for (int bin = 0; bin < nbins1 * nbins2; bin++) { tdens[bin] = 0; tpkxx[bin] = 0; tpkyy[bin] = 0; @@ -269,9 +250,9 @@ void ComputeStressCartesian::compute_array() } // calculate number density and kinetic contribution to pressure - for (i = 0; i < nlocal; i++) { - bin1 = (int) ((x[i][dir1] - boxlo[dir1]) / bin_width1) % nbins1; - bin2 = 0; + for (int i = 0; i < atom->nlocal; i++) { + int bin1 = (int) ((x[i][dir1] - boxlo[dir1]) / bin_width1) % nbins1; + int bin2 = 0; if (dims == 2) bin2 = (int) ((x[i][dir2] - boxlo[dir2]) / bin_width2) % nbins2; // Apply periodic boundary conditions and avoid out of range access @@ -295,73 +276,59 @@ void ComputeStressCartesian::compute_array() else if (bin2 >= nbins2) bin2 = nbins2 - 1; - j = bin1 + bin2 * nbins1; + int j = bin1 + bin2 * nbins1; tdens[j] += 1; - tpkxx[j] += mass[type[i]] * v[i][0] * v[i][0]; - tpkyy[j] += mass[type[i]] * v[i][1] * v[i][1]; - tpkzz[j] += mass[type[i]] * v[i][2] * v[i][2]; + tpkxx[j] += atom->mass[atom->type[i]] * v[i][0] * v[i][0]; + tpkyy[j] += atom->mass[atom->type[i]] * v[i][1] * v[i][1]; + tpkzz[j] += atom->mass[atom->type[i]] * v[i][2] * v[i][2]; } // loop over neighbors of my atoms - // skip if I or J are not in group - // for newton = 0 and J = ghost atom, - // need to ensure I,J pair is only output by one proc - // use same itag,jtag logic as in Neighbor::neigh_half_nsq() - // for flag = 0, just count pair interactions within force cutoff - // for flag = 1, calculate requested output fields + for (int ii = 0; ii < list->inum; ii++) { + int i = list->ilist[ii]; - Pair *pair = force->pair; - double **cutsq = force->pair->cutsq; + // skip if I or J are not in group + if (!(atom->mask[i] & groupbit)) continue; - double xi1, xi2; + double xi1 = x[i][dir1] - boxlo[dir1]; + double xi2 = x[i][dir2] - boxlo[dir2]; - for (ii = 0; ii < inum; ii++) { - i = ilist[ii]; - if (!(mask[i] & groupbit)) continue; - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - xi1 = x[i][dir1] - boxlo[dir1]; - xi2 = x[i][dir2] - boxlo[dir2]; - itag = tag[i]; - itype = type[i]; - jlist = firstneigh[i]; - jnum = numneigh[i]; - - for (jj = 0; jj < jnum; jj++) { - j = jlist[jj]; - factor_lj = special_lj[sbmask(j)]; - factor_coul = special_coul[sbmask(j)]; + for (int jj = 0; jj < list->numneigh[i]; jj++) { + int j = list->firstneigh[i][jj]; + double factor_lj = force->special_lj[sbmask(j)]; + double factor_coul = force->special_coul[sbmask(j)]; j &= NEIGHMASK; - if (!(mask[j] & groupbit)) continue; + if (!(atom->mask[j] & groupbit)) continue; - // itag = jtag is possible for long cutoffs that include images of self - // do calculation only on appropriate processor - if (newton_pair == 0 && j >= nlocal) { - jtag = tag[j]; - if (itag > jtag) { - if ((itag + jtag) % 2 == 0) continue; - } else if (itag < jtag) { - if ((itag + jtag) % 2 == 1) continue; + // for newton = 0 and J = ghost atom, need to ensure I,J pair is only output by one proc + // use same tag[i],tag[j] logic as in Neighbor::neigh_half_nsq() + if (force->newton_pair == 0 && j >= atom->nlocal) { + if (tag[i] > tag[j]) { + if ((tag[i] + tag[j]) % 2 == 0) continue; + } else if (tag[i] < tag[j]) { + if ((tag[i] + tag[j]) % 2 == 1) continue; } else { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + // tag[i] = tag[j] is possible for long cutoffs that include images of self + if (x[j][2] < x[i][2]) continue; + if (x[j][2] == x[i][2]) { + if (x[j][1] < x[i][1]) continue; + if (x[j][1] == x[i][1] && x[j][0] < x[i][0]) continue; } } } - delx = x[j][0] - xtmp; - dely = x[j][1] - ytmp; - delz = x[j][2] - ztmp; - rsq = delx * delx + dely * dely + delz * delz; - jtype = type[j]; + double delx = x[j][0] - x[i][0]; + double dely = x[j][1] - x[i][1]; + double delz = x[j][2] - x[i][2]; + double rsq = delx * delx + dely * dely + delz * delz; // Check if inside cut-off - if (rsq >= cutsq[itype][jtype]) continue; - pair->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fpair); + int itype = atom->type[i]; + int jtype = atom->type[j]; + if (rsq >= force->pair->cutsq[itype][jtype]) continue; + + double fpair; + force->pair->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fpair); compute_pressure(fpair, xi1, xi2, delx, dely, delz); } } @@ -399,7 +366,7 @@ void ComputeStressCartesian::compute_array() } // normalize pressure - for (bin = 0; bin < nbins1 * nbins2; bin++) { + for (int bin = 0; bin < nbins1 * nbins2; bin++) { tdens[bin] *= invV; tpkxx[bin] *= invV; tpkyy[bin] *= invV; @@ -419,7 +386,7 @@ void ComputeStressCartesian::compute_array() MPI_Allreduce(tpczz, pczz, nbins1 * nbins2, MPI_DOUBLE, MPI_SUM, world); // populate array to output. - for (bin = 0; bin < nbins1 * nbins2; bin++) { + for (int bin = 0; bin < nbins1 * nbins2; bin++) { array[bin][0] = (bin % nbins1 + 0.5) * bin_width1; if (dims == 2) array[bin][1] = ((int) (bin / nbins1) + 0.5) * bin_width2; array[bin][0 + dims] = dens[bin]; @@ -435,25 +402,26 @@ void ComputeStressCartesian::compute_array() void ComputeStressCartesian::compute_pressure(double fpair, double xi, double yi, double delx, double dely, double delz) { - int bin1, bin2, next_bin1, next_bin2; double la = 0.0, lb = 0.0, l_sum = 0.0; double rij[3] = {delx, dely, delz}; - double l1 = 0.0, l2, rij1, rij2; - rij1 = rij[dir1]; - rij2 = rij[dir2]; + double rij1 = rij[dir1]; + double rij2 = rij[dir2]; - next_bin1 = (int) floor(xi / bin_width1); - next_bin2 = (int) floor(yi / bin_width2); + int next_bin1 = (int) floor(xi / bin_width1); + int next_bin2 = (int) floor(yi / bin_width2); // Integrating along line while (lb < 1.0) { - bin1 = next_bin1; - bin2 = next_bin2; + int bin1 = next_bin1; + int bin2 = next_bin2; + double l1; if (rij1 > 0) l1 = ((bin1 + 1) * bin_width1 - xi) / rij1; else l1 = (bin1 * bin_width1 - xi) / rij1; + + double l2; if (rij2 > 0) l2 = ((bin2 + 1) * bin_width2 - yi) / rij2; else From 8e6615918b0c7414664e17cea86378921d132069 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Thu, 25 May 2023 14:39:03 +0300 Subject: [PATCH 257/448] avoid crashing when no bonds or no angles exist --- src/EXTRA-COMPUTE/compute_stress_mop.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.h b/src/EXTRA-COMPUTE/compute_stress_mop.h index d1074e002a..791e18d624 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.h +++ b/src/EXTRA-COMPUTE/compute_stress_mop.h @@ -44,6 +44,8 @@ class ComputeStressMop : public Compute { int me, nvalues, dir; int *which; + int bondflag, angleflag; + double *values_local, *values_global; double *bond_local, *bond_global; double *angle_local, *angle_global; From f26f397e087c183facd9e1cb108fe7f1b777a221 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Thu, 25 May 2023 14:47:20 +0300 Subject: [PATCH 258/448] avoid crashing when there are no bonds or no angles --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 27 ++++++++++++++++++------ 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 63d671eee7..e7a602e583 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -51,6 +51,9 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : MPI_Comm_rank(world,&me); + bondflag = 0; + angleflag = 0; + // set compute mode and direction of plane(s) for pressure calculation if (strcmp(arg[3],"x")==0) { @@ -201,11 +204,13 @@ void ComputeStressMop::init() //Compute stress/mop only accounts for pair interactions. // issue a warning if any intramolecular potential or Kspace is defined. - //if (force->bond!=nullptr) - // error->warning(FLERR,"compute stress/mop does not account for bond potentials"); + if (force->bond!=nullptr) bondflag = 1; if (force->angle!=nullptr) - if (force->angle->born_matrix_enable == 0) + if (force->angle->born_matrix_enable == 0) { error->warning(FLERR,"compute stress/mop does not account for angle potentials"); + } else { + angleflag = 1; + } if (force->dihedral!=nullptr) error->warning(FLERR,"compute stress/mop does not account for dihedral potentials"); if (force->improper!=nullptr) @@ -241,14 +246,22 @@ void ComputeStressMop::compute_vector() MPI_Allreduce(values_local,values_global,nvalues, MPI_DOUBLE,MPI_SUM,world); - //Compute bond contribution on separate procs - compute_bonds(); + if (bondflag) { + //Compute bond contribution on separate procs + compute_bonds(); + } else { + for (int i=0; i Date: Thu, 25 May 2023 12:58:57 -0600 Subject: [PATCH 259/448] Fixing mistakes in doc pages --- doc/src/compute_fabric.rst | 12 ++++++------ doc/src/pair_granular.rst | 2 +- src/GRANULAR/gran_sub_mod_normal.cpp | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/src/compute_fabric.rst b/doc/src/compute_fabric.rst index f1a5d3d7f9..b38ffafa48 100644 --- a/doc/src/compute_fabric.rst +++ b/doc/src/compute_fabric.rst @@ -146,13 +146,13 @@ m to :math:`M` (inclusive). A middle asterisk means all types from m to n Output info """"""""""" -This compute calculates a local vector of doubles and a scalar. The vector -stores the unique components of the first requested tensor in the order -:math:`xx`, :math:`yy`, :math:`zz`, :math:`xy`, :math:`xz`, :math:`yz` -followed by the same components for all subsequent tensors. +This compute calculates a global vector of doubles and a global scalar. The +vector stores the unique components of the first requested tensor in the +order :math:`xx`, :math:`yy`, :math:`zz`, :math:`xy`, :math:`xz`, +:math:`yz` followed by the same components for all subsequent tensors. The length of the vector is therefore six times the number of requested -tensors. The scalar output is the number of pairwise interactions included in -the calculation of the fabric tensor. +tensors. The scalar output is the number of pairwise interactions included +in the calculation of the fabric tensor. Restrictions """""""""""" diff --git a/doc/src/pair_granular.rst b/doc/src/pair_granular.rst index 0911a3486a..8a4d44fbf7 100644 --- a/doc/src/pair_granular.rst +++ b/doc/src/pair_granular.rst @@ -736,7 +736,7 @@ or .. math:: - E_{eff,ij} = \frac{E_{ij}}{2(1-\nu_{ij})} + E_{eff,ij} = \frac{E_{ij}}{2(1-\nu_{ij}^2)} These pair styles write their information to :doc:`binary restart files `, so a pair_style command does not need to be specified in an input script that reads a restart file. diff --git a/src/GRANULAR/gran_sub_mod_normal.cpp b/src/GRANULAR/gran_sub_mod_normal.cpp index 05639feb9d..f08892d6f2 100644 --- a/src/GRANULAR/gran_sub_mod_normal.cpp +++ b/src/GRANULAR/gran_sub_mod_normal.cpp @@ -167,7 +167,7 @@ void GranSubModNormalHertzMaterial::coeffs_to_local() void GranSubModNormalHertzMaterial::mix_coeffs(double* icoeffs, double* jcoeffs) { - coeffs[0] = mix_stiffnessE(icoeffs[0], jcoeffs[0],icoeffs[2], jcoeffs[2]); + coeffs[0] = mix_stiffnessE(icoeffs[0], jcoeffs[0], icoeffs[2], jcoeffs[2]); coeffs[1] = mix_geom(icoeffs[1], jcoeffs[1]); coeffs[2] = mix_geom(icoeffs[2], jcoeffs[2]); coeffs_to_local(); From edfb8cf10021ec15509a3cb04e306496222eeff4 Mon Sep 17 00:00:00 2001 From: jtclemm Date: Thu, 25 May 2023 13:54:12 -0600 Subject: [PATCH 260/448] Fixing double mixing of normal coeffs --- src/GRANULAR/gran_sub_mod_normal.cpp | 50 ++++++++++++++++++++-------- src/GRANULAR/gran_sub_mod_normal.h | 4 +++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/GRANULAR/gran_sub_mod_normal.cpp b/src/GRANULAR/gran_sub_mod_normal.cpp index f08892d6f2..9e19cab1f4 100644 --- a/src/GRANULAR/gran_sub_mod_normal.cpp +++ b/src/GRANULAR/gran_sub_mod_normal.cpp @@ -145,6 +145,7 @@ GranSubModNormalHertzMaterial::GranSubModNormalHertzMaterial(GranularModel *gm, material_properties = 1; num_coeffs = 3; contact_radius_flag = 1; + mixed_coefficients = 0; } /* ---------------------------------------------------------------------- */ @@ -154,10 +155,12 @@ void GranSubModNormalHertzMaterial::coeffs_to_local() Emod = coeffs[0]; damp = coeffs[1]; poiss = coeffs[2]; - if (gm->contact_type == PAIR) { - k = FOURTHIRDS * mix_stiffnessE(Emod, Emod, poiss, poiss); - } else { - k = FOURTHIRDS * mix_stiffnessE_wall(Emod, poiss); + if (!mixed_coefficients) { + if (gm->contact_type == PAIR) { + k = FOURTHIRDS * mix_stiffnessE(Emod, Emod, poiss, poiss); + } else { + k = FOURTHIRDS * mix_stiffnessE_wall(Emod, poiss); + } } if (Emod < 0.0 || damp < 0.0) error->all(FLERR, "Illegal Hertz material normal model"); @@ -170,6 +173,10 @@ void GranSubModNormalHertzMaterial::mix_coeffs(double* icoeffs, double* jcoeffs) coeffs[0] = mix_stiffnessE(icoeffs[0], jcoeffs[0], icoeffs[2], jcoeffs[2]); coeffs[1] = mix_geom(icoeffs[1], jcoeffs[1]); coeffs[2] = mix_geom(icoeffs[2], jcoeffs[2]); + + k = FOURTHIRDS * coeffs[0]; + mixed_coefficients = 1; + coeffs_to_local(); } @@ -183,6 +190,7 @@ GranSubModNormalDMT::GranSubModNormalDMT(GranularModel *gm, LAMMPS *lmp) : GranS cohesive_flag = 1; num_coeffs = 4; contact_radius_flag = 1; + mixed_coefficients = 0; } /* ---------------------------------------------------------------------- */ @@ -193,10 +201,13 @@ void GranSubModNormalDMT::coeffs_to_local() damp = coeffs[1]; poiss = coeffs[2]; cohesion = coeffs[3]; - if (gm->contact_type == PAIR) { - k = FOURTHIRDS * mix_stiffnessE(Emod, Emod, poiss, poiss); - } else { - k = FOURTHIRDS * mix_stiffnessE_wall(Emod, poiss); + + if (!mixed_coefficients) { + if (gm->contact_type == PAIR) { + k = FOURTHIRDS * mix_stiffnessE(Emod, Emod, poiss, poiss); + } else { + k = FOURTHIRDS * mix_stiffnessE_wall(Emod, poiss); + } } if (Emod < 0.0 || damp < 0.0) error->all(FLERR, "Illegal DMT normal model"); @@ -206,10 +217,14 @@ void GranSubModNormalDMT::coeffs_to_local() void GranSubModNormalDMT::mix_coeffs(double* icoeffs, double* jcoeffs) { - coeffs[0] = mix_stiffnessE(icoeffs[0], jcoeffs[0],icoeffs[2], jcoeffs[2]); + coeffs[0] = mix_stiffnessE(icoeffs[0], jcoeffs[0], icoeffs[2], jcoeffs[2]); coeffs[1] = mix_geom(icoeffs[1], jcoeffs[1]); coeffs[2] = mix_geom(icoeffs[2], jcoeffs[2]); coeffs[3] = mix_geom(icoeffs[3], jcoeffs[3]); + + k = FOURTHIRDS * coeffs[0]; + mixed_coefficients = 1; + coeffs_to_local(); } @@ -241,6 +256,7 @@ GranSubModNormalJKR::GranSubModNormalJKR(GranularModel *gm, LAMMPS *lmp) : GranS beyond_contact = 1; num_coeffs = 4; contact_radius_flag = 1; + mixed_coefficients = 0; } /* ---------------------------------------------------------------------- */ @@ -252,10 +268,12 @@ void GranSubModNormalJKR::coeffs_to_local() poiss = coeffs[2]; cohesion = coeffs[3]; - if (gm->contact_type == PAIR) { - Emix = mix_stiffnessE(Emod, Emod, poiss, poiss); - } else { - Emix = mix_stiffnessE_wall(Emod, poiss); + if (!mixed_coefficients) { + if (gm->contact_type == PAIR) { + Emix = mix_stiffnessE(Emod, Emod, poiss, poiss); + } else { + Emix = mix_stiffnessE_wall(Emod, poiss); + } } k = FOURTHIRDS * Emix; @@ -267,10 +285,14 @@ void GranSubModNormalJKR::coeffs_to_local() void GranSubModNormalJKR::mix_coeffs(double* icoeffs, double* jcoeffs) { - coeffs[0] = mix_stiffnessE(icoeffs[0], jcoeffs[0],icoeffs[2], jcoeffs[2]); + coeffs[0] = mix_stiffnessE(icoeffs[0], jcoeffs[0], icoeffs[2], jcoeffs[2]); coeffs[1] = mix_geom(icoeffs[1], jcoeffs[1]); coeffs[2] = mix_geom(icoeffs[2], jcoeffs[2]); coeffs[3] = mix_geom(icoeffs[3], jcoeffs[3]); + + Emix = coeffs[0]; + mixed_coefficients = 1; + coeffs_to_local(); } diff --git a/src/GRANULAR/gran_sub_mod_normal.h b/src/GRANULAR/gran_sub_mod_normal.h index ef022f864f..15e4c28701 100644 --- a/src/GRANULAR/gran_sub_mod_normal.h +++ b/src/GRANULAR/gran_sub_mod_normal.h @@ -99,6 +99,8 @@ class GranSubModNormalHertzMaterial : public GranSubModNormalHertz { GranSubModNormalHertzMaterial(class GranularModel *, class LAMMPS *); void coeffs_to_local() override; void mix_coeffs(double*, double*) override; + private: + int mixed_coefficients; }; /* ---------------------------------------------------------------------- */ @@ -113,6 +115,7 @@ class GranSubModNormalDMT : public GranSubModNormal { protected: double k, cohesion; double F_pulloff, Fne; + int mixed_coefficients; }; /* ---------------------------------------------------------------------- */ @@ -130,6 +133,7 @@ class GranSubModNormalJKR : public GranSubModNormal { protected: double k, cohesion; double Emix, F_pulloff, Fne; + int mixed_coefficients; }; } // namespace Granular_NS From 3d8df660c350b256bb6759f7c5783a5cf8af77f1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 25 May 2023 18:08:42 -0400 Subject: [PATCH 261/448] make rigid water examples more realistic and consistent. avoid warnings. --- doc/src/Howto_spc.rst | 6 ++---- doc/src/Howto_tip3p.rst | 4 ++-- doc/src/Howto_tip4p.rst | 13 +++++++------ doc/src/Howto_tip5p.rst | 5 +++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/src/Howto_spc.rst b/doc/src/Howto_spc.rst index 6414d3b846..6dedfe40c4 100644 --- a/doc/src/Howto_spc.rst +++ b/doc/src/Howto_spc.rst @@ -69,15 +69,13 @@ SPC/E with rigid bonds. timestep 1.0 fix rigid all shake 0.0001 10 10000 b 1 a 1 minimize 0.0 0.0 1000 10000 - run 0 post no - reset_timestep 0 velocity all create 300.0 5463576 - fix integrate all nvt temp 300.0 300.0 1.0 + fix integrate all nvt temp 300.0 300.0 100.0 thermo_style custom step temp press etotal density pe ke thermo 1000 run 20000 upto - write_data tip4p.data nocoeff + write_data spce.data nocoeff .. _spce_molecule: .. code-block:: diff --git a/doc/src/Howto_tip3p.rst b/doc/src/Howto_tip3p.rst index 682c7f2640..5419b9ba1b 100644 --- a/doc/src/Howto_tip3p.rst +++ b/doc/src/Howto_tip3p.rst @@ -128,11 +128,11 @@ TIP3P with rigid bonds. fix rigid all shake 0.001 10 10000 b 1 a 1 minimize 0.0 0.0 1000 10000 - run 0 post no reset_timestep 0 + timestep 1.0 velocity all create 300.0 5463576 - fix integrate all nvt temp 300 300 1.0 + fix integrate all nvt temp 300 300 100.0 thermo_style custom step temp press etotal pe diff --git a/doc/src/Howto_tip4p.rst b/doc/src/Howto_tip4p.rst index 7775d43e76..4d9b514e0d 100644 --- a/doc/src/Howto_tip4p.rst +++ b/doc/src/Howto_tip4p.rst @@ -180,17 +180,17 @@ file changed): fix rigid all shake 0.001 10 10000 b 1 a 1 minimize 0.0 0.0 1000 10000 - run 0 post no reset_timestep 0 + timestep 1.0 velocity all create 300.0 5463576 - fix integrate all nvt temp 300 300 1.0 + fix integrate all nvt temp 300 300 100.0 thermo_style custom step temp press etotal pe thermo 1000 run 20000 - write_data tip3p.data nocoeff + write_data tip4p-implicit.data nocoeff Below is the code for a LAMMPS input file using the explicit method and a TIP4P molecule file. Because of using :doc:`fix rigid/nvt/small @@ -203,6 +203,7 @@ rigid/nvt/small can identify rigid bodies by their molecule ID: units real atom_style charge + atom_modify map array region box block -5 5 -5 5 -5 5 create_box 3 box @@ -219,14 +220,14 @@ rigid/nvt/small can identify rigid bodies by their molecule ID: molecule water tip4p.mol create_atoms 0 random 33 34564 NULL mol water 25367 overlap 1.33 - timestep 0.1 - fix integrate all rigid/nvt/small molecule temp 300.0 300.0 1.0 + timestep 0.5 + fix integrate all rigid/nvt/small molecule temp 300.0 300.0 100.0 velocity all create 300.0 5463576 thermo_style custom step temp press etotal density pe ke thermo 1000 run 20000 - write_data tip4p.data nocoeff + write_data tip4p-explicit.data nocoeff .. _tip4p_molecule: .. code-block:: diff --git a/doc/src/Howto_tip5p.rst b/doc/src/Howto_tip5p.rst index 21cc78a684..10674a04b6 100644 --- a/doc/src/Howto_tip5p.rst +++ b/doc/src/Howto_tip5p.rst @@ -91,6 +91,7 @@ ID: units real atom_style charge + atom_modify map array region box block -5 5 -5 5 -5 5 create_box 3 box @@ -107,8 +108,8 @@ ID: molecule water tip5p.mol create_atoms 0 random 33 34564 NULL mol water 25367 overlap 1.33 - timestep 0.20 - fix integrate all rigid/nvt/small molecule temp 300.0 300.0 1.0 + timestep 0.5 + fix integrate all rigid/nvt/small molecule temp 300.0 300.0 100.0 reset_timestep 0 velocity all create 300.0 5463576 From 01b481ec4f708ebeef3e856dcb3b9ab8ab53d289 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 26 May 2023 15:27:15 -0700 Subject: [PATCH 262/448] Small tweaks --- doc/src/fix_efield.rst | 10 +++++----- doc/src/fix_qeq_reaxff.rst | 3 +-- src/REAXFF/fix_qeq_reaxff.cpp | 3 +-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/doc/src/fix_efield.rst b/doc/src/fix_efield.rst index 271912097f..0b94f80b8c 100644 --- a/doc/src/fix_efield.rst +++ b/doc/src/fix_efield.rst @@ -136,10 +136,10 @@ due to the electric field were a spring-like F = kx, then the energy formula should be E = -0.5kx\^2. If you don't do this correctly, the minimization will not converge properly. -The *potential* keyword can be used as an alternative to the *energy* -keyword to specify the name of an atom-style variable, which is used to compute -the added electric potential to each atom as a function of its position. -The variable should have units of electric field times distance (that is, +The *potential* keyword can be used as an alternative to the *energy* keyword +to specify the name of an atom-style variable, which is used to compute the +added electric potential to each atom as a function of its position. The +variable should have units of electric field multiplied by distance (that is, in `units real`, the potential should be in volts). As with the *energy* keyword, the variable name is specified as "v_name". The energy added by this fix is then calculated as the electric potential multiplied by charge. @@ -149,7 +149,7 @@ in simulations with :doc:`fix qeq/reaxff`, since with variable charges the electric potential can be known beforehand but the energy cannot. A small additional benefit is that the *energy* keyword requires an additional conversion to energy units which the *potential* keyword avoids. Thus, when the -*potential* keyword is specified the *energy* keyword is ignored (the simulation +*potential* keyword is specified, the *energy* keyword is ignored (the simulation will proceed but with a warning issued). As with *energy*, the *potential* keyword is not allowed if the added field is a constant vector. diff --git a/doc/src/fix_qeq_reaxff.rst b/doc/src/fix_qeq_reaxff.rst index 4422ddc89c..00cfb6d3ce 100644 --- a/doc/src/fix_qeq_reaxff.rst +++ b/doc/src/fix_qeq_reaxff.rst @@ -133,8 +133,7 @@ vector may only have components in non-periodic directions. Equal-style variables can be used for electric field vector components without any further settings. Atom-style variables can be used for spatially-varying electric field vector components, but the resulting electric potential must be specified -as an atom-style variable using the (new) *potential* keyword for -`fix efield`. +as an atom-style variable using the *potential* keyword for `fix efield`. Related commands """""""""""""""" diff --git a/src/REAXFF/fix_qeq_reaxff.cpp b/src/REAXFF/fix_qeq_reaxff.cpp index 4c0864ac27..554b911151 100644 --- a/src/REAXFF/fix_qeq_reaxff.cpp +++ b/src/REAXFF/fix_qeq_reaxff.cpp @@ -1111,9 +1111,8 @@ void FixQEqReaxFF::get_chi_field() const double factor = -1.0/qe2f; - if (efield->varflag != FixEfield::CONSTANT) { + if (efield->varflag != FixEfield::CONSTANT) efield->update_efield_variables(); - } // atom selection is for the group of fix efield From 458cce76999318fa4dd990aa57f5506d782d6b40 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sat, 27 May 2023 14:33:46 +0300 Subject: [PATCH 263/448] Updating unit test for mop to reflect the contribution from bonds --- unittest/commands/test_compute_global.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 6c365c8c2b..66a24f049f 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -225,9 +225,9 @@ TEST_F(ComputeGlobalTest, Geometry) EXPECT_DOUBLE_EQ(mom2[0], -0.022332069630161717); EXPECT_DOUBLE_EQ(mom2[1], -0.056896553865696115); EXPECT_DOUBLE_EQ(mom2[2], 0.069179891052881484); - EXPECT_DOUBLE_EQ(mop1[0], 3522311.3572200728); - EXPECT_DOUBLE_EQ(mop1[1], 2871104.9055934539); - EXPECT_DOUBLE_EQ(mop1[2], -4136077.5224247416); + EXPECT_DOUBLE_EQ(mop1[0], 3536584.0880458541); + EXPECT_DOUBLE_EQ(mop1[1], 2887485.033995091); + EXPECT_DOUBLE_EQ(mop1[2], -4154145.8952306858); EXPECT_DOUBLE_EQ(mop2[0][0], -8.0869239999999998); EXPECT_DOUBLE_EQ(mop2[0][1], 0.0); EXPECT_DOUBLE_EQ(mop2[0][2], 0.0); From b28ee36f000af8e90a70390b72f6d132312de43c Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sat, 27 May 2023 14:50:31 +0300 Subject: [PATCH 264/448] update documentation for compute stress/mop --- doc/src/compute_stress_mop.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index 4ad2261bb0..a8a3bc5660 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -117,8 +117,13 @@ size does not change in time, and axis-aligned planes. The method only works with two-body pair interactions, because it requires the class method pair->single() to be implemented. In -particular, it does not work with more than two-body pair interactions, -intra-molecular interactions, and long range (kspace) interactions. +particular, compute *stress/mop/profile* does not work with more than +two-body pair interactions, intra-molecular interactions, and long range +(kspace) interactions. Similarly, compute *stress/mop* does not work with more than +two-body pair interactions, long range (kspace) interactions and dihedral/improper +intramolecular interactions but works with all bond interactions with the class method +single() implemented and all angle interactions with the class method born_matrix() +implemented. Related commands """""""""""""""" From 4c4eb6ee1e00fcb0b7efefa8a6e47459e7dc5c33 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 28 May 2023 00:49:52 -0400 Subject: [PATCH 265/448] improve error message --- src/EXTRA-FIX/fix_electron_stopping.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/EXTRA-FIX/fix_electron_stopping.cpp b/src/EXTRA-FIX/fix_electron_stopping.cpp index 4a9421be6c..37f33f4ea0 100644 --- a/src/EXTRA-FIX/fix_electron_stopping.cpp +++ b/src/EXTRA-FIX/fix_electron_stopping.cpp @@ -175,7 +175,8 @@ void FixElectronStopping::post_force(int /*vflag*/) if (energy < Ecut) continue; if (energy < elstop_ranges[0][0]) continue; if (energy > elstop_ranges[0][table_entries - 1]) - error->one(FLERR, "Atom kinetic energy too high for fix electron/stopping"); + error->one(FLERR, "Fix electron/stopping: kinetic energy too high for atom {}: {} vs {}", + atom->tag[i], energy, elstop_ranges[0][table_entries - 1]); if (region) { // Only apply in the given region From f69b50408d98bc49ff0a6787e9ae59caea4d1a82 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 28 May 2023 11:47:32 -0400 Subject: [PATCH 266/448] improve error messages --- src/output.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/output.cpp b/src/output.cpp index 6282b85b76..ed8fa48831 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -276,7 +276,8 @@ void Output::setup(int memflag) auto nextrestart = static_cast (input->variable->compute_equal(ivar_restart_single)); if (nextrestart <= ntimestep) - error->all(FLERR,"Restart variable returned a bad timestep"); + error->all(FLERR,"Restart variable returned a bad next timestep: {} vs {}", + nextrestart, ntimestep); next_restart_single = nextrestart; } } else next_restart_single = update->laststep + 1; @@ -289,7 +290,8 @@ void Output::setup(int memflag) auto nextrestart = static_cast (input->variable->compute_equal(ivar_restart_double)); if (nextrestart <= ntimestep) - error->all(FLERR,"Restart variable returned a bad timestep"); + error->all(FLERR,"Restart variable returned a bad next timestep: {} vs {}", + nextrestart, ntimestep); next_restart_double = nextrestart; } } else next_restart_double = update->laststep + 1; @@ -401,7 +403,8 @@ void Output::write(bigint ntimestep) auto nextrestart = static_cast (input->variable->compute_equal(ivar_restart_single)); if (nextrestart <= ntimestep) - error->all(FLERR,"Restart variable returned a bad timestep"); + error->all(FLERR,"Restart variable returned a bad next timestep: {} vs {}", + nextrestart, ntimestep); next_restart_single = nextrestart; modify->addstep_compute(next_restart_single); } @@ -424,7 +427,8 @@ void Output::write(bigint ntimestep) auto nextrestart = static_cast (input->variable->compute_equal(ivar_restart_double)); if (nextrestart <= ntimestep) - error->all(FLERR,"Restart variable returned a bad timestep"); + error->all(FLERR,"Restart variable returned a bad next timestep: {} <= {}", + nextrestart, ntimestep); next_restart_double = nextrestart; modify->addstep_compute(next_restart_double); } @@ -647,7 +651,8 @@ void Output::reset_timestep(bigint ntimestep) auto nextrestart = static_cast (input->variable->compute_equal(ivar_restart_single)); if (nextrestart < ntimestep) - error->all(FLERR,"Restart variable returned a bad timestep"); + error->all(FLERR,"Restart variable returned a bad next timestep: {} <= {}", + nextrestart, ntimestep); update->ntimestep++; next_restart_single = nextrestart; modify->addstep_compute(next_restart_single); @@ -666,7 +671,8 @@ void Output::reset_timestep(bigint ntimestep) auto nextrestart = static_cast (input->variable->compute_equal(ivar_restart_double)); if (nextrestart < ntimestep) - error->all(FLERR,"Restart variable returned a bad timestep"); + error->all(FLERR,"Restart variable returned a bad next timestep: {} <= {}", + nextrestart, ntimestep); update->ntimestep++; next_restart_double = nextrestart; modify->addstep_compute(next_restart_double); From f9ee2ad42b991ed221da79f217e7f71d544427b0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 28 May 2023 11:49:02 -0400 Subject: [PATCH 267/448] reorder thermo and dump output so dump styles include correct thermo data --- src/output.cpp | 90 +++++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/output.cpp b/src/output.cpp index ed8fa48831..6e57122ffe 100644 --- a/src/output.cpp +++ b/src/output.cpp @@ -190,6 +190,32 @@ void Output::setup(int memflag) { bigint ntimestep = update->ntimestep; + // print memory usage unless being called between multiple runs + + if (memflag) memory_usage(); + + // set next_thermo to multiple of every or variable eval if var defined + // ensure thermo output on last step of run + // thermo may invoke computes so wrap with clear/add + + modify->clearstep_compute(); + + thermo->header(); + thermo->compute(0); + last_thermo = ntimestep; + + if (var_thermo) { + next_thermo = static_cast + (input->variable->compute_equal(ivar_thermo)); + if (next_thermo <= ntimestep) + error->all(FLERR,"Thermo every variable returned a bad timestep"); + } else if (thermo_every) { + next_thermo = (ntimestep/thermo_every)*thermo_every + thermo_every; + next_thermo = MIN(next_thermo,update->laststep); + } else next_thermo = update->laststep; + + modify->addstep_compute(next_thermo); + // consider all dumps // decide whether to write snapshot and/or calculate next step for dump @@ -257,7 +283,7 @@ void Output::setup(int memflag) next_dump_any = MIN(next_dump_any,next_dump[idump]); } - // if no dumps, set next_dump_any to last+1 so will not influence next + // if no dumps, set next_dump_any to last+1 so will not influence next } else next_dump_any = update->laststep + 1; @@ -298,32 +324,6 @@ void Output::setup(int memflag) next_restart = MIN(next_restart_single,next_restart_double); } else next_restart = update->laststep + 1; - // print memory usage unless being called between multiple runs - - if (memflag) memory_usage(); - - // set next_thermo to multiple of every or variable eval if var defined - // ensure thermo output on last step of run - // thermo may invoke computes so wrap with clear/add - - modify->clearstep_compute(); - - thermo->header(); - thermo->compute(0); - last_thermo = ntimestep; - - if (var_thermo) { - next_thermo = static_cast - (input->variable->compute_equal(ivar_thermo)); - if (next_thermo <= ntimestep) - error->all(FLERR,"Thermo every variable returned a bad timestep"); - } else if (thermo_every) { - next_thermo = (ntimestep/thermo_every)*thermo_every + thermo_every; - next_thermo = MIN(next_thermo,update->laststep); - } else next_thermo = update->laststep; - - modify->addstep_compute(next_thermo); - // next = next timestep any output will be done next = MIN(next_dump_any,next_restart); @@ -338,6 +338,24 @@ void Output::setup(int memflag) void Output::write(bigint ntimestep) { + // ensure next_thermo forces output on last step of run + // thermo may invoke computes so wrap with clear/add + + if (next_thermo == ntimestep) { + modify->clearstep_compute(); + if (last_thermo != ntimestep) thermo->compute(1); + last_thermo = ntimestep; + if (var_thermo) { + next_thermo = static_cast + (input->variable->compute_equal(ivar_thermo)); + if (next_thermo <= ntimestep) + error->all(FLERR,"Thermo every variable returned a bad timestep"); + } else if (thermo_every) next_thermo += thermo_every; + else next_thermo = update->laststep; + next_thermo = MIN(next_thermo,update->laststep); + modify->addstep_compute(next_thermo); + } + // perform dump if its next_dump = current ntimestep // but not if it was already written on this step // set next_dump and also next_time_dump for mode_dump = 1 @@ -437,24 +455,6 @@ void Output::write(bigint ntimestep) next_restart = MIN(next_restart_single,next_restart_double); } - // ensure next_thermo forces output on last step of run - // thermo may invoke computes so wrap with clear/add - - if (next_thermo == ntimestep) { - modify->clearstep_compute(); - if (last_thermo != ntimestep) thermo->compute(1); - last_thermo = ntimestep; - if (var_thermo) { - next_thermo = static_cast - (input->variable->compute_equal(ivar_thermo)); - if (next_thermo <= ntimestep) - error->all(FLERR,"Thermo every variable returned a bad timestep"); - } else if (thermo_every) next_thermo += thermo_every; - else next_thermo = update->laststep; - next_thermo = MIN(next_thermo,update->laststep); - modify->addstep_compute(next_thermo); - } - // next = next timestep any output will be done next = MIN(next_dump_any,next_restart); From c934208a4a462ec55c4a25cadd6b6d3adc307edc Mon Sep 17 00:00:00 2001 From: jrgissing Date: Sun, 28 May 2023 14:07:25 -0400 Subject: [PATCH 268/448] only update ivector if it still exists --- src/atom.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/atom.cpp b/src/atom.cpp index f30ace174e..d5f8b64a52 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2129,7 +2129,8 @@ void Atom::add_molecule_atom(Molecule *onemol, int iatom, int ilocal, tagint off // initialize custom per-atom properties to zero if present - for (int i = 0; i < nivector; ++i) ivector[i][ilocal] = 0; + for (int i = 0; i < nivector; ++i) + if (ivname[i] != nullptr) ivector[i][ilocal] = 0; for (int i = 0; i < ndvector; ++i) dvector[i][ilocal] = 0.0; for (int i = 0; i < niarray; ++i) for (int j = 0; j < icols[i]; ++j) From 86743bc0a6fa09ffd630d4d9220c76f60823d18d Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Mon, 29 May 2023 10:59:18 +0300 Subject: [PATCH 269/448] Update compute_stress_mop.cpp The angle was computed using the dot product of the vectors x[atom2] - x[atom1] and x[atom3] - x[atom2]. This is not consistent with the lammps convention where the angle is computed using the dot product between x[atom1]-x[atom2] and x[atom3]-x[atom2]. --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index e7a602e583..d512ce4810 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -692,7 +692,7 @@ void ComputeStressMop::compute_angles() // compute the cos(theta) of the angle r1 = sqrt(dx_left[0]*dx_left[0] + dx_left[1]*dx_left[1] + dx_left[2]*dx_left[2]); r2 = sqrt(dx_right[0]*dx_right[0] + dx_right[1]*dx_right[1] + dx_right[2]*dx_right[2]); - cos_theta = (dx_right[0]*dx_left[0] + dx_right[1]*dx_left[1] + dx_right[2]*dx_left[2])/(r1*r2); + cos_theta = -(dx_right[0]*dx_left[0] + dx_right[1]*dx_left[1] + dx_right[2]*dx_left[2])/(r1*r2); if (cos_theta > 1.0) cos_theta = 1.0; if (cos_theta < -1.0) cos_theta = -1.0; From 3b38145d91b130b72a6770992efa35b282f0cfee Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Mon, 29 May 2023 16:34:44 +0300 Subject: [PATCH 270/448] Update compute_stress_mop.cpp Fixing sign issues because I was considering the theta angle to be formed by vectors x[atom2] - x[atom1] & x[atom3] - x[atom2] instead of x[atom1] - x[atom2] & x[atom3] - x[atom2] as done in lammps --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index d512ce4810..a5f5969317 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -703,18 +703,18 @@ void ComputeStressMop::compute_angles() if (right_cross && !left_cross) { double sgn = copysign(1.0, x_angle_right[dir] - pos); - dcos_theta[0] = sgn*(dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; - dcos_theta[1] = sgn*(dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; - dcos_theta[2] = sgn*(dx_right[2]*cos_theta/r2 - dx_left[2]/r1)/r2; + dcos_theta[0] = sgn*(dx_right[0]*cos_theta/r2 + dx_left[0]/r1)/r2; + dcos_theta[1] = sgn*(dx_right[1]*cos_theta/r2 + dx_left[1]/r1)/r2; + dcos_theta[2] = sgn*(dx_right[2]*cos_theta/r2 + dx_left[2]/r1)/r2; } // only left bond crossing the plane if (!right_cross && left_cross) { double sgn = copysign(1.0, x_angle_left[dir] - pos); - dcos_theta[0] = -sgn*(dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; - dcos_theta[1] = -sgn*(dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; - dcos_theta[2] = -sgn*(dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; + dcos_theta[0] = -sgn*(dx_left[0]*cos_theta/r1 + dx_right[0]/r2)/r1; + dcos_theta[1] = -sgn*(dx_left[1]*cos_theta/r1 + dx_right[1]/r2)/r1; + dcos_theta[2] = -sgn*(dx_left[2]*cos_theta/r1 + dx_right[2]/r2)/r1; } // both bonds crossing the plane @@ -722,14 +722,14 @@ void ComputeStressMop::compute_angles() { // due to right bond double sgn = copysign(1.0, x_angle_middle[dir] - pos); - dcos_theta[0] = -sgn*(dx_right[0]*cos_theta/r2 - dx_left[0]/r1)/r2; - dcos_theta[1] = -sgn*(dx_right[1]*cos_theta/r2 - dx_left[1]/r1)/r2; - dcos_theta[2] = -sgn*(dx_right[2]*cos_theta/r2 - dx_left[2]/r1)/r2; + dcos_theta[0] = -sgn*(dx_right[0]*cos_theta/r2 + dx_left[0]/r1)/r2; + dcos_theta[1] = -sgn*(dx_right[1]*cos_theta/r2 + dx_left[1]/r1)/r2; + dcos_theta[2] = -sgn*(dx_right[2]*cos_theta/r2 + dx_left[2]/r1)/r2; // due to left bond - dcos_theta[0] += sgn*(dx_left[0]*cos_theta/r1 - dx_right[0]/r2)/r1; - dcos_theta[1] += sgn*(dx_left[1]*cos_theta/r1 - dx_right[1]/r2)/r1; - dcos_theta[2] += sgn*(dx_left[2]*cos_theta/r1 - dx_right[2]/r2)/r1; + dcos_theta[0] += sgn*(dx_left[0]*cos_theta/r1 + dx_right[0]/r2)/r1; + dcos_theta[1] += sgn*(dx_left[1]*cos_theta/r1 + dx_right[1]/r2)/r1; + dcos_theta[2] += sgn*(dx_left[2]*cos_theta/r1 + dx_right[2]/r2)/r1; } // final contribution of the given angle term From b3e9efcb50ded57acff46cc52305c59a0adb04a8 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Mon, 29 May 2023 17:55:24 +0300 Subject: [PATCH 271/448] Use system periodicity to find an equivalent position of the plane --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index a5f5969317..9249e4ce2d 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -74,6 +74,18 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : pos = 0.5*(domain->boxlo[dir]+domain->boxhi[dir]); } else pos = utils::numeric(FLERR,arg[4],false,lmp); + // plane inside the box + if (pos >domain->boxhi[dir] || pos boxlo[dir]) { + error->warning(FLERR,"The specified initial plane lies outside of the simulation box"); + double dx[3] {0}; + dx[dir] = pos - 0.5*(domain->boxhi[dir] + domain->boxlo[dir]); + domain->minimum_image(dx[0], dx[1], dx[2]); + pos = 0.5*(domain->boxhi[dir] + domain->boxlo[dir]) + dx[dir]; + + if (pos >domain->boxhi[dir] || pos boxlo[dir]) + error->all(FLERR, "Plane for compute stress/mop is out of bounds"); + } + if (pos < (domain->boxlo[dir]+domain->prd_half[dir])) { pos1 = pos + domain->prd[dir]; } else { @@ -117,10 +129,6 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : // orthogonal simulation box if (domain->triclinic != 0) error->all(FLERR, "Compute stress/mop incompatible with triclinic simulation box"); - // plane inside the box - if (pos >domain->boxhi[dir] || pos boxlo[dir]) - error->all(FLERR, "Plane for compute stress/mop is out of bounds"); - // Initialize some variables From da7a348089222a8d8ff11b246fa8c0ec605ddadd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 May 2023 14:24:32 -0400 Subject: [PATCH 272/448] simplify and shorten example, use symlinks, recreate logs --- .../C_SNAP_2021.10.15.quadratic.snapcoeff | 1603 +---------------- .../C_SNAP_2021.10.15.quadratic.snapparam | 11 +- examples/snap/in.C_SNAP | 32 +- examples/snap/log.23May23.C_SNAP | 136 -- examples/snap/log.30May23.C_SNAP.g++.1 | 105 ++ examples/snap/log.30May23.C_SNAP.g++.4 | 105 ++ examples/snap/pot_C.mod | 12 - 7 files changed, 226 insertions(+), 1778 deletions(-) mode change 100644 => 120000 examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff mode change 100644 => 120000 examples/snap/C_SNAP_2021.10.15.quadratic.snapparam delete mode 100644 examples/snap/log.23May23.C_SNAP create mode 100644 examples/snap/log.30May23.C_SNAP.g++.1 create mode 100644 examples/snap/log.30May23.C_SNAP.g++.4 delete mode 100644 examples/snap/pot_C.mod diff --git a/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff b/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff deleted file mode 100644 index 4db83060f7..0000000000 --- a/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff +++ /dev/null @@ -1,1602 +0,0 @@ -#Carbon SNAP generated on 2021-10-15 08:21:38.396384 -#UNITS: metal CONTRIBUTOR: Ivan Oleynik CITATION: Jonathan T. Willman, Kien Nguyen-Cong, Ashley S. Williams, Anatoly B. Belonoshko, Stan G. Moore, Aidan P. Thompson, Mitchell A. Wood, and Ivan I. Oleynik, "Machine learning interatomic potential for simulations of carbon at extreme conditions" Phys. Rev. B 106, L180101 (2022) -1 1596 -C 0.5 1.0 - -2.7758927591660334 # B[0] - 0.00859216942217639126 # B[1, 0, 0, 0] - 0.16638458601459194 # B[2, 1, 0, 1] - 0.22261822339506554 # B[3, 1, 1, 2] - 0.257355166247009937 # B[4, 2, 0, 2] - 0.802105904460230779 # B[5, 2, 1, 3] - 0.227216469467176801 # B[6, 2, 2, 2] - 0.494646284119575508 # B[7, 2, 2, 4] - 0.276718638025069574 # B[8, 3, 0, 3] - 1.09101782892605392 # B[9, 3, 1, 4] - 0.775283725099378151 # B[10, 3, 2, 3] - -0.232869556477520168 # B[11, 3, 2, 5] - 0.188466708736270222 # B[12, 3, 3, 4] - -0.213463540195325957 # B[13, 3, 3, 6] - 0.285049005401720568 # B[14, 4, 0, 4] - -0.248039138369940321 # B[15, 4, 1, 5] - -0.017694405190132434 # B[16, 4, 2, 4] - -0.513770238875468355 # B[17, 4, 2, 6] - -0.603368424950793791 # B[18, 4, 3, 5] - -0.4245149972360448 # B[19, 4, 3, 7] - -0.149612637312833391 # B[20, 4, 4, 4] - -0.153415086019898006 # B[21, 4, 4, 6] - -0.14513624400298164 # B[22, 4, 4, 8] - -0.0460661393681677661 # B[23, 5, 0, 5] - -0.0512559726916635844 # B[24, 5, 1, 6] - -0.125285455697324882 # B[25, 5, 2, 5] - -0.297464016341802473 # B[26, 5, 2, 7] - -0.219930176940332595 # B[27, 5, 3, 6] - -0.195418601625407001 # B[28, 5, 3, 8] - -0.236454956825408069 # B[29, 5, 4, 5] - -0.247483318285177556 # B[30, 5, 4, 7] - 0.108404148378543994 # B[31, 5, 5, 6] - 0.102786344334006338 # B[32, 5, 5, 8] - -0.0174963987262215619 # B[33, 6, 0, 6] - -0.347663919737827065 # B[34, 6, 1, 7] - -0.308777238806140442 # B[35, 6, 2, 6] - -0.30366671620990171 # B[36, 6, 2, 8] - -0.190992135157848048 # B[37, 6, 3, 7] - -0.212717125362634818 # B[38, 6, 4, 6] - -0.127682310305149815 # B[39, 6, 4, 8] - 0.128955786755968027 # B[40, 6, 5, 7] - 0.108121871413745185 # B[41, 6, 6, 6] - 0.0951564970231452284 # B[42, 6, 6, 8] - -0.0443430969083889667 # B[43, 7, 0, 7] - 0.0394012265947801602 # B[44, 7, 1, 8] - 0.0238287662182333909 # B[45, 7, 2, 7] - -0.0703216614205220136 # B[46, 7, 3, 8] - -0.0229748587995626564 # B[47, 7, 4, 7] - 0.461615758896215367 # B[48, 7, 5, 8] - 0.032037855993324961 # B[49, 7, 6, 7] - 0.105399776101016598 # B[50, 7, 7, 8] - -0.0452778356788145764 # B[51, 8, 0, 8] - -0.0400452652333231421 # B[52, 8, 2, 8] - -0.152415456089667084 # B[53, 8, 4, 8] - 0.0303383368396002995 # B[54, 8, 6, 8] - 0.0660845112300222914 # B[55, 8, 8, 8] - 5.0022584003536763e-06 # B[55, [1, 0, 0, 0], [1, 0, 0, 0]] - 7.12434860521689133e-05 # B[56, [1, 0, 0, 0], [2, 1, 0, 1]] - 0.00410559459459784552 # B[57, [1, 0, 0, 0], [3, 1, 1, 2]] - -0.000152151102822628559 # B[58, [1, 0, 0, 0], [4, 2, 0, 2]] - -0.00104851962847402839 # B[59, [1, 0, 0, 0], [5, 2, 1, 3]] - 0.00174544590749468355 # B[60, [1, 0, 0, 0], [6, 2, 2, 2]] - -0.00039686396723943862 # B[61, [1, 0, 0, 0], [7, 2, 2, 4]] - 0.000344474173032960351 # B[62, [1, 0, 0, 0], [8, 3, 0, 3]] - 5.77832175303926235e-05 # B[63, [1, 0, 0, 0], [9, 3, 1, 4]] - 0.00124014860085090543 # B[64, [1, 0, 0, 0], [10, 3, 2, 3]] - 1.92520730655986946e-05 # B[65, [1, 0, 0, 0], [11, 3, 2, 5]] - -0.000659022869027497959 # B[66, [1, 0, 0, 0], [12, 3, 3, 4]] - -0.000296998157394604001 # B[67, [1, 0, 0, 0], [13, 3, 3, 6]] - 2.13348987737616014e-06 # B[68, [1, 0, 0, 0], [14, 4, 0, 4]] - -0.000377679899824956422 # B[69, [1, 0, 0, 0], [15, 4, 1, 5]] - 0.00045743496488695988 # B[70, [1, 0, 0, 0], [16, 4, 2, 4]] - -0.00047978616167941926 # B[71, [1, 0, 0, 0], [17, 4, 2, 6]] - -0.000346601408372410741 # B[72, [1, 0, 0, 0], [18, 4, 3, 5]] - -0.000216752459512900564 # B[73, [1, 0, 0, 0], [19, 4, 3, 7]] - -0.000153945954064437646 # B[74, [1, 0, 0, 0], [20, 4, 4, 4]] - 0.00029484781857681483 # B[75, [1, 0, 0, 0], [21, 4, 4, 6]] - 1.59236973873017051e-05 # B[76, [1, 0, 0, 0], [22, 4, 4, 8]] - -2.35544935613951623e-05 # B[77, [1, 0, 0, 0], [23, 5, 0, 5]] - 0.000492019807872501325 # B[78, [1, 0, 0, 0], [24, 5, 1, 6]] - 0.000376700986017126233 # B[79, [1, 0, 0, 0], [25, 5, 2, 5]] - -0.000185900021989794662 # B[80, [1, 0, 0, 0], [26, 5, 2, 7]] - 0.000219939447169378507 # B[81, [1, 0, 0, 0], [27, 5, 3, 6]] - -0.000192198129806066265 # B[82, [1, 0, 0, 0], [28, 5, 3, 8]] - 0.000175514531344928004 # B[83, [1, 0, 0, 0], [29, 5, 4, 5]] - 0.000261949015135925535 # B[84, [1, 0, 0, 0], [30, 5, 4, 7]] - 0.00021011408484750832 # B[85, [1, 0, 0, 0], [31, 5, 5, 6]] - -7.47807464450689352e-05 # B[86, [1, 0, 0, 0], [32, 5, 5, 8]] - -1.36809205491805752e-05 # B[87, [1, 0, 0, 0], [33, 6, 0, 6]] - 0.000493576806965066728 # B[88, [1, 0, 0, 0], [34, 6, 1, 7]] - 0.000216301405824667614 # B[89, [1, 0, 0, 0], [35, 6, 2, 6]] - -0.000364540437645548276 # B[90, [1, 0, 0, 0], [36, 6, 2, 8]] - -0.000251411532179113273 # B[91, [1, 0, 0, 0], [37, 6, 3, 7]] - 3.19331690196988927e-05 # B[92, [1, 0, 0, 0], [38, 6, 4, 6]] - -1.56092571080845843e-05 # B[93, [1, 0, 0, 0], [39, 6, 4, 8]] - 2.4859429830464963e-05 # B[94, [1, 0, 0, 0], [40, 6, 5, 7]] - -5.06306418207175257e-05 # B[95, [1, 0, 0, 0], [41, 6, 6, 6]] - -9.75742047871729079e-05 # B[96, [1, 0, 0, 0], [42, 6, 6, 8]] - -4.07774117821002591e-05 # B[97, [1, 0, 0, 0], [43, 7, 0, 7]] - 0.000169705539551909257 # B[98, [1, 0, 0, 0], [44, 7, 1, 8]] - 0.000261792097012429614 # B[99, [1, 0, 0, 0], [45, 7, 2, 7]] - 0.000235813389494382575 # B[100, [1, 0, 0, 0], [46, 7, 3, 8]] - 3.69194385055615637e-05 # B[101, [1, 0, 0, 0], [47, 7, 4, 7]] - 0.000101832840349036502 # B[102, [1, 0, 0, 0], [48, 7, 5, 8]] - 1.87768621704026417e-05 # B[103, [1, 0, 0, 0], [49, 7, 6, 7]] - 6.90123641682582889e-05 # B[104, [1, 0, 0, 0], [50, 7, 7, 8]] - 3.82281861928956967e-05 # B[105, [1, 0, 0, 0], [51, 8, 0, 8]] - 0.00044905358698343889 # B[106, [1, 0, 0, 0], [52, 8, 2, 8]] - 3.83170337754923374e-05 # B[107, [1, 0, 0, 0], [53, 8, 4, 8]] - -4.53472261485315942e-05 # B[108, [1, 0, 0, 0], [54, 8, 6, 8]] - -0.000105793544360549552 # B[109, [1, 0, 0, 0], [55, 8, 8, 8]] - -0.00542851209933992596 # B[110, [2, 1, 0, 1], [2, 1, 0, 1]] - -0.00800035055604917701 # B[111, [2, 1, 0, 1], [3, 1, 1, 2]] - 0.000279580761847972054 # B[112, [2, 1, 0, 1], [4, 2, 0, 2]] - -0.0132643544617690821 # B[113, [2, 1, 0, 1], [5, 2, 1, 3]] - -0.00300637860380324968 # B[114, [2, 1, 0, 1], [6, 2, 2, 2]] - 0.00343216933390476549 # B[115, [2, 1, 0, 1], [7, 2, 2, 4]] - 6.39026040622058672e-05 # B[116, [2, 1, 0, 1], [8, 3, 0, 3]] - -0.0124005148347727506 # B[117, [2, 1, 0, 1], [9, 3, 1, 4]] - -0.0036690465725984691 # B[118, [2, 1, 0, 1], [10, 3, 2, 3]] - -0.0066468850826254932 # B[119, [2, 1, 0, 1], [11, 3, 2, 5]] - -0.00518212543330048934 # B[120, [2, 1, 0, 1], [12, 3, 3, 4]] - -0.00269613907034030407 # B[121, [2, 1, 0, 1], [13, 3, 3, 6]] - -0.000330193583102013615 # B[122, [2, 1, 0, 1], [14, 4, 0, 4]] - -0.000429062486184235686 # B[123, [2, 1, 0, 1], [15, 4, 1, 5]] - -0.000991704717453613382 # B[124, [2, 1, 0, 1], [16, 4, 2, 4]] - 0.00152944521177345071 # B[125, [2, 1, 0, 1], [17, 4, 2, 6]] - -0.00660856033628089406 # B[126, [2, 1, 0, 1], [18, 4, 3, 5]] - 0.00146758746394204951 # B[127, [2, 1, 0, 1], [19, 4, 3, 7]] - -0.00161093753941019967 # B[128, [2, 1, 0, 1], [20, 4, 4, 4]] - -0.00101484284665418574 # B[129, [2, 1, 0, 1], [21, 4, 4, 6]] - 0.00150269420364470413 # B[130, [2, 1, 0, 1], [22, 4, 4, 8]] - -0.000251279508914979688 # B[131, [2, 1, 0, 1], [23, 5, 0, 5]] - 0.00427791921512100763 # B[132, [2, 1, 0, 1], [24, 5, 1, 6]] - -0.00312327633171666707 # B[133, [2, 1, 0, 1], [25, 5, 2, 5]] - 0.00145518956483171066 # B[134, [2, 1, 0, 1], [26, 5, 2, 7]] - -0.00296392629706135422 # B[135, [2, 1, 0, 1], [27, 5, 3, 6]] - 0.00106990236696331148 # B[136, [2, 1, 0, 1], [28, 5, 3, 8]] - 0.000140740776400729824 # B[137, [2, 1, 0, 1], [29, 5, 4, 5]] - -0.000704484148092703912 # B[138, [2, 1, 0, 1], [30, 5, 4, 7]] - 0.000555926138942124939 # B[139, [2, 1, 0, 1], [31, 5, 5, 6]] - 0.000749361142656781065 # B[140, [2, 1, 0, 1], [32, 5, 5, 8]] - -0.000275563231062828096 # B[141, [2, 1, 0, 1], [33, 6, 0, 6]] - 0.00404287546990938183 # B[142, [2, 1, 0, 1], [34, 6, 1, 7]] - -0.00329083016295819491 # B[143, [2, 1, 0, 1], [35, 6, 2, 6]] - 0.00374648670440783874 # B[144, [2, 1, 0, 1], [36, 6, 2, 8]] - -0.000931584323738718183 # B[145, [2, 1, 0, 1], [37, 6, 3, 7]] - 0.001545987588966576 # B[146, [2, 1, 0, 1], [38, 6, 4, 6]] - 0.000136630337825366203 # B[147, [2, 1, 0, 1], [39, 6, 4, 8]] - -0.000338191518470186761 # B[148, [2, 1, 0, 1], [40, 6, 5, 7]] - 0.000383732900037425575 # B[149, [2, 1, 0, 1], [41, 6, 6, 6]] - 0.000891911333988446714 # B[150, [2, 1, 0, 1], [42, 6, 6, 8]] - 0.000372325777048820861 # B[151, [2, 1, 0, 1], [43, 7, 0, 7]] - 0.00203975899324063559 # B[152, [2, 1, 0, 1], [44, 7, 1, 8]] - -0.00366168906366426058 # B[153, [2, 1, 0, 1], [45, 7, 2, 7]] - -0.00217927110231279971 # B[154, [2, 1, 0, 1], [46, 7, 3, 8]] - -0.000355180731966526532 # B[155, [2, 1, 0, 1], [47, 7, 4, 7]] - -0.00190295940654904624 # B[156, [2, 1, 0, 1], [48, 7, 5, 8]] - -0.00045640385432905474 # B[157, [2, 1, 0, 1], [49, 7, 6, 7]] - -0.00123273230096131864 # B[158, [2, 1, 0, 1], [50, 7, 7, 8]] - 2.61749541232737803e-06 # B[159, [2, 1, 0, 1], [51, 8, 0, 8]] - -0.00188736987570012403 # B[160, [2, 1, 0, 1], [52, 8, 2, 8]] - 0.000127235145614493401 # B[161, [2, 1, 0, 1], [53, 8, 4, 8]] - -0.000446185446234578786 # B[162, [2, 1, 0, 1], [54, 8, 6, 8]] - 3.06626149019382718e-05 # B[163, [2, 1, 0, 1], [55, 8, 8, 8]] - 0.00500803145405033512 # B[164, [3, 1, 1, 2], [3, 1, 1, 2]] - 0.0136537265129433767 # B[165, [3, 1, 1, 2], [4, 2, 0, 2]] - 0.00586793418015095231 # B[166, [3, 1, 1, 2], [5, 2, 1, 3]] - 0.0108897828563872673 # B[167, [3, 1, 1, 2], [6, 2, 2, 2]] - 0.000782326392446437181 # B[168, [3, 1, 1, 2], [7, 2, 2, 4]] - -0.00196905235294965193 # B[169, [3, 1, 1, 2], [8, 3, 0, 3]] - -0.00575620599927615263 # B[170, [3, 1, 1, 2], [9, 3, 1, 4]] - -0.0395084171352078836 # B[171, [3, 1, 1, 2], [10, 3, 2, 3]] - -0.0402914809330097226 # B[172, [3, 1, 1, 2], [11, 3, 2, 5]] - -0.031380925125560552 # B[173, [3, 1, 1, 2], [12, 3, 3, 4]] - 0.0074098991236085333 # B[174, [3, 1, 1, 2], [13, 3, 3, 6]] - -0.00144234945688183152 # B[175, [3, 1, 1, 2], [14, 4, 0, 4]] - -0.00715563010950572616 # B[176, [3, 1, 1, 2], [15, 4, 1, 5]] - -0.0068004389765142035 # B[177, [3, 1, 1, 2], [16, 4, 2, 4]] - -0.0397838555572563451 # B[178, [3, 1, 1, 2], [17, 4, 2, 6]] - 0.00335672059516798228 # B[179, [3, 1, 1, 2], [18, 4, 3, 5]] - 0.0148934683418572647 # B[180, [3, 1, 1, 2], [19, 4, 3, 7]] - -0.000967980016249102011 # B[181, [3, 1, 1, 2], [20, 4, 4, 4]] - 0.00772576295059950596 # B[182, [3, 1, 1, 2], [21, 4, 4, 6]] - -0.00450662666899595381 # B[183, [3, 1, 1, 2], [22, 4, 4, 8]] - -0.00395807515027411967 # B[184, [3, 1, 1, 2], [23, 5, 0, 5]] - 0.010414612350238486 # B[185, [3, 1, 1, 2], [24, 5, 1, 6]] - -0.00513372683983254804 # B[186, [3, 1, 1, 2], [25, 5, 2, 5]] - -0.0265398819124704963 # B[187, [3, 1, 1, 2], [26, 5, 2, 7]] - 0.00742434172938952544 # B[188, [3, 1, 1, 2], [27, 5, 3, 6]] - -0.00256386423704287481 # B[189, [3, 1, 1, 2], [28, 5, 3, 8]] - 0.00841179553194743718 # B[190, [3, 1, 1, 2], [29, 5, 4, 5]] - 0.00668617729586690451 # B[191, [3, 1, 1, 2], [30, 5, 4, 7]] - 0.000484464094046739568 # B[192, [3, 1, 1, 2], [31, 5, 5, 6]] - 0.00458460314168420216 # B[193, [3, 1, 1, 2], [32, 5, 5, 8]] - -0.00235318401641824212 # B[194, [3, 1, 1, 2], [33, 6, 0, 6]] - -0.000804392064641467762 # B[195, [3, 1, 1, 2], [34, 6, 1, 7]] - -0.000974349018272668323 # B[196, [3, 1, 1, 2], [35, 6, 2, 6]] - -0.0186467861443154748 # B[197, [3, 1, 1, 2], [36, 6, 2, 8]] - 0.0149394908128317495 # B[198, [3, 1, 1, 2], [37, 6, 3, 7]] - -0.001417773975968062 # B[199, [3, 1, 1, 2], [38, 6, 4, 6]] - 0.00708801668305296916 # B[200, [3, 1, 1, 2], [39, 6, 4, 8]] - 0.00422029817457212405 # B[201, [3, 1, 1, 2], [40, 6, 5, 7]] - 0.00110117813016081525 # B[202, [3, 1, 1, 2], [41, 6, 6, 6]] - -0.00187490884044745794 # B[203, [3, 1, 1, 2], [42, 6, 6, 8]] - -0.00530063898164105998 # B[204, [3, 1, 1, 2], [43, 7, 0, 7]] - 0.0156639815207892212 # B[205, [3, 1, 1, 2], [44, 7, 1, 8]] - 0.0118519420103458811 # B[206, [3, 1, 1, 2], [45, 7, 2, 7]] - 0.00375057568532275679 # B[207, [3, 1, 1, 2], [46, 7, 3, 8]] - 0.00757584350406629962 # B[208, [3, 1, 1, 2], [47, 7, 4, 7]] - 0.0106601777099339986 # B[209, [3, 1, 1, 2], [48, 7, 5, 8]] - -0.0041075690062942552 # B[210, [3, 1, 1, 2], [49, 7, 6, 7]] - 0.00248707997936048041 # B[211, [3, 1, 1, 2], [50, 7, 7, 8]] - -0.0025390217113529746 # B[212, [3, 1, 1, 2], [51, 8, 0, 8]] - 0.00498354453902482165 # B[213, [3, 1, 1, 2], [52, 8, 2, 8]] - 0.00383782774054214912 # B[214, [3, 1, 1, 2], [53, 8, 4, 8]] - 0.00318870204625110783 # B[215, [3, 1, 1, 2], [54, 8, 6, 8]] - -0.00078409267383599678 # B[216, [3, 1, 1, 2], [55, 8, 8, 8]] - 0.00411479420703600093 # B[217, [4, 2, 0, 2], [4, 2, 0, 2]] - -0.00352482696278418658 # B[218, [4, 2, 0, 2], [5, 2, 1, 3]] - 0.00293296373222708129 # B[219, [4, 2, 0, 2], [6, 2, 2, 2]] - -0.00169108240942662173 # B[220, [4, 2, 0, 2], [7, 2, 2, 4]] - -0.00166875839344953099 # B[221, [4, 2, 0, 2], [8, 3, 0, 3]] - -0.00303743189373234653 # B[222, [4, 2, 0, 2], [9, 3, 1, 4]] - -0.00360352002032471395 # B[223, [4, 2, 0, 2], [10, 3, 2, 3]] - -0.00844475258400314774 # B[224, [4, 2, 0, 2], [11, 3, 2, 5]] - -0.00267861760564082688 # B[225, [4, 2, 0, 2], [12, 3, 3, 4]] - 0.00249373694942188646 # B[226, [4, 2, 0, 2], [13, 3, 3, 6]] - 0.00129518789575956 # B[227, [4, 2, 0, 2], [14, 4, 0, 4]] - -0.000616706097657935626 # B[228, [4, 2, 0, 2], [15, 4, 1, 5]] - -0.00374793183827557257 # B[229, [4, 2, 0, 2], [16, 4, 2, 4]] - -0.00725453590077526286 # B[230, [4, 2, 0, 2], [17, 4, 2, 6]] - -0.00328165463874066426 # B[231, [4, 2, 0, 2], [18, 4, 3, 5]] - -0.00387910875571249565 # B[232, [4, 2, 0, 2], [19, 4, 3, 7]] - -0.000691443248665482221 # B[233, [4, 2, 0, 2], [20, 4, 4, 4]] - -0.00364575524119575139 # B[234, [4, 2, 0, 2], [21, 4, 4, 6]] - 0.000579213613942424974 # B[235, [4, 2, 0, 2], [22, 4, 4, 8]] - 0.000382530088889220486 # B[236, [4, 2, 0, 2], [23, 5, 0, 5]] - 0.000700082663528700608 # B[237, [4, 2, 0, 2], [24, 5, 1, 6]] - -0.00303645662419470708 # B[238, [4, 2, 0, 2], [25, 5, 2, 5]] - -0.00412449214914962191 # B[239, [4, 2, 0, 2], [26, 5, 2, 7]] - -0.000863747946010486305 # B[240, [4, 2, 0, 2], [27, 5, 3, 6]] - 0.000597171151136822748 # B[241, [4, 2, 0, 2], [28, 5, 3, 8]] - -0.00290482182317059953 # B[242, [4, 2, 0, 2], [29, 5, 4, 5]] - -0.00218615594313117554 # B[243, [4, 2, 0, 2], [30, 5, 4, 7]] - 0.00120270898159113111 # B[244, [4, 2, 0, 2], [31, 5, 5, 6]] - -0.000439562436330729364 # B[245, [4, 2, 0, 2], [32, 5, 5, 8]] - -0.000155002689849706443 # B[246, [4, 2, 0, 2], [33, 6, 0, 6]] - -0.00203784613220199399 # B[247, [4, 2, 0, 2], [34, 6, 1, 7]] - -0.00251933129878168221 # B[248, [4, 2, 0, 2], [35, 6, 2, 6]] - -0.00227857345941180406 # B[249, [4, 2, 0, 2], [36, 6, 2, 8]] - 0.00307391827986236085 # B[250, [4, 2, 0, 2], [37, 6, 3, 7]] - -0.000435707916552085118 # B[251, [4, 2, 0, 2], [38, 6, 4, 6]] - -0.00141960729594133419 # B[252, [4, 2, 0, 2], [39, 6, 4, 8]] - -0.000275734648504752638 # B[253, [4, 2, 0, 2], [40, 6, 5, 7]] - 0.000703286595409794617 # B[254, [4, 2, 0, 2], [41, 6, 6, 6]] - -5.55751922647368824e-05 # B[255, [4, 2, 0, 2], [42, 6, 6, 8]] - -0.000401816924228297345 # B[256, [4, 2, 0, 2], [43, 7, 0, 7]] - -0.000554714661495172429 # B[257, [4, 2, 0, 2], [44, 7, 1, 8]] - 0.00088244559527147267 # B[258, [4, 2, 0, 2], [45, 7, 2, 7]] - 0.000429487284537406104 # B[259, [4, 2, 0, 2], [46, 7, 3, 8]] - 0.000160720016534536374 # B[260, [4, 2, 0, 2], [47, 7, 4, 7]] - -0.000116046064898544729 # B[261, [4, 2, 0, 2], [48, 7, 5, 8]] - 0.00077812424584384446 # B[262, [4, 2, 0, 2], [49, 7, 6, 7]] - 0.0014223009786123353 # B[263, [4, 2, 0, 2], [50, 7, 7, 8]] - 5.45987148103492526e-05 # B[264, [4, 2, 0, 2], [51, 8, 0, 8]] - -0.00229888217343966316 # B[265, [4, 2, 0, 2], [52, 8, 2, 8]] - -0.00144376280980788169 # B[266, [4, 2, 0, 2], [53, 8, 4, 8]] - 0.000240138800657541986 # B[267, [4, 2, 0, 2], [54, 8, 6, 8]] - -4.09764373741731969e-05 # B[268, [4, 2, 0, 2], [55, 8, 8, 8]] - 0.0453826120189535706 # B[269, [5, 2, 1, 3], [5, 2, 1, 3]] - 0.00337080799390409615 # B[270, [5, 2, 1, 3], [6, 2, 2, 2]] - 0.0339316309546992961 # B[271, [5, 2, 1, 3], [7, 2, 2, 4]] - 0.00483677443671226039 # B[272, [5, 2, 1, 3], [8, 3, 0, 3]] - 0.00174954019608989774 # B[273, [5, 2, 1, 3], [9, 3, 1, 4]] - 0.00420306320210527603 # B[274, [5, 2, 1, 3], [10, 3, 2, 3]] - -0.0179939258962366969 # B[275, [5, 2, 1, 3], [11, 3, 2, 5]] - -0.01997198698308544 # B[276, [5, 2, 1, 3], [12, 3, 3, 4]] - -0.0136471344704570501 # B[277, [5, 2, 1, 3], [13, 3, 3, 6]] - -0.00203572867299816902 # B[278, [5, 2, 1, 3], [14, 4, 0, 4]] - 0.0113893698593142377 # B[279, [5, 2, 1, 3], [15, 4, 1, 5]] - -0.00283495847488346529 # B[280, [5, 2, 1, 3], [16, 4, 2, 4]] - -0.0209899506178404249 # B[281, [5, 2, 1, 3], [17, 4, 2, 6]] - 0.00307893999573658839 # B[282, [5, 2, 1, 3], [18, 4, 3, 5]] - 0.00625880909518397067 # B[283, [5, 2, 1, 3], [19, 4, 3, 7]] - 0.00109461945578659598 # B[284, [5, 2, 1, 3], [20, 4, 4, 4]] - 0.00213752786441095705 # B[285, [5, 2, 1, 3], [21, 4, 4, 6]] - -0.00379774849562602296 # B[286, [5, 2, 1, 3], [22, 4, 4, 8]] - -0.0013508169978871552 # B[287, [5, 2, 1, 3], [23, 5, 0, 5]] - 0.00921730935112183292 # B[288, [5, 2, 1, 3], [24, 5, 1, 6]] - -0.0029427132897584694 # B[289, [5, 2, 1, 3], [25, 5, 2, 5]] - 0.0013497580216050211 # B[290, [5, 2, 1, 3], [26, 5, 2, 7]] - -0.0130362734683665445 # B[291, [5, 2, 1, 3], [27, 5, 3, 6]] - 0.000858369129835153365 # B[292, [5, 2, 1, 3], [28, 5, 3, 8]] - 0.0129288669947052737 # B[293, [5, 2, 1, 3], [29, 5, 4, 5]] - -0.00373719468786774291 # B[294, [5, 2, 1, 3], [30, 5, 4, 7]] - -0.00885030928727506203 # B[295, [5, 2, 1, 3], [31, 5, 5, 6]] - 0.00285083482960970039 # B[296, [5, 2, 1, 3], [32, 5, 5, 8]] - 0.00351819863542377799 # B[297, [5, 2, 1, 3], [33, 6, 0, 6]] - -0.00783526064954031404 # B[298, [5, 2, 1, 3], [34, 6, 1, 7]] - -0.00257460837433342703 # B[299, [5, 2, 1, 3], [35, 6, 2, 6]] - -0.00421680657028429638 # B[300, [5, 2, 1, 3], [36, 6, 2, 8]] - -0.00918753516813325399 # B[301, [5, 2, 1, 3], [37, 6, 3, 7]] - -0.00316878171100497871 # B[302, [5, 2, 1, 3], [38, 6, 4, 6]] - 0.000939804682159322766 # B[303, [5, 2, 1, 3], [39, 6, 4, 8]] - -0.00618801787900946643 # B[304, [5, 2, 1, 3], [40, 6, 5, 7]] - -0.00623545765495540482 # B[305, [5, 2, 1, 3], [41, 6, 6, 6]] - 0.00519552954815065936 # B[306, [5, 2, 1, 3], [42, 6, 6, 8]] - 0.0042213652228506697 # B[307, [5, 2, 1, 3], [43, 7, 0, 7]] - 0.0113944611011103838 # B[308, [5, 2, 1, 3], [44, 7, 1, 8]] - -0.00104197865751114085 # B[309, [5, 2, 1, 3], [45, 7, 2, 7]] - -0.0087446191630695079 # B[310, [5, 2, 1, 3], [46, 7, 3, 8]] - -0.00196327596558909696 # B[311, [5, 2, 1, 3], [47, 7, 4, 7]] - -0.00447686867642808298 # B[312, [5, 2, 1, 3], [48, 7, 5, 8]] - -0.00474469665733750351 # B[313, [5, 2, 1, 3], [49, 7, 6, 7]] - -0.0059004868061462868 # B[314, [5, 2, 1, 3], [50, 7, 7, 8]] - 2.22874717926892923e-05 # B[315, [5, 2, 1, 3], [51, 8, 0, 8]] - -0.00154741089157206784 # B[316, [5, 2, 1, 3], [52, 8, 2, 8]] - 0.00417852330669051582 # B[317, [5, 2, 1, 3], [53, 8, 4, 8]] - 0.00134060860138395356 # B[318, [5, 2, 1, 3], [54, 8, 6, 8]] - -4.29219459423162489e-05 # B[319, [5, 2, 1, 3], [55, 8, 8, 8]] - 0.000319124100064731785 # B[320, [6, 2, 2, 2], [6, 2, 2, 2]] - -0.00839561599135440172 # B[321, [6, 2, 2, 2], [7, 2, 2, 4]] - -0.00326195850510992494 # B[322, [6, 2, 2, 2], [8, 3, 0, 3]] - 0.0194547426296311776 # B[323, [6, 2, 2, 2], [9, 3, 1, 4]] - -0.020516093722439413 # B[324, [6, 2, 2, 2], [10, 3, 2, 3]] - -0.00901624473884381043 # B[325, [6, 2, 2, 2], [11, 3, 2, 5]] - 0.0129026669830971837 # B[326, [6, 2, 2, 2], [12, 3, 3, 4]] - 0.00463182910296210636 # B[327, [6, 2, 2, 2], [13, 3, 3, 6]] - -0.00261498466108737743 # B[328, [6, 2, 2, 2], [14, 4, 0, 4]] - 0.0215819608660451426 # B[329, [6, 2, 2, 2], [15, 4, 1, 5]] - 0.000767688854520869957 # B[330, [6, 2, 2, 2], [16, 4, 2, 4]] - -0.00666111439578009716 # B[331, [6, 2, 2, 2], [17, 4, 2, 6]] - 0.0112705725443772303 # B[332, [6, 2, 2, 2], [18, 4, 3, 5]] - 0.00228839615631495127 # B[333, [6, 2, 2, 2], [19, 4, 3, 7]] - 0.00124148748415313414 # B[334, [6, 2, 2, 2], [20, 4, 4, 4]] - 0.00353391028977510834 # B[335, [6, 2, 2, 2], [21, 4, 4, 6]] - -0.00310464569903003834 # B[336, [6, 2, 2, 2], [22, 4, 4, 8]] - -0.001770681064288395 # B[337, [6, 2, 2, 2], [23, 5, 0, 5]] - 0.000554784469018851215 # B[338, [6, 2, 2, 2], [24, 5, 1, 6]] - -0.000102008183116791319 # B[339, [6, 2, 2, 2], [25, 5, 2, 5]] - -0.00128750706249572758 # B[340, [6, 2, 2, 2], [26, 5, 2, 7]] - 0.0046490656013451568 # B[341, [6, 2, 2, 2], [27, 5, 3, 6]] - 0.0034506831073765681 # B[342, [6, 2, 2, 2], [28, 5, 3, 8]] - 0.00501652811902741046 # B[343, [6, 2, 2, 2], [29, 5, 4, 5]] - -1.88389891915279224e-05 # B[344, [6, 2, 2, 2], [30, 5, 4, 7]] - -0.00246586719805504942 # B[345, [6, 2, 2, 2], [31, 5, 5, 6]] - -0.00339629261051872756 # B[346, [6, 2, 2, 2], [32, 5, 5, 8]] - -1.22729584505151552e-05 # B[347, [6, 2, 2, 2], [33, 6, 0, 6]] - -0.0055646406349652653 # B[348, [6, 2, 2, 2], [34, 6, 1, 7]] - 0.00216606634250279383 # B[349, [6, 2, 2, 2], [35, 6, 2, 6]] - -0.000140725603696151627 # B[350, [6, 2, 2, 2], [36, 6, 2, 8]] - -0.01190136261487338 # B[351, [6, 2, 2, 2], [37, 6, 3, 7]] - -0.000996588010308921109 # B[352, [6, 2, 2, 2], [38, 6, 4, 6]] - -0.0040124728576705895 # B[353, [6, 2, 2, 2], [39, 6, 4, 8]] - 0.000422679331586792552 # B[354, [6, 2, 2, 2], [40, 6, 5, 7]] - 0.000548939662545001959 # B[355, [6, 2, 2, 2], [41, 6, 6, 6]] - 0.00256895119228900404 # B[356, [6, 2, 2, 2], [42, 6, 6, 8]] - -0.000615139781019174688 # B[357, [6, 2, 2, 2], [43, 7, 0, 7]] - -0.00404941774617198578 # B[358, [6, 2, 2, 2], [44, 7, 1, 8]] - 0.00466754848324051064 # B[359, [6, 2, 2, 2], [45, 7, 2, 7]] - 0.00150461796185176488 # B[360, [6, 2, 2, 2], [46, 7, 3, 8]] - 0.0037489054114537468 # B[361, [6, 2, 2, 2], [47, 7, 4, 7]] - 0.00285804436398595782 # B[362, [6, 2, 2, 2], [48, 7, 5, 8]] - -0.00287521518361254919 # B[363, [6, 2, 2, 2], [49, 7, 6, 7]] - 0.000969520968104660755 # B[364, [6, 2, 2, 2], [50, 7, 7, 8]] - -0.000716125857042927043 # B[365, [6, 2, 2, 2], [51, 8, 0, 8]] - -0.00157385185114507437 # B[366, [6, 2, 2, 2], [52, 8, 2, 8]] - 0.002689243736875038 # B[367, [6, 2, 2, 2], [53, 8, 4, 8]] - -0.000661038690452418623 # B[368, [6, 2, 2, 2], [54, 8, 6, 8]] - 0.00157186481624649321 # B[369, [6, 2, 2, 2], [55, 8, 8, 8]] - -0.0134601349926017494 # B[370, [7, 2, 2, 4], [7, 2, 2, 4]] - -0.000918558149715113011 # B[371, [7, 2, 2, 4], [8, 3, 0, 3]] - -0.00377418701166061087 # B[372, [7, 2, 2, 4], [9, 3, 1, 4]] - 0.0148168734486278948 # B[373, [7, 2, 2, 4], [10, 3, 2, 3]] - -0.00535328606426562371 # B[374, [7, 2, 2, 4], [11, 3, 2, 5]] - 0.00804271469408427385 # B[375, [7, 2, 2, 4], [12, 3, 3, 4]] - 0.00136329663181449737 # B[376, [7, 2, 2, 4], [13, 3, 3, 6]] - 0.000218608555253111195 # B[377, [7, 2, 2, 4], [14, 4, 0, 4]] - 0.00767165886258287799 # B[378, [7, 2, 2, 4], [15, 4, 1, 5]] - -0.0022580429604385833 # B[379, [7, 2, 2, 4], [16, 4, 2, 4]] - -0.0050991924246220309 # B[380, [7, 2, 2, 4], [17, 4, 2, 6]] - -0.00308509180848093572 # B[381, [7, 2, 2, 4], [18, 4, 3, 5]] - -0.000900097231895549623 # B[382, [7, 2, 2, 4], [19, 4, 3, 7]] - -0.0063557020842957869 # B[383, [7, 2, 2, 4], [20, 4, 4, 4]] - -0.000409569358807882096 # B[384, [7, 2, 2, 4], [21, 4, 4, 6]] - 0.00254581400782049119 # B[385, [7, 2, 2, 4], [22, 4, 4, 8]] - 0.000657951401298526029 # B[386, [7, 2, 2, 4], [23, 5, 0, 5]] - -0.00940269729352927013 # B[387, [7, 2, 2, 4], [24, 5, 1, 6]] - 0.00333566383730494239 # B[388, [7, 2, 2, 4], [25, 5, 2, 5]] - 0.00896493308698088215 # B[389, [7, 2, 2, 4], [26, 5, 2, 7]] - 0.00132812590751918685 # B[390, [7, 2, 2, 4], [27, 5, 3, 6]] - -0.00127282140780485189 # B[391, [7, 2, 2, 4], [28, 5, 3, 8]] - -0.00435358176352772068 # B[392, [7, 2, 2, 4], [29, 5, 4, 5]] - -0.00226566527245459885 # B[393, [7, 2, 2, 4], [30, 5, 4, 7]] - 0.00326597657188156627 # B[394, [7, 2, 2, 4], [31, 5, 5, 6]] - -0.00247993076825692074 # B[395, [7, 2, 2, 4], [32, 5, 5, 8]] - -0.00138012806761597748 # B[396, [7, 2, 2, 4], [33, 6, 0, 6]] - -0.00296559266178312566 # B[397, [7, 2, 2, 4], [34, 6, 1, 7]] - -0.00345134318647404535 # B[398, [7, 2, 2, 4], [35, 6, 2, 6]] - 0.00604122282441024554 # B[399, [7, 2, 2, 4], [36, 6, 2, 8]] - -0.00602530276328681197 # B[400, [7, 2, 2, 4], [37, 6, 3, 7]] - 0.00113230868581531974 # B[401, [7, 2, 2, 4], [38, 6, 4, 6]] - 0.00132069580529702024 # B[402, [7, 2, 2, 4], [39, 6, 4, 8]] - -0.00355708848499901743 # B[403, [7, 2, 2, 4], [40, 6, 5, 7]] - 0.00103954578232134899 # B[404, [7, 2, 2, 4], [41, 6, 6, 6]] - 0.00138660655783935638 # B[405, [7, 2, 2, 4], [42, 6, 6, 8]] - 0.00122312383058832339 # B[406, [7, 2, 2, 4], [43, 7, 0, 7]] - 0.00122422070912251465 # B[407, [7, 2, 2, 4], [44, 7, 1, 8]] - -0.00497379521097694472 # B[408, [7, 2, 2, 4], [45, 7, 2, 7]] - -0.00811974704425355749 # B[409, [7, 2, 2, 4], [46, 7, 3, 8]] - 0.00114732010903773659 # B[410, [7, 2, 2, 4], [47, 7, 4, 7]] - -0.00569074628354063975 # B[411, [7, 2, 2, 4], [48, 7, 5, 8]] - 0.00235624642317577588 # B[412, [7, 2, 2, 4], [49, 7, 6, 7]] - 7.98437182146268919e-05 # B[413, [7, 2, 2, 4], [50, 7, 7, 8]] - 0.00113891921332402897 # B[414, [7, 2, 2, 4], [51, 8, 0, 8]] - -0.00492469555442132112 # B[415, [7, 2, 2, 4], [52, 8, 2, 8]] - 0.000792980352556455804 # B[416, [7, 2, 2, 4], [53, 8, 4, 8]] - 0.00153854887229367375 # B[417, [7, 2, 2, 4], [54, 8, 6, 8]] - -0.000881221748445243022 # B[418, [7, 2, 2, 4], [55, 8, 8, 8]] - -0.00136471788502227735 # B[419, [8, 3, 0, 3], [8, 3, 0, 3]] - 0.00246251727263488776 # B[420, [8, 3, 0, 3], [9, 3, 1, 4]] - 0.000996613519267240677 # B[421, [8, 3, 0, 3], [10, 3, 2, 3]] - -0.00207976146372090831 # B[422, [8, 3, 0, 3], [11, 3, 2, 5]] - -9.97509064182486305e-05 # B[423, [8, 3, 0, 3], [12, 3, 3, 4]] - 0.000656935135924852087 # B[424, [8, 3, 0, 3], [13, 3, 3, 6]] - -0.000492474229225159377 # B[425, [8, 3, 0, 3], [14, 4, 0, 4]] - 0.0032189163248994351 # B[426, [8, 3, 0, 3], [15, 4, 1, 5]] - -0.00115555104609991501 # B[427, [8, 3, 0, 3], [16, 4, 2, 4]] - -0.000101151026370576574 # B[428, [8, 3, 0, 3], [17, 4, 2, 6]] - 0.00020301152740384229 # B[429, [8, 3, 0, 3], [18, 4, 3, 5]] - -0.000285445107860462371 # B[430, [8, 3, 0, 3], [19, 4, 3, 7]] - 0.000462665925556146607 # B[431, [8, 3, 0, 3], [20, 4, 4, 4]] - -2.75652763320703015e-05 # B[432, [8, 3, 0, 3], [21, 4, 4, 6]] - -0.000358778647317398169 # B[433, [8, 3, 0, 3], [22, 4, 4, 8]] - -0.000397176131748222527 # B[434, [8, 3, 0, 3], [23, 5, 0, 5]] - -0.00026950177456114624 # B[435, [8, 3, 0, 3], [24, 5, 1, 6]] - 0.00119424632084062527 # B[436, [8, 3, 0, 3], [25, 5, 2, 5]] - 0.000922347152199163439 # B[437, [8, 3, 0, 3], [26, 5, 2, 7]] - -0.000340838509282952173 # B[438, [8, 3, 0, 3], [27, 5, 3, 6]] - 0.00128847730890532808 # B[439, [8, 3, 0, 3], [28, 5, 3, 8]] - -0.00044582191494569115 # B[440, [8, 3, 0, 3], [29, 5, 4, 5]] - -0.00114898350718379422 # B[441, [8, 3, 0, 3], [30, 5, 4, 7]] - -0.000530499767100067743 # B[442, [8, 3, 0, 3], [31, 5, 5, 6]] - 1.68864176486992895e-05 # B[443, [8, 3, 0, 3], [32, 5, 5, 8]] - -0.000312292146951373417 # B[444, [8, 3, 0, 3], [33, 6, 0, 6]] - -0.00186273440079770883 # B[445, [8, 3, 0, 3], [34, 6, 1, 7]] - -0.000475625961442131123 # B[446, [8, 3, 0, 3], [35, 6, 2, 6]] - 0.000505090975521763769 # B[447, [8, 3, 0, 3], [36, 6, 2, 8]] - 0.000128630083375533277 # B[448, [8, 3, 0, 3], [37, 6, 3, 7]] - -0.000431369283499544176 # B[449, [8, 3, 0, 3], [38, 6, 4, 6]] - 0.000461881443708941908 # B[450, [8, 3, 0, 3], [39, 6, 4, 8]] - 0.000867550860200114182 # B[451, [8, 3, 0, 3], [40, 6, 5, 7]] - 0.000179604539903628624 # B[452, [8, 3, 0, 3], [41, 6, 6, 6]] - -0.000405383988192370426 # B[453, [8, 3, 0, 3], [42, 6, 6, 8]] - -0.000305572243426546764 # B[454, [8, 3, 0, 3], [43, 7, 0, 7]] - -0.0010766931736053021 # B[455, [8, 3, 0, 3], [44, 7, 1, 8]] - 0.000701859051866787764 # B[456, [8, 3, 0, 3], [45, 7, 2, 7]] - -1.5413662061584954e-05 # B[457, [8, 3, 0, 3], [46, 7, 3, 8]] - 0.000428834666348756888 # B[458, [8, 3, 0, 3], [47, 7, 4, 7]] - 0.000468098667731533385 # B[459, [8, 3, 0, 3], [48, 7, 5, 8]] - 0.000158467988956009775 # B[460, [8, 3, 0, 3], [49, 7, 6, 7]] - 2.77948419442784408e-05 # B[461, [8, 3, 0, 3], [50, 7, 7, 8]] - -0.000282655955044820717 # B[462, [8, 3, 0, 3], [51, 8, 0, 8]] - 0.000100300940760145348 # B[463, [8, 3, 0, 3], [52, 8, 2, 8]] - 0.000314947671131902973 # B[464, [8, 3, 0, 3], [53, 8, 4, 8]] - 0.000144842823919437078 # B[465, [8, 3, 0, 3], [54, 8, 6, 8]] - 7.00050428864840146e-05 # B[466, [8, 3, 0, 3], [55, 8, 8, 8]] - 0.0118411448561217512 # B[467, [9, 3, 1, 4], [9, 3, 1, 4]] - 0.0158809314732707603 # B[468, [9, 3, 1, 4], [10, 3, 2, 3]] - -0.00690506493475962109 # B[469, [9, 3, 1, 4], [11, 3, 2, 5]] - 0.0085626937099196887 # B[470, [9, 3, 1, 4], [12, 3, 3, 4]] - -0.00387686964925252654 # B[471, [9, 3, 1, 4], [13, 3, 3, 6]] - 0.00015029200549142481 # B[472, [9, 3, 1, 4], [14, 4, 0, 4]] - -0.000142532963490632015 # B[473, [9, 3, 1, 4], [15, 4, 1, 5]] - 0.00921427022949583042 # B[474, [9, 3, 1, 4], [16, 4, 2, 4]] - -0.0112717231196791407 # B[475, [9, 3, 1, 4], [17, 4, 2, 6]] - -0.0122014182952103704 # B[476, [9, 3, 1, 4], [18, 4, 3, 5]] - -0.0111571557686284996 # B[477, [9, 3, 1, 4], [19, 4, 3, 7]] - -0.00276180055211498916 # B[478, [9, 3, 1, 4], [20, 4, 4, 4]] - -0.00444456405006457382 # B[479, [9, 3, 1, 4], [21, 4, 4, 6]] - -0.00248162623330630983 # B[480, [9, 3, 1, 4], [22, 4, 4, 8]] - 0.000238830840202226575 # B[481, [9, 3, 1, 4], [23, 5, 0, 5]] - 0.0106883008114137777 # B[482, [9, 3, 1, 4], [24, 5, 1, 6]] - -0.00176293319638371826 # B[483, [9, 3, 1, 4], [25, 5, 2, 5]] - -0.000706186990249144109 # B[484, [9, 3, 1, 4], [26, 5, 2, 7]] - -0.000957413082652629373 # B[485, [9, 3, 1, 4], [27, 5, 3, 6]] - -0.00485998335666546887 # B[486, [9, 3, 1, 4], [28, 5, 3, 8]] - -0.000739967956913101287 # B[487, [9, 3, 1, 4], [29, 5, 4, 5]] - -0.00656002591947351353 # B[488, [9, 3, 1, 4], [30, 5, 4, 7]] - -0.00191607250770065712 # B[489, [9, 3, 1, 4], [31, 5, 5, 6]] - -0.000375150046930213714 # B[490, [9, 3, 1, 4], [32, 5, 5, 8]] - 0.000379540253919751804 # B[491, [9, 3, 1, 4], [33, 6, 0, 6]] - 0.0103809997405371179 # B[492, [9, 3, 1, 4], [34, 6, 1, 7]] - -0.00167937900508645203 # B[493, [9, 3, 1, 4], [35, 6, 2, 6]] - -0.000942453027264282192 # B[494, [9, 3, 1, 4], [36, 6, 2, 8]] - -0.00358794660355351257 # B[495, [9, 3, 1, 4], [37, 6, 3, 7]] - 0.00367542903060237222 # B[496, [9, 3, 1, 4], [38, 6, 4, 6]] - -0.00605874518215254298 # B[497, [9, 3, 1, 4], [39, 6, 4, 8]] - -0.0053364107721741022 # B[498, [9, 3, 1, 4], [40, 6, 5, 7]] - -0.00220303686176452889 # B[499, [9, 3, 1, 4], [41, 6, 6, 6]] - 0.000240224733534942676 # B[500, [9, 3, 1, 4], [42, 6, 6, 8]] - 0.00118204722287629585 # B[501, [9, 3, 1, 4], [43, 7, 0, 7]] - 0.00391606544218769514 # B[502, [9, 3, 1, 4], [44, 7, 1, 8]] - -0.00190557542057654024 # B[503, [9, 3, 1, 4], [45, 7, 2, 7]] - -0.0010749256928406746 # B[504, [9, 3, 1, 4], [46, 7, 3, 8]] - 6.24186835188134462e-05 # B[505, [9, 3, 1, 4], [47, 7, 4, 7]] - -0.00250872188348977114 # B[506, [9, 3, 1, 4], [48, 7, 5, 8]] - -0.00164710314956706405 # B[507, [9, 3, 1, 4], [49, 7, 6, 7]] - -0.0029144992153610676 # B[508, [9, 3, 1, 4], [50, 7, 7, 8]] - 0.000712015267242259442 # B[509, [9, 3, 1, 4], [51, 8, 0, 8]] - -0.00179539873092394715 # B[510, [9, 3, 1, 4], [52, 8, 2, 8]] - 0.00203000698298521493 # B[511, [9, 3, 1, 4], [53, 8, 4, 8]] - -0.00103477100047664442 # B[512, [9, 3, 1, 4], [54, 8, 6, 8]] - -0.000727628763147338854 # B[513, [9, 3, 1, 4], [55, 8, 8, 8]] - 0.0163451466486591972 # B[514, [10, 3, 2, 3], [10, 3, 2, 3]] - -0.00145259448176927441 # B[515, [10, 3, 2, 3], [11, 3, 2, 5]] - -0.00808947571520425568 # B[516, [10, 3, 2, 3], [12, 3, 3, 4]] - -0.00693599935022420205 # B[517, [10, 3, 2, 3], [13, 3, 3, 6]] - -0.00419683318703741731 # B[518, [10, 3, 2, 3], [14, 4, 0, 4]] - 0.00927666204585274323 # B[519, [10, 3, 2, 3], [15, 4, 1, 5]] - -0.0138962541759877663 # B[520, [10, 3, 2, 3], [16, 4, 2, 4]] - 0.0115061801390417759 # B[521, [10, 3, 2, 3], [17, 4, 2, 6]] - 0.0118559077356181798 # B[522, [10, 3, 2, 3], [18, 4, 3, 5]] - 0.00193270595871023604 # B[523, [10, 3, 2, 3], [19, 4, 3, 7]] - 0.00156708209719190472 # B[524, [10, 3, 2, 3], [20, 4, 4, 4]] - 0.0030286948486105119 # B[525, [10, 3, 2, 3], [21, 4, 4, 6]] - -6.03736466163237034e-05 # B[526, [10, 3, 2, 3], [22, 4, 4, 8]] - -0.00147218391304548835 # B[527, [10, 3, 2, 3], [23, 5, 0, 5]] - 0.000931966019926808685 # B[528, [10, 3, 2, 3], [24, 5, 1, 6]] - 0.0153667638164197012 # B[529, [10, 3, 2, 3], [25, 5, 2, 5]] - -0.0023105273691670326 # B[530, [10, 3, 2, 3], [26, 5, 2, 7]] - 0.0018873267014898696 # B[531, [10, 3, 2, 3], [27, 5, 3, 6]] - -0.00221592978134090707 # B[532, [10, 3, 2, 3], [28, 5, 3, 8]] - 0.00175823978838723916 # B[533, [10, 3, 2, 3], [29, 5, 4, 5]] - 0.00134986143361107494 # B[534, [10, 3, 2, 3], [30, 5, 4, 7]] - -0.00280444330034939227 # B[535, [10, 3, 2, 3], [31, 5, 5, 6]] - -0.000446159575940244073 # B[536, [10, 3, 2, 3], [32, 5, 5, 8]] - 0.000126573802730074736 # B[537, [10, 3, 2, 3], [33, 6, 0, 6]] - 7.95217271451070795e-05 # B[538, [10, 3, 2, 3], [34, 6, 1, 7]] - -0.000615992203402992468 # B[539, [10, 3, 2, 3], [35, 6, 2, 6]] - -0.0106304231235931409 # B[540, [10, 3, 2, 3], [36, 6, 2, 8]] - -0.00513102234934090934 # B[541, [10, 3, 2, 3], [37, 6, 3, 7]] - 0.00086364506858761271 # B[542, [10, 3, 2, 3], [38, 6, 4, 6]] - -0.00427816275089007263 # B[543, [10, 3, 2, 3], [39, 6, 4, 8]] - -0.00709876751806875171 # B[544, [10, 3, 2, 3], [40, 6, 5, 7]] - -0.00107679083671011894 # B[545, [10, 3, 2, 3], [41, 6, 6, 6]] - -0.0014022801302571164 # B[546, [10, 3, 2, 3], [42, 6, 6, 8]] - 0.00032001340322446864 # B[547, [10, 3, 2, 3], [43, 7, 0, 7]] - 0.0099494513037338677 # B[548, [10, 3, 2, 3], [44, 7, 1, 8]] - 0.00657164457459321564 # B[549, [10, 3, 2, 3], [45, 7, 2, 7]] - -0.00193909086513409032 # B[550, [10, 3, 2, 3], [46, 7, 3, 8]] - -0.000661327911070458407 # B[551, [10, 3, 2, 3], [47, 7, 4, 7]] - -0.00236609840279333045 # B[552, [10, 3, 2, 3], [48, 7, 5, 8]] - 0.000323126961361372422 # B[553, [10, 3, 2, 3], [49, 7, 6, 7]] - 0.00156411007472663857 # B[554, [10, 3, 2, 3], [50, 7, 7, 8]] - -0.000413410696562647312 # B[555, [10, 3, 2, 3], [51, 8, 0, 8]] - 0.00151556635054790959 # B[556, [10, 3, 2, 3], [52, 8, 2, 8]] - 0.0032252808357782943 # B[557, [10, 3, 2, 3], [53, 8, 4, 8]] - 0.00431814581620697767 # B[558, [10, 3, 2, 3], [54, 8, 6, 8]] - 0.000198535493268348594 # B[559, [10, 3, 2, 3], [55, 8, 8, 8]] - 0.0156540432654675432 # B[560, [11, 3, 2, 5], [11, 3, 2, 5]] - 0.00979845476873780416 # B[561, [11, 3, 2, 5], [12, 3, 3, 4]] - 0.00873265456764509701 # B[562, [11, 3, 2, 5], [13, 3, 3, 6]] - -0.00355250352643814854 # B[563, [11, 3, 2, 5], [14, 4, 0, 4]] - 0.0197388975583387243 # B[564, [11, 3, 2, 5], [15, 4, 1, 5]] - 0.0158965586216084157 # B[565, [11, 3, 2, 5], [16, 4, 2, 4]] - 0.0126440348146513917 # B[566, [11, 3, 2, 5], [17, 4, 2, 6]] - 0.00588822462217037865 # B[567, [11, 3, 2, 5], [18, 4, 3, 5]] - 0.00465829809814364074 # B[568, [11, 3, 2, 5], [19, 4, 3, 7]] - 0.00460100330976275125 # B[569, [11, 3, 2, 5], [20, 4, 4, 4]] - 0.00507979510261629894 # B[570, [11, 3, 2, 5], [21, 4, 4, 6]] - -0.000978147842247499566 # B[571, [11, 3, 2, 5], [22, 4, 4, 8]] - 0.000175648698607325238 # B[572, [11, 3, 2, 5], [23, 5, 0, 5]] - 0.00701365729786882983 # B[573, [11, 3, 2, 5], [24, 5, 1, 6]] - 0.0124121871279893672 # B[574, [11, 3, 2, 5], [25, 5, 2, 5]] - 0.0133268604743271169 # B[575, [11, 3, 2, 5], [26, 5, 2, 7]] - -0.00306906262974302943 # B[576, [11, 3, 2, 5], [27, 5, 3, 6]] - 0.00411586711144847073 # B[577, [11, 3, 2, 5], [28, 5, 3, 8]] - -0.00483702208096517539 # B[578, [11, 3, 2, 5], [29, 5, 4, 5]] - 0.000232830853394127776 # B[579, [11, 3, 2, 5], [30, 5, 4, 7]] - -0.00500644765401524715 # B[580, [11, 3, 2, 5], [31, 5, 5, 6]] - -0.000732991087538808345 # B[581, [11, 3, 2, 5], [32, 5, 5, 8]] - 0.0028290195015726223 # B[582, [11, 3, 2, 5], [33, 6, 0, 6]] - 0.000660043236562475252 # B[583, [11, 3, 2, 5], [34, 6, 1, 7]] - 0.00858014820620479901 # B[584, [11, 3, 2, 5], [35, 6, 2, 6]] - 0.00979420830127970127 # B[585, [11, 3, 2, 5], [36, 6, 2, 8]] - -0.00276929529868128257 # B[586, [11, 3, 2, 5], [37, 6, 3, 7]] - -0.00462592209123751513 # B[587, [11, 3, 2, 5], [38, 6, 4, 6]] - 0.000957159367659247626 # B[588, [11, 3, 2, 5], [39, 6, 4, 8]] - -0.00289923459154850169 # B[589, [11, 3, 2, 5], [40, 6, 5, 7]] - -0.00605668820795574915 # B[590, [11, 3, 2, 5], [41, 6, 6, 6]] - -0.00571070540762017888 # B[591, [11, 3, 2, 5], [42, 6, 6, 8]] - 0.00247733408975375075 # B[592, [11, 3, 2, 5], [43, 7, 0, 7]] - 0.00452000165177812024 # B[593, [11, 3, 2, 5], [44, 7, 1, 8]] - 0.00267833963693382693 # B[594, [11, 3, 2, 5], [45, 7, 2, 7]] - -0.00558917145621175976 # B[595, [11, 3, 2, 5], [46, 7, 3, 8]] - -0.00228097422335522999 # B[596, [11, 3, 2, 5], [47, 7, 4, 7]] - -0.00366604043706369575 # B[597, [11, 3, 2, 5], [48, 7, 5, 8]] - -0.00340088281218112534 # B[598, [11, 3, 2, 5], [49, 7, 6, 7]] - -0.00355022426643257852 # B[599, [11, 3, 2, 5], [50, 7, 7, 8]] - 0.00124080314205340242 # B[600, [11, 3, 2, 5], [51, 8, 0, 8]] - 0.00287261267197001097 # B[601, [11, 3, 2, 5], [52, 8, 2, 8]] - 0.000744815191487350516 # B[602, [11, 3, 2, 5], [53, 8, 4, 8]] - -0.000112288931147085103 # B[603, [11, 3, 2, 5], [54, 8, 6, 8]] - -0.000128712309023326903 # B[604, [11, 3, 2, 5], [55, 8, 8, 8]] - -0.00238666366477884723 # B[605, [12, 3, 3, 4], [12, 3, 3, 4]] - 0.000248696286071804773 # B[606, [12, 3, 3, 4], [13, 3, 3, 6]] - -0.000479775127143412111 # B[607, [12, 3, 3, 4], [14, 4, 0, 4]] - 0.00175952173341571141 # B[608, [12, 3, 3, 4], [15, 4, 1, 5]] - 0.000197368498788095745 # B[609, [12, 3, 3, 4], [16, 4, 2, 4]] - 0.00726401135600521306 # B[610, [12, 3, 3, 4], [17, 4, 2, 6]] - -0.00118096336629036625 # B[611, [12, 3, 3, 4], [18, 4, 3, 5]] - 0.00702896514440041337 # B[612, [12, 3, 3, 4], [19, 4, 3, 7]] - -0.00236026619914155369 # B[613, [12, 3, 3, 4], [20, 4, 4, 4]] - -0.00341152672753146672 # B[614, [12, 3, 3, 4], [21, 4, 4, 6]] - 0.00348613231611557411 # B[615, [12, 3, 3, 4], [22, 4, 4, 8]] - 0.00244457707345889508 # B[616, [12, 3, 3, 4], [23, 5, 0, 5]] - -0.000822727235681003019 # B[617, [12, 3, 3, 4], [24, 5, 1, 6]] - -0.00248763810919495551 # B[618, [12, 3, 3, 4], [25, 5, 2, 5]] - 0.00796413115978647848 # B[619, [12, 3, 3, 4], [26, 5, 2, 7]] - -0.00179317048488774472 # B[620, [12, 3, 3, 4], [27, 5, 3, 6]] - 0.00454384820995466787 # B[621, [12, 3, 3, 4], [28, 5, 3, 8]] - -0.00425365149530766012 # B[622, [12, 3, 3, 4], [29, 5, 4, 5]] - -0.000569152560526600682 # B[623, [12, 3, 3, 4], [30, 5, 4, 7]] - -0.00506501220127485163 # B[624, [12, 3, 3, 4], [31, 5, 5, 6]] - -0.00142637122228714969 # B[625, [12, 3, 3, 4], [32, 5, 5, 8]] - 0.00190739239349446005 # B[626, [12, 3, 3, 4], [33, 6, 0, 6]] - 0.00215429853006474104 # B[627, [12, 3, 3, 4], [34, 6, 1, 7]] - 0.00512135793044871807 # B[628, [12, 3, 3, 4], [35, 6, 2, 6]] - 0.00479344551680733165 # B[629, [12, 3, 3, 4], [36, 6, 2, 8]] - -0.000813733007282164966 # B[630, [12, 3, 3, 4], [37, 6, 3, 7]] - -0.00162747725274282884 # B[631, [12, 3, 3, 4], [38, 6, 4, 6]] - -0.00440004969635155417 # B[632, [12, 3, 3, 4], [39, 6, 4, 8]] - -0.00939941153506137356 # B[633, [12, 3, 3, 4], [40, 6, 5, 7]] - -0.00314893787689287524 # B[634, [12, 3, 3, 4], [41, 6, 6, 6]] - -0.00125776748984993136 # B[635, [12, 3, 3, 4], [42, 6, 6, 8]] - 0.00129112127843685615 # B[636, [12, 3, 3, 4], [43, 7, 0, 7]] - 0.00564724346615860621 # B[637, [12, 3, 3, 4], [44, 7, 1, 8]] - -0.0018460571659526942 # B[638, [12, 3, 3, 4], [45, 7, 2, 7]] - -0.000300525523225368685 # B[639, [12, 3, 3, 4], [46, 7, 3, 8]] - -0.00277157581435865698 # B[640, [12, 3, 3, 4], [47, 7, 4, 7]] - -0.00975210406554173105 # B[641, [12, 3, 3, 4], [48, 7, 5, 8]] - -0.00233845213984289896 # B[642, [12, 3, 3, 4], [49, 7, 6, 7]] - -0.00138723239922117561 # B[643, [12, 3, 3, 4], [50, 7, 7, 8]] - 0.000864866797073243071 # B[644, [12, 3, 3, 4], [51, 8, 0, 8]] - -0.000747563068773752452 # B[645, [12, 3, 3, 4], [52, 8, 2, 8]] - 0.000965474694725087373 # B[646, [12, 3, 3, 4], [53, 8, 4, 8]] - -0.00140612646390263218 # B[647, [12, 3, 3, 4], [54, 8, 6, 8]] - -0.00149643617894318522 # B[648, [12, 3, 3, 4], [55, 8, 8, 8]] - 0.00149153681612450295 # B[649, [13, 3, 3, 6], [13, 3, 3, 6]] - -0.000954556711257832646 # B[650, [13, 3, 3, 6], [14, 4, 0, 4]] - 0.00120983585813713799 # B[651, [13, 3, 3, 6], [15, 4, 1, 5]] - 0.00300317867570911888 # B[652, [13, 3, 3, 6], [16, 4, 2, 4]] - 0.00236443796053106663 # B[653, [13, 3, 3, 6], [17, 4, 2, 6]] - 0.00415524139600132597 # B[654, [13, 3, 3, 6], [18, 4, 3, 5]] - -0.000123573851697839077 # B[655, [13, 3, 3, 6], [19, 4, 3, 7]] - 0.000470359195248265527 # B[656, [13, 3, 3, 6], [20, 4, 4, 4]] - 0.000635927641249957321 # B[657, [13, 3, 3, 6], [21, 4, 4, 6]] - 0.000747673754939660613 # B[658, [13, 3, 3, 6], [22, 4, 4, 8]] - 0.00074188846631736971 # B[659, [13, 3, 3, 6], [23, 5, 0, 5]] - 0.00463957097737913854 # B[660, [13, 3, 3, 6], [24, 5, 1, 6]] - -0.00271105182543343939 # B[661, [13, 3, 3, 6], [25, 5, 2, 5]] - 6.90411348413036419e-06 # B[662, [13, 3, 3, 6], [26, 5, 2, 7]] - 0.000911354980270381865 # B[663, [13, 3, 3, 6], [27, 5, 3, 6]] - -0.0028545746938972022 # B[664, [13, 3, 3, 6], [28, 5, 3, 8]] - -1.76062828863947363e-05 # B[665, [13, 3, 3, 6], [29, 5, 4, 5]] - -1.51206672011107435e-05 # B[666, [13, 3, 3, 6], [30, 5, 4, 7]] - -0.000798318879555708766 # B[667, [13, 3, 3, 6], [31, 5, 5, 6]] - -0.0015978026047660434 # B[668, [13, 3, 3, 6], [32, 5, 5, 8]] - 0.00034244751324807865 # B[669, [13, 3, 3, 6], [33, 6, 0, 6]] - 0.00338996797689858353 # B[670, [13, 3, 3, 6], [34, 6, 1, 7]] - 0.000289281476490772793 # B[671, [13, 3, 3, 6], [35, 6, 2, 6]] - -0.000559772151149058594 # B[672, [13, 3, 3, 6], [36, 6, 2, 8]] - -0.000650724286175463629 # B[673, [13, 3, 3, 6], [37, 6, 3, 7]] - 0.00148244897292096334 # B[674, [13, 3, 3, 6], [38, 6, 4, 6]] - 0.000183404639618602733 # B[675, [13, 3, 3, 6], [39, 6, 4, 8]] - -0.00185779692530890772 # B[676, [13, 3, 3, 6], [40, 6, 5, 7]] - -0.000708322215432564961 # B[677, [13, 3, 3, 6], [41, 6, 6, 6]] - -0.000491831969715535167 # B[678, [13, 3, 3, 6], [42, 6, 6, 8]] - 0.000833818016036214082 # B[679, [13, 3, 3, 6], [43, 7, 0, 7]] - -0.00256922900730601443 # B[680, [13, 3, 3, 6], [44, 7, 1, 8]] - -0.00112433206588518839 # B[681, [13, 3, 3, 6], [45, 7, 2, 7]] - 6.43716101358243753e-05 # B[682, [13, 3, 3, 6], [46, 7, 3, 8]] - -0.00126304972485289518 # B[683, [13, 3, 3, 6], [47, 7, 4, 7]] - -0.00210937996313975001 # B[684, [13, 3, 3, 6], [48, 7, 5, 8]] - -0.00126022676030809744 # B[685, [13, 3, 3, 6], [49, 7, 6, 7]] - -0.000555039709846411045 # B[686, [13, 3, 3, 6], [50, 7, 7, 8]] - 0.000790824100586496465 # B[687, [13, 3, 3, 6], [51, 8, 0, 8]] - -0.000844206812343649936 # B[688, [13, 3, 3, 6], [52, 8, 2, 8]] - 0.000195900027714517901 # B[689, [13, 3, 3, 6], [53, 8, 4, 8]] - -0.000823274415849936658 # B[690, [13, 3, 3, 6], [54, 8, 6, 8]] - -0.000330474595809105917 # B[691, [13, 3, 3, 6], [55, 8, 8, 8]] - -3.04835503155357485e-05 # B[692, [14, 4, 0, 4], [14, 4, 0, 4]] - -0.000825475145007361147 # B[693, [14, 4, 0, 4], [15, 4, 1, 5]] - -0.00244887111925138484 # B[694, [14, 4, 0, 4], [16, 4, 2, 4]] - -0.00122050568127611732 # B[695, [14, 4, 0, 4], [17, 4, 2, 6]] - -0.00226655265247485693 # B[696, [14, 4, 0, 4], [18, 4, 3, 5]] - -0.000767631950688907327 # B[697, [14, 4, 0, 4], [19, 4, 3, 7]] - -0.000547575812124723171 # B[698, [14, 4, 0, 4], [20, 4, 4, 4]] - -0.00121783548699544442 # B[699, [14, 4, 0, 4], [21, 4, 4, 6]] - 6.68947985199286332e-05 # B[700, [14, 4, 0, 4], [22, 4, 4, 8]] - -9.6030771921717939e-05 # B[701, [14, 4, 0, 4], [23, 5, 0, 5]] - -0.000544408900336967871 # B[702, [14, 4, 0, 4], [24, 5, 1, 6]] - -0.00139019051437529293 # B[703, [14, 4, 0, 4], [25, 5, 2, 5]] - -0.000281919324988699413 # B[704, [14, 4, 0, 4], [26, 5, 2, 7]] - -0.00125721115437776171 # B[705, [14, 4, 0, 4], [27, 5, 3, 6]] - -0.000282797770993010317 # B[706, [14, 4, 0, 4], [28, 5, 3, 8]] - -0.00139320549871079641 # B[707, [14, 4, 0, 4], [29, 5, 4, 5]] - -0.000628813518841068401 # B[708, [14, 4, 0, 4], [30, 5, 4, 7]] - -0.000607292163329276047 # B[709, [14, 4, 0, 4], [31, 5, 5, 6]] - 0.000242807689929189566 # B[710, [14, 4, 0, 4], [32, 5, 5, 8]] - -0.000100536983796830487 # B[711, [14, 4, 0, 4], [33, 6, 0, 6]] - 0.00111838401982674706 # B[712, [14, 4, 0, 4], [34, 6, 1, 7]] - -0.0012014113032742873 # B[713, [14, 4, 0, 4], [35, 6, 2, 6]] - -1.32311363260466386e-05 # B[714, [14, 4, 0, 4], [36, 6, 2, 8]] - 0.000753146180409180327 # B[715, [14, 4, 0, 4], [37, 6, 3, 7]] - -0.000270332227596856156 # B[716, [14, 4, 0, 4], [38, 6, 4, 6]] - -0.000293750660311472775 # B[717, [14, 4, 0, 4], [39, 6, 4, 8]] - 6.52480591955099942e-05 # B[718, [14, 4, 0, 4], [40, 6, 5, 7]] - -4.70588815947581285e-05 # B[719, [14, 4, 0, 4], [41, 6, 6, 6]] - 0.000244731448919628669 # B[720, [14, 4, 0, 4], [42, 6, 6, 8]] - -9.3149326930830334e-05 # B[721, [14, 4, 0, 4], [43, 7, 0, 7]] - 0.000731947904616598796 # B[722, [14, 4, 0, 4], [44, 7, 1, 8]] - -0.00107463735030771668 # B[723, [14, 4, 0, 4], [45, 7, 2, 7]] - 0.000139861959076940934 # B[724, [14, 4, 0, 4], [46, 7, 3, 8]] - 0.000101877532936889281 # B[725, [14, 4, 0, 4], [47, 7, 4, 7]] - -0.000196888502333611437 # B[726, [14, 4, 0, 4], [48, 7, 5, 8]] - 6.12030178565765859e-05 # B[727, [14, 4, 0, 4], [49, 7, 6, 7]] - -0.000223986590912481076 # B[728, [14, 4, 0, 4], [50, 7, 7, 8]] - -6.56819431667232667e-05 # B[729, [14, 4, 0, 4], [51, 8, 0, 8]] - -0.000970632773483491584 # B[730, [14, 4, 0, 4], [52, 8, 2, 8]] - -0.000182189294658170395 # B[731, [14, 4, 0, 4], [53, 8, 4, 8]] - -3.45215935849477185e-05 # B[732, [14, 4, 0, 4], [54, 8, 6, 8]] - 6.19739521221795986e-05 # B[733, [14, 4, 0, 4], [55, 8, 8, 8]] - 0.000242753902013392972 # B[734, [15, 4, 1, 5], [15, 4, 1, 5]] - 0.00729727211034517358 # B[735, [15, 4, 1, 5], [16, 4, 2, 4]] - -0.0024545495000649507 # B[736, [15, 4, 1, 5], [17, 4, 2, 6]] - -0.00265559618939786597 # B[737, [15, 4, 1, 5], [18, 4, 3, 5]] - 0.00473045463551583639 # B[738, [15, 4, 1, 5], [19, 4, 3, 7]] - -0.000140785797905494323 # B[739, [15, 4, 1, 5], [20, 4, 4, 4]] - 0.00179841698526277474 # B[740, [15, 4, 1, 5], [21, 4, 4, 6]] - 0.00129773534161339073 # B[741, [15, 4, 1, 5], [22, 4, 4, 8]] - 0.00172905697138841467 # B[742, [15, 4, 1, 5], [23, 5, 0, 5]] - -0.00408304027381215483 # B[743, [15, 4, 1, 5], [24, 5, 1, 6]] - -0.00205043992851699228 # B[744, [15, 4, 1, 5], [25, 5, 2, 5]] - 0.000756591579123801249 # B[745, [15, 4, 1, 5], [26, 5, 2, 7]] - -0.00421238291006168549 # B[746, [15, 4, 1, 5], [27, 5, 3, 6]] - -0.00196911327032830725 # B[747, [15, 4, 1, 5], [28, 5, 3, 8]] - 0.000729488918071528446 # B[748, [15, 4, 1, 5], [29, 5, 4, 5]] - -0.00177843604064341788 # B[749, [15, 4, 1, 5], [30, 5, 4, 7]] - -0.00130376966915328159 # B[750, [15, 4, 1, 5], [31, 5, 5, 6]] - -0.00198695656227435707 # B[751, [15, 4, 1, 5], [32, 5, 5, 8]] - 0.000608914142072050635 # B[752, [15, 4, 1, 5], [33, 6, 0, 6]] - -0.00109469344681823767 # B[753, [15, 4, 1, 5], [34, 6, 1, 7]] - -0.00451953523789613495 # B[754, [15, 4, 1, 5], [35, 6, 2, 6]] - 0.00279449892877900279 # B[755, [15, 4, 1, 5], [36, 6, 2, 8]] - -0.00435984465194903283 # B[756, [15, 4, 1, 5], [37, 6, 3, 7]] - 0.00275969130186590542 # B[757, [15, 4, 1, 5], [38, 6, 4, 6]] - 0.00154021904971430755 # B[758, [15, 4, 1, 5], [39, 6, 4, 8]] - -0.00146163413862035289 # B[759, [15, 4, 1, 5], [40, 6, 5, 7]] - -0.000333421796264918996 # B[760, [15, 4, 1, 5], [41, 6, 6, 6]] - -0.00139958818201657261 # B[761, [15, 4, 1, 5], [42, 6, 6, 8]] - 0.000750502250600797172 # B[762, [15, 4, 1, 5], [43, 7, 0, 7]] - 0.00476052216726493421 # B[763, [15, 4, 1, 5], [44, 7, 1, 8]] - -0.00155321215408361565 # B[764, [15, 4, 1, 5], [45, 7, 2, 7]] - -0.00351167160511536933 # B[765, [15, 4, 1, 5], [46, 7, 3, 8]] - 0.00268907735535169144 # B[766, [15, 4, 1, 5], [47, 7, 4, 7]] - -0.00296394481906553462 # B[767, [15, 4, 1, 5], [48, 7, 5, 8]] - -0.00115945739998543369 # B[768, [15, 4, 1, 5], [49, 7, 6, 7]] - -0.0011498694923236445 # B[769, [15, 4, 1, 5], [50, 7, 7, 8]] - 0.000691127444573572114 # B[770, [15, 4, 1, 5], [51, 8, 0, 8]] - 0.00149148321917135169 # B[771, [15, 4, 1, 5], [52, 8, 2, 8]] - 0.00226549729687968923 # B[772, [15, 4, 1, 5], [53, 8, 4, 8]] - -0.00127955154911817224 # B[773, [15, 4, 1, 5], [54, 8, 6, 8]] - -0.0006680598304007173 # B[774, [15, 4, 1, 5], [55, 8, 8, 8]] - 0.00773393138113156846 # B[775, [16, 4, 2, 4], [16, 4, 2, 4]] - 0.00481567776445743917 # B[776, [16, 4, 2, 4], [17, 4, 2, 6]] - 0.00646602315581837339 # B[777, [16, 4, 2, 4], [18, 4, 3, 5]] - 0.00401373256364237051 # B[778, [16, 4, 2, 4], [19, 4, 3, 7]] - -0.000224833927917125753 # B[779, [16, 4, 2, 4], [20, 4, 4, 4]] - 0.0030532060451974926 # B[780, [16, 4, 2, 4], [21, 4, 4, 6]] - -0.000126777823410560014 # B[781, [16, 4, 2, 4], [22, 4, 4, 8]] - 0.00109512376860463863 # B[782, [16, 4, 2, 4], [23, 5, 0, 5]] - 0.0014906978453806609 # B[783, [16, 4, 2, 4], [24, 5, 1, 6]] - 0.00278609484035531206 # B[784, [16, 4, 2, 4], [25, 5, 2, 5]] - 0.00720611209490516682 # B[785, [16, 4, 2, 4], [26, 5, 2, 7]] - 0.00230880055683394415 # B[786, [16, 4, 2, 4], [27, 5, 3, 6]] - 0.00492114792718315389 # B[787, [16, 4, 2, 4], [28, 5, 3, 8]] - 0.00102265649585190407 # B[788, [16, 4, 2, 4], [29, 5, 4, 5]] - -0.000348239317084679881 # B[789, [16, 4, 2, 4], [30, 5, 4, 7]] - -0.00394431438420023671 # B[790, [16, 4, 2, 4], [31, 5, 5, 6]] - -0.00362914461095884553 # B[791, [16, 4, 2, 4], [32, 5, 5, 8]] - 0.000172019923347470349 # B[792, [16, 4, 2, 4], [33, 6, 0, 6]] - -0.000316455135754767445 # B[793, [16, 4, 2, 4], [34, 6, 1, 7]] - 0.00107098215861984453 # B[794, [16, 4, 2, 4], [35, 6, 2, 6]] - -0.000907131668137324478 # B[795, [16, 4, 2, 4], [36, 6, 2, 8]] - -0.000367695081353409058 # B[796, [16, 4, 2, 4], [37, 6, 3, 7]] - 0.00181370580350630889 # B[797, [16, 4, 2, 4], [38, 6, 4, 6]] - 0.000820930060826967692 # B[798, [16, 4, 2, 4], [39, 6, 4, 8]] - -0.00466238776474962348 # B[799, [16, 4, 2, 4], [40, 6, 5, 7]] - -0.0024305728850557008 # B[800, [16, 4, 2, 4], [41, 6, 6, 6]] - -0.00165013696151081928 # B[801, [16, 4, 2, 4], [42, 6, 6, 8]] - 0.000760058338755045804 # B[802, [16, 4, 2, 4], [43, 7, 0, 7]] - -0.00203289214112462729 # B[803, [16, 4, 2, 4], [44, 7, 1, 8]] - -0.00103057221789182719 # B[804, [16, 4, 2, 4], [45, 7, 2, 7]] - 0.00188720556649034019 # B[805, [16, 4, 2, 4], [46, 7, 3, 8]] - -0.000348979964538542048 # B[806, [16, 4, 2, 4], [47, 7, 4, 7]] - -0.00595514004121479486 # B[807, [16, 4, 2, 4], [48, 7, 5, 8]] - -0.00122307692783891336 # B[808, [16, 4, 2, 4], [49, 7, 6, 7]] - -0.00161626528708522232 # B[809, [16, 4, 2, 4], [50, 7, 7, 8]] - 0.000683658453003721522 # B[810, [16, 4, 2, 4], [51, 8, 0, 8]] - 0.000169503544911074264 # B[811, [16, 4, 2, 4], [52, 8, 2, 8]] - 0.00163132840171071117 # B[812, [16, 4, 2, 4], [53, 8, 4, 8]] - -0.000633742642666999118 # B[813, [16, 4, 2, 4], [54, 8, 6, 8]] - -0.000861029784191980584 # B[814, [16, 4, 2, 4], [55, 8, 8, 8]] - 0.0101724317893582689 # B[815, [17, 4, 2, 6], [17, 4, 2, 6]] - 0.00963074903115390332 # B[816, [17, 4, 2, 6], [18, 4, 3, 5]] - 0.00792776812488414986 # B[817, [17, 4, 2, 6], [19, 4, 3, 7]] - 0.00129789596639547263 # B[818, [17, 4, 2, 6], [20, 4, 4, 4]] - 0.0025280260724625768 # B[819, [17, 4, 2, 6], [21, 4, 4, 6]] - -0.00130604081814601758 # B[820, [17, 4, 2, 6], [22, 4, 4, 8]] - 0.00061656245411057832 # B[821, [17, 4, 2, 6], [23, 5, 0, 5]] - 0.00256026791937838134 # B[822, [17, 4, 2, 6], [24, 5, 1, 6]] - 0.00833728674660196879 # B[823, [17, 4, 2, 6], [25, 5, 2, 5]] - 0.00819332084025456604 # B[824, [17, 4, 2, 6], [26, 5, 2, 7]] - 0.00199258058679730159 # B[825, [17, 4, 2, 6], [27, 5, 3, 6]] - -0.00235687406293394464 # B[826, [17, 4, 2, 6], [28, 5, 3, 8]] - 0.00172306590551023903 # B[827, [17, 4, 2, 6], [29, 5, 4, 5]] - 0.00273320921325834404 # B[828, [17, 4, 2, 6], [30, 5, 4, 7]] - 0.00124490813870011289 # B[829, [17, 4, 2, 6], [31, 5, 5, 6]] - -0.00239829497882970916 # B[830, [17, 4, 2, 6], [32, 5, 5, 8]] - 0.000403489881901454572 # B[831, [17, 4, 2, 6], [33, 6, 0, 6]] - 0.0115977289566935714 # B[832, [17, 4, 2, 6], [34, 6, 1, 7]] - 0.00631330244272786285 # B[833, [17, 4, 2, 6], [35, 6, 2, 6]] - 0.00745951676374975552 # B[834, [17, 4, 2, 6], [36, 6, 2, 8]] - 0.00129555462014044158 # B[835, [17, 4, 2, 6], [37, 6, 3, 7]] - 0.0031708889242759988 # B[836, [17, 4, 2, 6], [38, 6, 4, 6]] - 0.00314059501950873093 # B[837, [17, 4, 2, 6], [39, 6, 4, 8]] - -0.00157311519106628078 # B[838, [17, 4, 2, 6], [40, 6, 5, 7]] - -0.000535633835711041804 # B[839, [17, 4, 2, 6], [41, 6, 6, 6]] - -0.00106218347026977491 # B[840, [17, 4, 2, 6], [42, 6, 6, 8]] - 0.00171130648037900839 # B[841, [17, 4, 2, 6], [43, 7, 0, 7]] - 0.00318381348777509654 # B[842, [17, 4, 2, 6], [44, 7, 1, 8]] - 0.00121186975917000981 # B[843, [17, 4, 2, 6], [45, 7, 2, 7]] - -0.00505226933268299559 # B[844, [17, 4, 2, 6], [46, 7, 3, 8]] - 0.000505489038324865442 # B[845, [17, 4, 2, 6], [47, 7, 4, 7]] - -0.00260650572816220009 # B[846, [17, 4, 2, 6], [48, 7, 5, 8]] - -0.00458388666826989831 # B[847, [17, 4, 2, 6], [49, 7, 6, 7]] - -0.0030323259618317824 # B[848, [17, 4, 2, 6], [50, 7, 7, 8]] - 0.000919810997489799165 # B[849, [17, 4, 2, 6], [51, 8, 0, 8]] - 0.00153843620323466154 # B[850, [17, 4, 2, 6], [52, 8, 2, 8]] - 0.00177452104337356975 # B[851, [17, 4, 2, 6], [53, 8, 4, 8]] - -0.00133363365246129796 # B[852, [17, 4, 2, 6], [54, 8, 6, 8]] - 0.000497168699576265929 # B[853, [17, 4, 2, 6], [55, 8, 8, 8]] - 0.00916493227652732945 # B[854, [18, 4, 3, 5], [18, 4, 3, 5]] - 0.00662893191875722591 # B[855, [18, 4, 3, 5], [19, 4, 3, 7]] - 0.00102473567933248147 # B[856, [18, 4, 3, 5], [20, 4, 4, 4]] - 0.000661293664462594619 # B[857, [18, 4, 3, 5], [21, 4, 4, 6]] - 0.00302383517430961438 # B[858, [18, 4, 3, 5], [22, 4, 4, 8]] - 0.00182134236384280147 # B[859, [18, 4, 3, 5], [23, 5, 0, 5]] - 0.00481003527044247467 # B[860, [18, 4, 3, 5], [24, 5, 1, 6]] - 0.00472221587821478311 # B[861, [18, 4, 3, 5], [25, 5, 2, 5]] - 0.00204855894682247092 # B[862, [18, 4, 3, 5], [26, 5, 2, 7]] - 0.00108437129165206425 # B[863, [18, 4, 3, 5], [27, 5, 3, 6]] - 0.000188071259560827417 # B[864, [18, 4, 3, 5], [28, 5, 3, 8]] - 0.000402244806083140727 # B[865, [18, 4, 3, 5], [29, 5, 4, 5]] - 0.00350511561101824257 # B[866, [18, 4, 3, 5], [30, 5, 4, 7]] - -0.00196731170271619883 # B[867, [18, 4, 3, 5], [31, 5, 5, 6]] - -0.000854471064769226317 # B[868, [18, 4, 3, 5], [32, 5, 5, 8]] - 0.00163753590726098495 # B[869, [18, 4, 3, 5], [33, 6, 0, 6]] - 0.00678767470498069323 # B[870, [18, 4, 3, 5], [34, 6, 1, 7]] - 0.00671898362129526739 # B[871, [18, 4, 3, 5], [35, 6, 2, 6]] - 0.00504150139406711259 # B[872, [18, 4, 3, 5], [36, 6, 2, 8]] - -0.00150058947564556469 # B[873, [18, 4, 3, 5], [37, 6, 3, 7]] - 0.00126561580055304518 # B[874, [18, 4, 3, 5], [38, 6, 4, 6]] - -0.000556565865268397481 # B[875, [18, 4, 3, 5], [39, 6, 4, 8]] - -0.00527488386402661519 # B[876, [18, 4, 3, 5], [40, 6, 5, 7]] - -0.00214157468754809163 # B[877, [18, 4, 3, 5], [41, 6, 6, 6]] - -0.0020431148178264337 # B[878, [18, 4, 3, 5], [42, 6, 6, 8]] - 0.00142704628054338232 # B[879, [18, 4, 3, 5], [43, 7, 0, 7]] - 0.00368882624306161085 # B[880, [18, 4, 3, 5], [44, 7, 1, 8]] - -0.000742447358153045661 # B[881, [18, 4, 3, 5], [45, 7, 2, 7]] - -0.00158678830901623838 # B[882, [18, 4, 3, 5], [46, 7, 3, 8]] - -0.00107876302160130055 # B[883, [18, 4, 3, 5], [47, 7, 4, 7]] - -0.00701537311445033646 # B[884, [18, 4, 3, 5], [48, 7, 5, 8]] - -0.00184801443295596127 # B[885, [18, 4, 3, 5], [49, 7, 6, 7]] - -0.00127678697871524667 # B[886, [18, 4, 3, 5], [50, 7, 7, 8]] - 0.00105641109188138113 # B[887, [18, 4, 3, 5], [51, 8, 0, 8]] - 0.000718098622203026428 # B[888, [18, 4, 3, 5], [52, 8, 2, 8]] - 0.00219486004289275692 # B[889, [18, 4, 3, 5], [53, 8, 4, 8]] - -0.00158748993130468905 # B[890, [18, 4, 3, 5], [54, 8, 6, 8]] - -0.00105128398142791644 # B[891, [18, 4, 3, 5], [55, 8, 8, 8]] - -0.00705876763301777586 # B[892, [19, 4, 3, 7], [19, 4, 3, 7]] - 0.00377186011578763136 # B[893, [19, 4, 3, 7], [20, 4, 4, 4]] - 0.00351225097737749986 # B[894, [19, 4, 3, 7], [21, 4, 4, 6]] - -0.00323798036048509805 # B[895, [19, 4, 3, 7], [22, 4, 4, 8]] - 0.00126225430824061444 # B[896, [19, 4, 3, 7], [23, 5, 0, 5]] - -0.00132900767543010258 # B[897, [19, 4, 3, 7], [24, 5, 1, 6]] - 0.000212743875668733318 # B[898, [19, 4, 3, 7], [25, 5, 2, 5]] - -8.93559293989563963e-05 # B[899, [19, 4, 3, 7], [26, 5, 2, 7]] - 0.00401415269432878544 # B[900, [19, 4, 3, 7], [27, 5, 3, 6]] - -0.00422923196125859352 # B[901, [19, 4, 3, 7], [28, 5, 3, 8]] - 0.00252733635050122335 # B[902, [19, 4, 3, 7], [29, 5, 4, 5]] - -0.00020969110581340808 # B[903, [19, 4, 3, 7], [30, 5, 4, 7]] - -0.000969147769818896193 # B[904, [19, 4, 3, 7], [31, 5, 5, 6]] - -0.00249817386761041864 # B[905, [19, 4, 3, 7], [32, 5, 5, 8]] - 7.71120512828363247e-05 # B[906, [19, 4, 3, 7], [33, 6, 0, 6]] - 0.00560302176075209817 # B[907, [19, 4, 3, 7], [34, 6, 1, 7]] - 0.00342833731167378752 # B[908, [19, 4, 3, 7], [35, 6, 2, 6]] - 0.00116548365936076578 # B[909, [19, 4, 3, 7], [36, 6, 2, 8]] - 0.00499590856190199745 # B[910, [19, 4, 3, 7], [37, 6, 3, 7]] - 0.00391644837067879614 # B[911, [19, 4, 3, 7], [38, 6, 4, 6]] - 0.00116606811408420229 # B[912, [19, 4, 3, 7], [39, 6, 4, 8]] - -0.000563820914290556058 # B[913, [19, 4, 3, 7], [40, 6, 5, 7]] - -0.000251464925992161276 # B[914, [19, 4, 3, 7], [41, 6, 6, 6]] - -0.000718753250305587815 # B[915, [19, 4, 3, 7], [42, 6, 6, 8]] - 0.000453024387943248494 # B[916, [19, 4, 3, 7], [43, 7, 0, 7]] - -0.00146422451962339994 # B[917, [19, 4, 3, 7], [44, 7, 1, 8]] - 0.00271974781140060795 # B[918, [19, 4, 3, 7], [45, 7, 2, 7]] - 0.00151707017829591159 # B[919, [19, 4, 3, 7], [46, 7, 3, 8]] - 0.00202377896423465691 # B[920, [19, 4, 3, 7], [47, 7, 4, 7]] - -0.00131185948123999779 # B[921, [19, 4, 3, 7], [48, 7, 5, 8]] - 0.000239464941185672797 # B[922, [19, 4, 3, 7], [49, 7, 6, 7]] - -0.000667571478871501964 # B[923, [19, 4, 3, 7], [50, 7, 7, 8]] - 0.000666789360176615192 # B[924, [19, 4, 3, 7], [51, 8, 0, 8]] - 0.00179543252151156355 # B[925, [19, 4, 3, 7], [52, 8, 2, 8]] - 0.000954396542852647967 # B[926, [19, 4, 3, 7], [53, 8, 4, 8]] - 0.000593331439814590023 # B[927, [19, 4, 3, 7], [54, 8, 6, 8]] - -0.000292670120459602445 # B[928, [19, 4, 3, 7], [55, 8, 8, 8]] - -0.000303353861178074294 # B[929, [20, 4, 4, 4], [20, 4, 4, 4]] - -6.41585335468541906e-05 # B[930, [20, 4, 4, 4], [21, 4, 4, 6]] - 0.00145464895340288725 # B[931, [20, 4, 4, 4], [22, 4, 4, 8]] - 0.000557677559397141802 # B[932, [20, 4, 4, 4], [23, 5, 0, 5]] - 0.00214733001664968188 # B[933, [20, 4, 4, 4], [24, 5, 1, 6]] - 0.000196804226194771757 # B[934, [20, 4, 4, 4], [25, 5, 2, 5]] - 0.00169621771662652795 # B[935, [20, 4, 4, 4], [26, 5, 2, 7]] - -0.00126951106424718924 # B[936, [20, 4, 4, 4], [27, 5, 3, 6]] - 0.00156201190059711802 # B[937, [20, 4, 4, 4], [28, 5, 3, 8]] - -0.000188505112089858498 # B[938, [20, 4, 4, 4], [29, 5, 4, 5]] - 0.00101485096974841295 # B[939, [20, 4, 4, 4], [30, 5, 4, 7]] - -0.000254023094278113288 # B[940, [20, 4, 4, 4], [31, 5, 5, 6]] - -0.000332430225508446864 # B[941, [20, 4, 4, 4], [32, 5, 5, 8]] - 0.000393172799404761797 # B[942, [20, 4, 4, 4], [33, 6, 0, 6]] - -0.000945851456653874594 # B[943, [20, 4, 4, 4], [34, 6, 1, 7]] - 0.000937118523093692299 # B[944, [20, 4, 4, 4], [35, 6, 2, 6]] - 0.00108463610451345858 # B[945, [20, 4, 4, 4], [36, 6, 2, 8]] - -0.00167878968186336089 # B[946, [20, 4, 4, 4], [37, 6, 3, 7]] - 0.000109649976457827647 # B[947, [20, 4, 4, 4], [38, 6, 4, 6]] - 0.000205908523746248934 # B[948, [20, 4, 4, 4], [39, 6, 4, 8]] - -0.000952641271225448949 # B[949, [20, 4, 4, 4], [40, 6, 5, 7]] - -0.000386842165161269298 # B[950, [20, 4, 4, 4], [41, 6, 6, 6]] - -0.000662992329463731739 # B[951, [20, 4, 4, 4], [42, 6, 6, 8]] - 0.000368522676488847178 # B[952, [20, 4, 4, 4], [43, 7, 0, 7]] - -0.000181924614212486402 # B[953, [20, 4, 4, 4], [44, 7, 1, 8]] - -0.00119374010493299761 # B[954, [20, 4, 4, 4], [45, 7, 2, 7]] - -0.000775398926021152179 # B[955, [20, 4, 4, 4], [46, 7, 3, 8]] - -0.000670782103704289923 # B[956, [20, 4, 4, 4], [47, 7, 4, 7]] - -0.00192682764111087456 # B[957, [20, 4, 4, 4], [48, 7, 5, 8]] - -0.000648663865567958298 # B[958, [20, 4, 4, 4], [49, 7, 6, 7]] - -0.000387954189232417312 # B[959, [20, 4, 4, 4], [50, 7, 7, 8]] - 0.000302370648048068055 # B[960, [20, 4, 4, 4], [51, 8, 0, 8]] - -0.00085980088667597307 # B[961, [20, 4, 4, 4], [52, 8, 2, 8]] - 0.000568399123124077588 # B[962, [20, 4, 4, 4], [53, 8, 4, 8]] - -0.000482151590861096269 # B[963, [20, 4, 4, 4], [54, 8, 6, 8]] - -0.000405828455879983507 # B[964, [20, 4, 4, 4], [55, 8, 8, 8]] - 0.00165997230068267755 # B[965, [21, 4, 4, 6], [21, 4, 4, 6]] - 0.000963896255597472551 # B[966, [21, 4, 4, 6], [22, 4, 4, 8]] - 0.0002094521100325826 # B[967, [21, 4, 4, 6], [23, 5, 0, 5]] - 0.000534879644705995444 # B[968, [21, 4, 4, 6], [24, 5, 1, 6]] - 0.00292236533791157905 # B[969, [21, 4, 4, 6], [25, 5, 2, 5]] - 0.00151524368635043427 # B[970, [21, 4, 4, 6], [26, 5, 2, 7]] - -0.00101689007388491501 # B[971, [21, 4, 4, 6], [27, 5, 3, 6]] - 0.000738459806183821427 # B[972, [21, 4, 4, 6], [28, 5, 3, 8]] - 0.00148643764242684627 # B[973, [21, 4, 4, 6], [29, 5, 4, 5]] - 0.0011556877894129472 # B[974, [21, 4, 4, 6], [30, 5, 4, 7]] - -0.000208381440186615127 # B[975, [21, 4, 4, 6], [31, 5, 5, 6]] - -0.00143743030752817389 # B[976, [21, 4, 4, 6], [32, 5, 5, 8]] - -0.00016600302639456152 # B[977, [21, 4, 4, 6], [33, 6, 0, 6]] - 0.00172160125073629253 # B[978, [21, 4, 4, 6], [34, 6, 1, 7]] - 0.00344812165058533751 # B[979, [21, 4, 4, 6], [35, 6, 2, 6]] - 0.000544104512334869089 # B[980, [21, 4, 4, 6], [36, 6, 2, 8]] - -0.00182558144376257503 # B[981, [21, 4, 4, 6], [37, 6, 3, 7]] - 0.00101065848983370246 # B[982, [21, 4, 4, 6], [38, 6, 4, 6]] - 0.00103400096073465869 # B[983, [21, 4, 4, 6], [39, 6, 4, 8]] - -0.000235944095127582111 # B[984, [21, 4, 4, 6], [40, 6, 5, 7]] - 0.000154580830205655606 # B[985, [21, 4, 4, 6], [41, 6, 6, 6]] - -0.000488680460493023505 # B[986, [21, 4, 4, 6], [42, 6, 6, 8]] - 3.83739714257189113e-05 # B[987, [21, 4, 4, 6], [43, 7, 0, 7]] - -0.000275037336268196993 # B[988, [21, 4, 4, 6], [44, 7, 1, 8]] - 0.0017878021157122859 # B[989, [21, 4, 4, 6], [45, 7, 2, 7]] - -0.00110857713686632331 # B[990, [21, 4, 4, 6], [46, 7, 3, 8]] - -0.000126074852562767237 # B[991, [21, 4, 4, 6], [47, 7, 4, 7]] - -0.00125862858469075189 # B[992, [21, 4, 4, 6], [48, 7, 5, 8]] - -0.000277638160776805254 # B[993, [21, 4, 4, 6], [49, 7, 6, 7]] - 0.000163335859971639602 # B[994, [21, 4, 4, 6], [50, 7, 7, 8]] - 0.000151747507838979889 # B[995, [21, 4, 4, 6], [51, 8, 0, 8]] - 0.00156180455186682998 # B[996, [21, 4, 4, 6], [52, 8, 2, 8]] - 0.00112614353705531994 # B[997, [21, 4, 4, 6], [53, 8, 4, 8]] - -0.000376140365477903652 # B[998, [21, 4, 4, 6], [54, 8, 6, 8]] - -0.000378786757414536351 # B[999, [21, 4, 4, 6], [55, 8, 8, 8]] - -0.00186381195965971969 # B[1000, [22, 4, 4, 8], [22, 4, 4, 8]] - 0.000334060235611270684 # B[1001, [22, 4, 4, 8], [23, 5, 0, 5]] - -0.000182139490643212255 # B[1002, [22, 4, 4, 8], [24, 5, 1, 6]] - -0.000866414678376911532 # B[1003, [22, 4, 4, 8], [25, 5, 2, 5]] - -0.000713836573909394211 # B[1004, [22, 4, 4, 8], [26, 5, 2, 7]] - 0.00340359387460056721 # B[1005, [22, 4, 4, 8], [27, 5, 3, 6]] - -0.0025631762232975969 # B[1006, [22, 4, 4, 8], [28, 5, 3, 8]] - 0.00154837338005092001 # B[1007, [22, 4, 4, 8], [29, 5, 4, 5]] - -0.000713785025005329171 # B[1008, [22, 4, 4, 8], [30, 5, 4, 7]] - -6.17852167664190155e-06 # B[1009, [22, 4, 4, 8], [31, 5, 5, 6]] - -0.000925788250245492385 # B[1010, [22, 4, 4, 8], [32, 5, 5, 8]] - -0.000220618203180443506 # B[1011, [22, 4, 4, 8], [33, 6, 0, 6]] - 0.00158760304062654546 # B[1012, [22, 4, 4, 8], [34, 6, 1, 7]] - -0.00201296543384867077 # B[1013, [22, 4, 4, 8], [35, 6, 2, 6]] - -0.000153111573438037551 # B[1014, [22, 4, 4, 8], [36, 6, 2, 8]] - 0.001936342943994784 # B[1015, [22, 4, 4, 8], [37, 6, 3, 7]] - 0.0014724303902098404 # B[1016, [22, 4, 4, 8], [38, 6, 4, 6]] - 0.000412977919829218137 # B[1017, [22, 4, 4, 8], [39, 6, 4, 8]] - 0.000243129124011996767 # B[1018, [22, 4, 4, 8], [40, 6, 5, 7]] - 0.000433542078585167322 # B[1019, [22, 4, 4, 8], [41, 6, 6, 6]] - 5.87712210821707964e-05 # B[1020, [22, 4, 4, 8], [42, 6, 6, 8]] - -2.13873587015245281e-05 # B[1021, [22, 4, 4, 8], [43, 7, 0, 7]] - -0.00121671500578664389 # B[1022, [22, 4, 4, 8], [44, 7, 1, 8]] - 0.00185443425860575776 # B[1023, [22, 4, 4, 8], [45, 7, 2, 7]] - 0.00153976874095648406 # B[1024, [22, 4, 4, 8], [46, 7, 3, 8]] - 0.00100585852984078766 # B[1025, [22, 4, 4, 8], [47, 7, 4, 7]] - 0.000146502145157426621 # B[1026, [22, 4, 4, 8], [48, 7, 5, 8]] - 0.00026572798098887726 # B[1027, [22, 4, 4, 8], [49, 7, 6, 7]] - 0.000239744529446223043 # B[1028, [22, 4, 4, 8], [50, 7, 7, 8]] - 3.13331575558552233e-05 # B[1029, [22, 4, 4, 8], [51, 8, 0, 8]] - 0.0005761629631739415 # B[1030, [22, 4, 4, 8], [52, 8, 2, 8]] - 0.00020451472183747807 # B[1031, [22, 4, 4, 8], [53, 8, 4, 8]] - 0.000761501707699011737 # B[1032, [22, 4, 4, 8], [54, 8, 6, 8]] - 4.7608269104475881e-05 # B[1033, [22, 4, 4, 8], [55, 8, 8, 8]] - 0.00010288893231941848 # B[1034, [23, 5, 0, 5], [23, 5, 0, 5]] - -0.000598160679614365143 # B[1035, [23, 5, 0, 5], [24, 5, 1, 6]] - -0.000125600887517359969 # B[1036, [23, 5, 0, 5], [25, 5, 2, 5]] - -0.000541602347577959872 # B[1037, [23, 5, 0, 5], [26, 5, 2, 7]] - 0.000138742295315047448 # B[1038, [23, 5, 0, 5], [27, 5, 3, 6]] - 0.000320496112291311641 # B[1039, [23, 5, 0, 5], [28, 5, 3, 8]] - 9.77076363189860464e-05 # B[1040, [23, 5, 0, 5], [29, 5, 4, 5]] - -0.00018519393057754574 # B[1041, [23, 5, 0, 5], [30, 5, 4, 7]] - -0.000314308790209320843 # B[1042, [23, 5, 0, 5], [31, 5, 5, 6]] - -2.03507196530547385e-05 # B[1043, [23, 5, 0, 5], [32, 5, 5, 8]] - -8.76692912155085935e-08 # B[1044, [23, 5, 0, 5], [33, 6, 0, 6]] - -0.000208914241663854874 # B[1045, [23, 5, 0, 5], [34, 6, 1, 7]] - 0.000289191305925793653 # B[1046, [23, 5, 0, 5], [35, 6, 2, 6]] - 0.000292827060287376498 # B[1047, [23, 5, 0, 5], [36, 6, 2, 8]] - -0.000195999965143696386 # B[1048, [23, 5, 0, 5], [37, 6, 3, 7]] - 0.000122837407081860615 # B[1049, [23, 5, 0, 5], [38, 6, 4, 6]] - 0.000238061673948679331 # B[1050, [23, 5, 0, 5], [39, 6, 4, 8]] - 6.23458911314621333e-06 # B[1051, [23, 5, 0, 5], [40, 6, 5, 7]] - 0.000153645644536796327 # B[1052, [23, 5, 0, 5], [41, 6, 6, 6]] - 0.000208144485879115104 # B[1053, [23, 5, 0, 5], [42, 6, 6, 8]] - 0.000107382317423423967 # B[1054, [23, 5, 0, 5], [43, 7, 0, 7]] - -3.16437877474207152e-05 # B[1055, [23, 5, 0, 5], [44, 7, 1, 8]] - 5.2567890411161361e-05 # B[1056, [23, 5, 0, 5], [45, 7, 2, 7]] - -0.000407365287815795313 # B[1057, [23, 5, 0, 5], [46, 7, 3, 8]] - -0.000277007442936893014 # B[1058, [23, 5, 0, 5], [47, 7, 4, 7]] - -0.000163960409271388802 # B[1059, [23, 5, 0, 5], [48, 7, 5, 8]] - -0.00018222236229294142 # B[1060, [23, 5, 0, 5], [49, 7, 6, 7]] - -8.93725149996096868e-05 # B[1061, [23, 5, 0, 5], [50, 7, 7, 8]] - -4.59835267753172516e-05 # B[1062, [23, 5, 0, 5], [51, 8, 0, 8]] - -3.00980967951527262e-05 # B[1063, [23, 5, 0, 5], [52, 8, 2, 8]] - -0.00011786089545340328 # B[1064, [23, 5, 0, 5], [53, 8, 4, 8]] - 6.24840877215676604e-05 # B[1065, [23, 5, 0, 5], [54, 8, 6, 8]] - 0.000151333518371397913 # B[1066, [23, 5, 0, 5], [55, 8, 8, 8]] - -0.00373509601310103353 # B[1067, [24, 5, 1, 6], [24, 5, 1, 6]] - 0.00250350668234289742 # B[1068, [24, 5, 1, 6], [25, 5, 2, 5]] - -0.00141763987470412255 # B[1069, [24, 5, 1, 6], [26, 5, 2, 7]] - -0.000458490741576836162 # B[1070, [24, 5, 1, 6], [27, 5, 3, 6]] - 0.000169432811229417585 # B[1071, [24, 5, 1, 6], [28, 5, 3, 8]] - -0.000531768848310092699 # B[1072, [24, 5, 1, 6], [29, 5, 4, 5]] - 0.0019269207337581605 # B[1073, [24, 5, 1, 6], [30, 5, 4, 7]] - 0.000623468915929115824 # B[1074, [24, 5, 1, 6], [31, 5, 5, 6]] - 0.000262459747020924762 # B[1075, [24, 5, 1, 6], [32, 5, 5, 8]] - 0.000319464830252011445 # B[1076, [24, 5, 1, 6], [33, 6, 0, 6]] - 0.00250974732963905444 # B[1077, [24, 5, 1, 6], [34, 6, 1, 7]] - 0.00423653007687384807 # B[1078, [24, 5, 1, 6], [35, 6, 2, 6]] - 0.00144771358428595707 # B[1079, [24, 5, 1, 6], [36, 6, 2, 8]] - 0.00255496505633429419 # B[1080, [24, 5, 1, 6], [37, 6, 3, 7]] - -0.000923899857380450218 # B[1081, [24, 5, 1, 6], [38, 6, 4, 6]] - -0.000308666389289608337 # B[1082, [24, 5, 1, 6], [39, 6, 4, 8]] - 0.00222537659577300671 # B[1083, [24, 5, 1, 6], [40, 6, 5, 7]] - -0.00107541311587263343 # B[1084, [24, 5, 1, 6], [41, 6, 6, 6]] - -0.00278767944085371068 # B[1085, [24, 5, 1, 6], [42, 6, 6, 8]] - -0.000867530969177243705 # B[1086, [24, 5, 1, 6], [43, 7, 0, 7]] - 0.00357297895621819196 # B[1087, [24, 5, 1, 6], [44, 7, 1, 8]] - 0.00383976572090019216 # B[1088, [24, 5, 1, 6], [45, 7, 2, 7]] - -0.000580234942856992786 # B[1089, [24, 5, 1, 6], [46, 7, 3, 8]] - 0.00102888910081111798 # B[1090, [24, 5, 1, 6], [47, 7, 4, 7]] - 0.00132107614311613355 # B[1091, [24, 5, 1, 6], [48, 7, 5, 8]] - 0.00101848252621374036 # B[1092, [24, 5, 1, 6], [49, 7, 6, 7]] - 0.00160018234143227862 # B[1093, [24, 5, 1, 6], [50, 7, 7, 8]] - -5.52824024903572631e-05 # B[1094, [24, 5, 1, 6], [51, 8, 0, 8]] - 4.59186780197786033e-05 # B[1095, [24, 5, 1, 6], [52, 8, 2, 8]] - -0.000153436254581188554 # B[1096, [24, 5, 1, 6], [53, 8, 4, 8]] - -0.000546750998621967597 # B[1097, [24, 5, 1, 6], [54, 8, 6, 8]] - 0.000595956738118895348 # B[1098, [24, 5, 1, 6], [55, 8, 8, 8]] - 0.0083807047595118693 # B[1099, [25, 5, 2, 5], [25, 5, 2, 5]] - -0.000170544318645505719 # B[1100, [25, 5, 2, 5], [26, 5, 2, 7]] - 0.00235544441902155004 # B[1101, [25, 5, 2, 5], [27, 5, 3, 6]] - -0.00340197827063909962 # B[1102, [25, 5, 2, 5], [28, 5, 3, 8]] - 0.00311335525578198104 # B[1103, [25, 5, 2, 5], [29, 5, 4, 5]] - 0.00185214714164834123 # B[1104, [25, 5, 2, 5], [30, 5, 4, 7]] - -0.00328905913600528992 # B[1105, [25, 5, 2, 5], [31, 5, 5, 6]] - -0.00141866010082636025 # B[1106, [25, 5, 2, 5], [32, 5, 5, 8]] - 0.000176317033907393006 # B[1107, [25, 5, 2, 5], [33, 6, 0, 6]] - 0.00648328973805229608 # B[1108, [25, 5, 2, 5], [34, 6, 1, 7]] - 4.8980528358618259e-05 # B[1109, [25, 5, 2, 5], [35, 6, 2, 6]] - -0.00616971046300731144 # B[1110, [25, 5, 2, 5], [36, 6, 2, 8]] - -0.00135942372726050205 # B[1111, [25, 5, 2, 5], [37, 6, 3, 7]] - 0.000572735024796908881 # B[1112, [25, 5, 2, 5], [38, 6, 4, 6]] - -0.00229752149848994405 # B[1113, [25, 5, 2, 5], [39, 6, 4, 8]] - 0.0003485310815041524 # B[1114, [25, 5, 2, 5], [40, 6, 5, 7]] - -0.0011437361439647427 # B[1115, [25, 5, 2, 5], [41, 6, 6, 6]] - -0.000604819873822432311 # B[1116, [25, 5, 2, 5], [42, 6, 6, 8]] - 9.06237770597643696e-05 # B[1117, [25, 5, 2, 5], [43, 7, 0, 7]] - -0.000382141545017884894 # B[1118, [25, 5, 2, 5], [44, 7, 1, 8]] - -0.000842464094047663554 # B[1119, [25, 5, 2, 5], [45, 7, 2, 7]] - 0.000461973830441065811 # B[1120, [25, 5, 2, 5], [46, 7, 3, 8]] - 2.86192620363814355e-06 # B[1121, [25, 5, 2, 5], [47, 7, 4, 7]] - -0.0023436531447123838 # B[1122, [25, 5, 2, 5], [48, 7, 5, 8]] - 0.00134025173860287308 # B[1123, [25, 5, 2, 5], [49, 7, 6, 7]] - -0.000520013981518205846 # B[1124, [25, 5, 2, 5], [50, 7, 7, 8]] - 0.000515782740310496285 # B[1125, [25, 5, 2, 5], [51, 8, 0, 8]] - 0.00421651313615256564 # B[1126, [25, 5, 2, 5], [52, 8, 2, 8]] - 0.000755327719218409519 # B[1127, [25, 5, 2, 5], [53, 8, 4, 8]] - 0.000182937308412391315 # B[1128, [25, 5, 2, 5], [54, 8, 6, 8]] - 8.10383680097163071e-05 # B[1129, [25, 5, 2, 5], [55, 8, 8, 8]] - 0.000177735296666065024 # B[1130, [26, 5, 2, 7], [26, 5, 2, 7]] - -0.000642334677407747565 # B[1131, [26, 5, 2, 7], [27, 5, 3, 6]] - 0.000205172894139061396 # B[1132, [26, 5, 2, 7], [28, 5, 3, 8]] - -0.000537004220752698019 # B[1133, [26, 5, 2, 7], [29, 5, 4, 5]] - 5.14115941491347442e-05 # B[1134, [26, 5, 2, 7], [30, 5, 4, 7]] - 0.000417673445165051005 # B[1135, [26, 5, 2, 7], [31, 5, 5, 6]] - 0.00158446769775330391 # B[1136, [26, 5, 2, 7], [32, 5, 5, 8]] - 0.00121383407410429606 # B[1137, [26, 5, 2, 7], [33, 6, 0, 6]] - -0.00111992976945914785 # B[1138, [26, 5, 2, 7], [34, 6, 1, 7]] - 0.00398972286341117699 # B[1139, [26, 5, 2, 7], [35, 6, 2, 6]] - 0.00454565411209783762 # B[1140, [26, 5, 2, 7], [36, 6, 2, 8]] - -0.00300928796618537761 # B[1141, [26, 5, 2, 7], [37, 6, 3, 7]] - -0.00280024702462813163 # B[1142, [26, 5, 2, 7], [38, 6, 4, 6]] - 0.00182097597359056305 # B[1143, [26, 5, 2, 7], [39, 6, 4, 8]] - 0.00247143387165752772 # B[1144, [26, 5, 2, 7], [40, 6, 5, 7]] - -0.00143698477566456435 # B[1145, [26, 5, 2, 7], [41, 6, 6, 6]] - -0.00105878554545993375 # B[1146, [26, 5, 2, 7], [42, 6, 6, 8]] - 0.000650619036842032747 # B[1147, [26, 5, 2, 7], [43, 7, 0, 7]] - 8.72947879012740853e-05 # B[1148, [26, 5, 2, 7], [44, 7, 1, 8]] - -0.0002084941102769855 # B[1149, [26, 5, 2, 7], [45, 7, 2, 7]] - -0.000924608969529588931 # B[1150, [26, 5, 2, 7], [46, 7, 3, 8]] - -0.000320719808114693777 # B[1151, [26, 5, 2, 7], [47, 7, 4, 7]] - 0.00241998856780361801 # B[1152, [26, 5, 2, 7], [48, 7, 5, 8]] - -0.00171923440812344827 # B[1153, [26, 5, 2, 7], [49, 7, 6, 7]] - -0.000301390241580377569 # B[1154, [26, 5, 2, 7], [50, 7, 7, 8]] - -6.37461557401481499e-05 # B[1155, [26, 5, 2, 7], [51, 8, 0, 8]] - 0.00161644303684405446 # B[1156, [26, 5, 2, 7], [52, 8, 2, 8]] - 0.00104379414920739667 # B[1157, [26, 5, 2, 7], [53, 8, 4, 8]] - -0.00119795702190159808 # B[1158, [26, 5, 2, 7], [54, 8, 6, 8]] - 0.000604059138156293803 # B[1159, [26, 5, 2, 7], [55, 8, 8, 8]] - 0.000513459633959805622 # B[1160, [27, 5, 3, 6], [27, 5, 3, 6]] - -0.000172334638360790993 # B[1161, [27, 5, 3, 6], [28, 5, 3, 8]] - 1.60719061511648345e-05 # B[1162, [27, 5, 3, 6], [29, 5, 4, 5]] - 0.00440279299288983371 # B[1163, [27, 5, 3, 6], [30, 5, 4, 7]] - 0.000549761981236742206 # B[1164, [27, 5, 3, 6], [31, 5, 5, 6]] - 0.000424619689378998542 # B[1165, [27, 5, 3, 6], [32, 5, 5, 8]] - 0.000247367934895610653 # B[1166, [27, 5, 3, 6], [33, 6, 0, 6]] - 0.00400569055534595944 # B[1167, [27, 5, 3, 6], [34, 6, 1, 7]] - 0.00274378194299987679 # B[1168, [27, 5, 3, 6], [35, 6, 2, 6]] - 0.00368141326251353665 # B[1169, [27, 5, 3, 6], [36, 6, 2, 8]] - 0.00160469169395054817 # B[1170, [27, 5, 3, 6], [37, 6, 3, 7]] - 0.000105807739550402985 # B[1171, [27, 5, 3, 6], [38, 6, 4, 6]] - -0.000682801438033796976 # B[1172, [27, 5, 3, 6], [39, 6, 4, 8]] - -0.00121964915110857504 # B[1173, [27, 5, 3, 6], [40, 6, 5, 7]] - -0.000817665263990522556 # B[1174, [27, 5, 3, 6], [41, 6, 6, 6]] - 0.000534593784435832137 # B[1175, [27, 5, 3, 6], [42, 6, 6, 8]] - 0.000116542343021167755 # B[1176, [27, 5, 3, 6], [43, 7, 0, 7]] - 0.00351267154418699948 # B[1177, [27, 5, 3, 6], [44, 7, 1, 8]] - -0.00189934642995405814 # B[1178, [27, 5, 3, 6], [45, 7, 2, 7]] - 0.000751906974843792597 # B[1179, [27, 5, 3, 6], [46, 7, 3, 8]] - -0.000446808189773967301 # B[1180, [27, 5, 3, 6], [47, 7, 4, 7]] - -0.00324699511848197502 # B[1181, [27, 5, 3, 6], [48, 7, 5, 8]] - 2.53540837371335481e-05 # B[1182, [27, 5, 3, 6], [49, 7, 6, 7]] - 7.5273388360289073e-07 # B[1183, [27, 5, 3, 6], [50, 7, 7, 8]] - 0.00023346363571073725 # B[1184, [27, 5, 3, 6], [51, 8, 0, 8]] - 0.000490008984593369619 # B[1185, [27, 5, 3, 6], [52, 8, 2, 8]] - 0.000205260233742234413 # B[1186, [27, 5, 3, 6], [53, 8, 4, 8]] - -7.84984665939646165e-05 # B[1187, [27, 5, 3, 6], [54, 8, 6, 8]] - -0.000299454037036409743 # B[1188, [27, 5, 3, 6], [55, 8, 8, 8]] - -0.00411961786705090406 # B[1189, [28, 5, 3, 8], [28, 5, 3, 8]] - 0.00256764268592788759 # B[1190, [28, 5, 3, 8], [29, 5, 4, 5]] - -0.000267820435572239945 # B[1191, [28, 5, 3, 8], [30, 5, 4, 7]] - 0.000545048575291992229 # B[1192, [28, 5, 3, 8], [31, 5, 5, 6]] - -0.000141236037433873154 # B[1193, [28, 5, 3, 8], [32, 5, 5, 8]] - -8.17647193563642016e-05 # B[1194, [28, 5, 3, 8], [33, 6, 0, 6]] - 0.00184594470809960887 # B[1195, [28, 5, 3, 8], [34, 6, 1, 7]] - 0.000715653691449843685 # B[1196, [28, 5, 3, 8], [35, 6, 2, 6]] - -0.000371782729873919304 # B[1197, [28, 5, 3, 8], [36, 6, 2, 8]] - 0.00184451560473704312 # B[1198, [28, 5, 3, 8], [37, 6, 3, 7]] - 0.00298992898894900189 # B[1199, [28, 5, 3, 8], [38, 6, 4, 6]] - 0.00087474408278464047 # B[1200, [28, 5, 3, 8], [39, 6, 4, 8]] - 0.00115889056554823421 # B[1201, [28, 5, 3, 8], [40, 6, 5, 7]] - -0.000209440071593354482 # B[1202, [28, 5, 3, 8], [41, 6, 6, 6]] - 0.000707847416081031772 # B[1203, [28, 5, 3, 8], [42, 6, 6, 8]] - 0.00025922895119332573 # B[1204, [28, 5, 3, 8], [43, 7, 0, 7]] - -0.00210744601505012327 # B[1205, [28, 5, 3, 8], [44, 7, 1, 8]] - -0.00187401632149015486 # B[1206, [28, 5, 3, 8], [45, 7, 2, 7]] - 0.000616682247583759391 # B[1207, [28, 5, 3, 8], [46, 7, 3, 8]] - 0.00142526179781785924 # B[1208, [28, 5, 3, 8], [47, 7, 4, 7]] - -9.1619163886703936e-06 # B[1209, [28, 5, 3, 8], [48, 7, 5, 8]] - -0.000300978843055903222 # B[1210, [28, 5, 3, 8], [49, 7, 6, 7]] - -0.000124034381208077554 # B[1211, [28, 5, 3, 8], [50, 7, 7, 8]] - 0.000249158311162858692 # B[1212, [28, 5, 3, 8], [51, 8, 0, 8]] - -0.000970252220622513538 # B[1213, [28, 5, 3, 8], [52, 8, 2, 8]] - 0.000840312328335843066 # B[1214, [28, 5, 3, 8], [53, 8, 4, 8]] - 0.000145361901756495965 # B[1215, [28, 5, 3, 8], [54, 8, 6, 8]] - 0.00013163551986085896 # B[1216, [28, 5, 3, 8], [55, 8, 8, 8]] - 0.00265810885844912576 # B[1217, [29, 5, 4, 5], [29, 5, 4, 5]] - 0.00191793603428468823 # B[1218, [29, 5, 4, 5], [30, 5, 4, 7]] - 0.000446118694394436605 # B[1219, [29, 5, 4, 5], [31, 5, 5, 6]] - -9.59445098255573559e-05 # B[1220, [29, 5, 4, 5], [32, 5, 5, 8]] - 0.000369255428727587043 # B[1221, [29, 5, 4, 5], [33, 6, 0, 6]] - -0.000553149628059141762 # B[1222, [29, 5, 4, 5], [34, 6, 1, 7]] - 0.00315275275750991242 # B[1223, [29, 5, 4, 5], [35, 6, 2, 6]] - 0.00138540352181828336 # B[1224, [29, 5, 4, 5], [36, 6, 2, 8]] - 0.000776256233303879162 # B[1225, [29, 5, 4, 5], [37, 6, 3, 7]] - 0.000594477884906325672 # B[1226, [29, 5, 4, 5], [38, 6, 4, 6]] - 0.000757712543509288586 # B[1227, [29, 5, 4, 5], [39, 6, 4, 8]] - -0.000917903532807641184 # B[1228, [29, 5, 4, 5], [40, 6, 5, 7]] - -0.000915313398456763742 # B[1229, [29, 5, 4, 5], [41, 6, 6, 6]] - -0.00116732293566375843 # B[1230, [29, 5, 4, 5], [42, 6, 6, 8]] - 0.000172432189541951719 # B[1231, [29, 5, 4, 5], [43, 7, 0, 7]] - 0.000845370011774060912 # B[1232, [29, 5, 4, 5], [44, 7, 1, 8]] - 0.00178029205661471915 # B[1233, [29, 5, 4, 5], [45, 7, 2, 7]] - 0.00129739636685697463 # B[1234, [29, 5, 4, 5], [46, 7, 3, 8]] - 0.000282865369400489564 # B[1235, [29, 5, 4, 5], [47, 7, 4, 7]] - -0.00178988233479955398 # B[1236, [29, 5, 4, 5], [48, 7, 5, 8]] - 0.00023603474784275949 # B[1237, [29, 5, 4, 5], [49, 7, 6, 7]] - -0.000461436431325358207 # B[1238, [29, 5, 4, 5], [50, 7, 7, 8]] - 0.000234131705926524103 # B[1239, [29, 5, 4, 5], [51, 8, 0, 8]] - 0.00216254821351878363 # B[1240, [29, 5, 4, 5], [52, 8, 2, 8]] - 0.000831658742681578439 # B[1241, [29, 5, 4, 5], [53, 8, 4, 8]] - -0.00046318901257626742 # B[1242, [29, 5, 4, 5], [54, 8, 6, 8]] - -0.000607580535321294163 # B[1243, [29, 5, 4, 5], [55, 8, 8, 8]] - 0.00158347719827001653 # B[1244, [30, 5, 4, 7], [30, 5, 4, 7]] - 0.00120733638068271261 # B[1245, [30, 5, 4, 7], [31, 5, 5, 6]] - -0.000191610125195333311 # B[1246, [30, 5, 4, 7], [32, 5, 5, 8]] - -0.000363280761575070915 # B[1247, [30, 5, 4, 7], [33, 6, 0, 6]] - 0.0015080393447339897 # B[1248, [30, 5, 4, 7], [34, 6, 1, 7]] - 0.00144737958774105498 # B[1249, [30, 5, 4, 7], [35, 6, 2, 6]] - -0.000191256340607337365 # B[1250, [30, 5, 4, 7], [36, 6, 2, 8]] - 0.00324542123326504103 # B[1251, [30, 5, 4, 7], [37, 6, 3, 7]] - 0.00135369467391198949 # B[1252, [30, 5, 4, 7], [38, 6, 4, 6]] - 0.00077393986417062131 # B[1253, [30, 5, 4, 7], [39, 6, 4, 8]] - 0.00187057819081324836 # B[1254, [30, 5, 4, 7], [40, 6, 5, 7]] - 4.06728949024891956e-05 # B[1255, [30, 5, 4, 7], [41, 6, 6, 6]] - -0.000100060243024913467 # B[1256, [30, 5, 4, 7], [42, 6, 6, 8]] - -0.000170624797097965186 # B[1257, [30, 5, 4, 7], [43, 7, 0, 7]] - -0.00157200294852092963 # B[1258, [30, 5, 4, 7], [44, 7, 1, 8]] - -5.099465391029262e-05 # B[1259, [30, 5, 4, 7], [45, 7, 2, 7]] - 0.00166973065524506255 # B[1260, [30, 5, 4, 7], [46, 7, 3, 8]] - 0.000976468235486894175 # B[1261, [30, 5, 4, 7], [47, 7, 4, 7]] - -0.000570830124590235299 # B[1262, [30, 5, 4, 7], [48, 7, 5, 8]] - 0.000667250794893839427 # B[1263, [30, 5, 4, 7], [49, 7, 6, 7]] - -0.000273376565753529832 # B[1264, [30, 5, 4, 7], [50, 7, 7, 8]] - 0.000206233716860107844 # B[1265, [30, 5, 4, 7], [51, 8, 0, 8]] - 0.00260342927157033218 # B[1266, [30, 5, 4, 7], [52, 8, 2, 8]] - 0.000943954042545826558 # B[1267, [30, 5, 4, 7], [53, 8, 4, 8]] - -0.00022781927635321525 # B[1268, [30, 5, 4, 7], [54, 8, 6, 8]] - -0.000448456045604168733 # B[1269, [30, 5, 4, 7], [55, 8, 8, 8]] - 0.00102985782764508475 # B[1270, [31, 5, 5, 6], [31, 5, 5, 6]] - -8.89908688742153606e-05 # B[1271, [31, 5, 5, 6], [32, 5, 5, 8]] - -0.000162481274467801695 # B[1272, [31, 5, 5, 6], [33, 6, 0, 6]] - 0.00263772603538907271 # B[1273, [31, 5, 5, 6], [34, 6, 1, 7]] - -0.00223528099165903275 # B[1274, [31, 5, 5, 6], [35, 6, 2, 6]] - 0.000441657599119526373 # B[1275, [31, 5, 5, 6], [36, 6, 2, 8]] - 0.00165514785004864176 # B[1276, [31, 5, 5, 6], [37, 6, 3, 7]] - 0.000898928585103351413 # B[1277, [31, 5, 5, 6], [38, 6, 4, 6]] - -0.00026071204606309753 # B[1278, [31, 5, 5, 6], [39, 6, 4, 8]] - -0.000251612913047311385 # B[1279, [31, 5, 5, 6], [40, 6, 5, 7]] - -0.00022773870089292346 # B[1280, [31, 5, 5, 6], [41, 6, 6, 6]] - -0.000449951686975022525 # B[1281, [31, 5, 5, 6], [42, 6, 6, 8]] - -0.000252400784021909741 # B[1282, [31, 5, 5, 6], [43, 7, 0, 7]] - 0.000574433272355396977 # B[1283, [31, 5, 5, 6], [44, 7, 1, 8]] - -0.0014040949400035245 # B[1284, [31, 5, 5, 6], [45, 7, 2, 7]] - 0.00124516802775002586 # B[1285, [31, 5, 5, 6], [46, 7, 3, 8]] - 0.000875572292146320832 # B[1286, [31, 5, 5, 6], [47, 7, 4, 7]] - -0.000509730931921630048 # B[1287, [31, 5, 5, 6], [48, 7, 5, 8]] - 0.000422266146488117777 # B[1288, [31, 5, 5, 6], [49, 7, 6, 7]] - -0.000239146684560266956 # B[1289, [31, 5, 5, 6], [50, 7, 7, 8]] - 9.95899703990707486e-05 # B[1290, [31, 5, 5, 6], [51, 8, 0, 8]] - -0.0020784147827535588 # B[1291, [31, 5, 5, 6], [52, 8, 2, 8]] - 0.000735684723224858811 # B[1292, [31, 5, 5, 6], [53, 8, 4, 8]] - -0.000248804810033285279 # B[1293, [31, 5, 5, 6], [54, 8, 6, 8]] - -0.000598263607047986451 # B[1294, [31, 5, 5, 6], [55, 8, 8, 8]] - 0.000131065920905359436 # B[1295, [32, 5, 5, 8], [32, 5, 5, 8]] - 0.000100196796943449913 # B[1296, [32, 5, 5, 8], [33, 6, 0, 6]] - -0.00173991171955805834 # B[1297, [32, 5, 5, 8], [34, 6, 1, 7]] - -0.000490539010579770906 # B[1298, [32, 5, 5, 8], [35, 6, 2, 6]] - 0.000676191083650941674 # B[1299, [32, 5, 5, 8], [36, 6, 2, 8]] - 0.000446932761165407325 # B[1300, [32, 5, 5, 8], [37, 6, 3, 7]] - -0.000153107558622965576 # B[1301, [32, 5, 5, 8], [38, 6, 4, 6]] - 1.67752859932734574e-05 # B[1302, [32, 5, 5, 8], [39, 6, 4, 8]] - 0.000215146896189506113 # B[1303, [32, 5, 5, 8], [40, 6, 5, 7]] - -0.000188466441880926362 # B[1304, [32, 5, 5, 8], [41, 6, 6, 6]] - -4.80917708388720055e-06 # B[1305, [32, 5, 5, 8], [42, 6, 6, 8]] - -5.04429979448911547e-05 # B[1306, [32, 5, 5, 8], [43, 7, 0, 7]] - -0.000494944862407609067 # B[1307, [32, 5, 5, 8], [44, 7, 1, 8]] - -0.000424473825928651724 # B[1308, [32, 5, 5, 8], [45, 7, 2, 7]] - 0.000417544384337296959 # B[1309, [32, 5, 5, 8], [46, 7, 3, 8]] - 0.000431586591455488614 # B[1310, [32, 5, 5, 8], [47, 7, 4, 7]] - 0.000187341827588022357 # B[1311, [32, 5, 5, 8], [48, 7, 5, 8]] - -6.87669988055673864e-05 # B[1312, [32, 5, 5, 8], [49, 7, 6, 7]] - 0.000147867669408649482 # B[1313, [32, 5, 5, 8], [50, 7, 7, 8]] - -7.32201679551347517e-06 # B[1314, [32, 5, 5, 8], [51, 8, 0, 8]] - -0.000392519615947300787 # B[1315, [32, 5, 5, 8], [52, 8, 2, 8]] - 8.78465325612771269e-05 # B[1316, [32, 5, 5, 8], [53, 8, 4, 8]] - -6.3960070015590606e-05 # B[1317, [32, 5, 5, 8], [54, 8, 6, 8]] - -7.97839909379757101e-06 # B[1318, [32, 5, 5, 8], [55, 8, 8, 8]] - 3.95695067041609838e-05 # B[1319, [33, 6, 0, 6], [33, 6, 0, 6]] - -0.000611658005184461534 # B[1320, [33, 6, 0, 6], [34, 6, 1, 7]] - -0.000277914808470863806 # B[1321, [33, 6, 0, 6], [35, 6, 2, 6]] - 0.000987938388973043716 # B[1322, [33, 6, 0, 6], [36, 6, 2, 8]] - 0.000198558948919527745 # B[1323, [33, 6, 0, 6], [37, 6, 3, 7]] - 9.76274805398642809e-05 # B[1324, [33, 6, 0, 6], [38, 6, 4, 6]] - 9.92197766131464043e-05 # B[1325, [33, 6, 0, 6], [39, 6, 4, 8]] - -4.16996931875308896e-05 # B[1326, [33, 6, 0, 6], [40, 6, 5, 7]] - -5.3495059095630057e-05 # B[1327, [33, 6, 0, 6], [41, 6, 6, 6]] - 1.0720822351671655e-05 # B[1328, [33, 6, 0, 6], [42, 6, 6, 8]] - 0.000114464898537391946 # B[1329, [33, 6, 0, 6], [43, 7, 0, 7]] - -0.00033593422820483651 # B[1330, [33, 6, 0, 6], [44, 7, 1, 8]] - -0.00061665800523461739 # B[1331, [33, 6, 0, 6], [45, 7, 2, 7]] - -0.000258302532232180387 # B[1332, [33, 6, 0, 6], [46, 7, 3, 8]] - 3.78181072490033077e-05 # B[1333, [33, 6, 0, 6], [47, 7, 4, 7]] - -0.000326273283142861775 # B[1334, [33, 6, 0, 6], [48, 7, 5, 8]] - 1.74277156155672186e-05 # B[1335, [33, 6, 0, 6], [49, 7, 6, 7]] - -0.000206600107910874173 # B[1336, [33, 6, 0, 6], [50, 7, 7, 8]] - 2.12855018918572947e-05 # B[1337, [33, 6, 0, 6], [51, 8, 0, 8]] - -0.000696835386532819456 # B[1338, [33, 6, 0, 6], [52, 8, 2, 8]] - 8.06841007746916805e-05 # B[1339, [33, 6, 0, 6], [53, 8, 4, 8]] - 1.96129469472779844e-05 # B[1340, [33, 6, 0, 6], [54, 8, 6, 8]] - 7.35114191380559223e-05 # B[1341, [33, 6, 0, 6], [55, 8, 8, 8]] - 0.00360109138862139185 # B[1342, [34, 6, 1, 7], [34, 6, 1, 7]] - 0.00304872474261531218 # B[1343, [34, 6, 1, 7], [35, 6, 2, 6]] - -0.00546316824530662139 # B[1344, [34, 6, 1, 7], [36, 6, 2, 8]] - 0.000721988419001898946 # B[1345, [34, 6, 1, 7], [37, 6, 3, 7]] - -0.00254968694435141717 # B[1346, [34, 6, 1, 7], [38, 6, 4, 6]] - -0.00102187793811427596 # B[1347, [34, 6, 1, 7], [39, 6, 4, 8]] - 0.000977866285507509106 # B[1348, [34, 6, 1, 7], [40, 6, 5, 7]] - 0.00129156024637028417 # B[1349, [34, 6, 1, 7], [41, 6, 6, 6]] - 8.43980229575398005e-05 # B[1350, [34, 6, 1, 7], [42, 6, 6, 8]] - -0.000854491821273548058 # B[1351, [34, 6, 1, 7], [43, 7, 0, 7]] - -0.00229655360277009144 # B[1352, [34, 6, 1, 7], [44, 7, 1, 8]] - 0.00392740594657482126 # B[1353, [34, 6, 1, 7], [45, 7, 2, 7]] - 0.00282086313880587115 # B[1354, [34, 6, 1, 7], [46, 7, 3, 8]] - -0.00269367822401865922 # B[1355, [34, 6, 1, 7], [47, 7, 4, 7]] - 0.00120544917432826269 # B[1356, [34, 6, 1, 7], [48, 7, 5, 8]] - 0.00137213082032611872 # B[1357, [34, 6, 1, 7], [49, 7, 6, 7]] - 0.00278774897747785522 # B[1358, [34, 6, 1, 7], [50, 7, 7, 8]] - -1.00075929411755707e-05 # B[1359, [34, 6, 1, 7], [51, 8, 0, 8]] - 0.00331402709384703321 # B[1360, [34, 6, 1, 7], [52, 8, 2, 8]] - -0.00220016465090739841 # B[1361, [34, 6, 1, 7], [53, 8, 4, 8]] - 0.000794479619849004434 # B[1362, [34, 6, 1, 7], [54, 8, 6, 8]] - 0.000207117210070053084 # B[1363, [34, 6, 1, 7], [55, 8, 8, 8]] - 0.000547206364960122621 # B[1364, [35, 6, 2, 6], [35, 6, 2, 6]] - 0.00243529980905243717 # B[1365, [35, 6, 2, 6], [36, 6, 2, 8]] - 0.000346076245330416421 # B[1366, [35, 6, 2, 6], [37, 6, 3, 7]] - 0.00220550296989585788 # B[1367, [35, 6, 2, 6], [38, 6, 4, 6]] - 0.00101934408216735467 # B[1368, [35, 6, 2, 6], [39, 6, 4, 8]] - 6.76995447894471192e-05 # B[1369, [35, 6, 2, 6], [40, 6, 5, 7]] - -4.61734905116591154e-05 # B[1370, [35, 6, 2, 6], [41, 6, 6, 6]] - 0.000809543629624515093 # B[1371, [35, 6, 2, 6], [42, 6, 6, 8]] - 0.000219078295465409238 # B[1372, [35, 6, 2, 6], [43, 7, 0, 7]] - -0.00316872925249137884 # B[1373, [35, 6, 2, 6], [44, 7, 1, 8]] - 0.000676713636760976206 # B[1374, [35, 6, 2, 6], [45, 7, 2, 7]] - -0.00100477918211841141 # B[1375, [35, 6, 2, 6], [46, 7, 3, 8]] - 0.000400524978896980161 # B[1376, [35, 6, 2, 6], [47, 7, 4, 7]] - -0.00197634098305848622 # B[1377, [35, 6, 2, 6], [48, 7, 5, 8]] - 0.000367979983554051621 # B[1378, [35, 6, 2, 6], [49, 7, 6, 7]] - -0.00126672502130457942 # B[1379, [35, 6, 2, 6], [50, 7, 7, 8]] - 0.000161373464169148675 # B[1380, [35, 6, 2, 6], [51, 8, 0, 8]] - 0.00258770627559228462 # B[1381, [35, 6, 2, 6], [52, 8, 2, 8]] - 0.000816135012742828661 # B[1382, [35, 6, 2, 6], [53, 8, 4, 8]] - -3.28991122771973843e-05 # B[1383, [35, 6, 2, 6], [54, 8, 6, 8]] - -4.18127338362338707e-05 # B[1384, [35, 6, 2, 6], [55, 8, 8, 8]] - 0.00658745572292138409 # B[1385, [36, 6, 2, 8], [36, 6, 2, 8]] - -0.00238764687643479301 # B[1386, [36, 6, 2, 8], [37, 6, 3, 7]] - -0.000831950910425274803 # B[1387, [36, 6, 2, 8], [38, 6, 4, 6]] - 0.00351737364404769177 # B[1388, [36, 6, 2, 8], [39, 6, 4, 8]] - -0.00276293358095670936 # B[1389, [36, 6, 2, 8], [40, 6, 5, 7]] - -0.00115031008308692437 # B[1390, [36, 6, 2, 8], [41, 6, 6, 6]] - -0.000921624256609663434 # B[1391, [36, 6, 2, 8], [42, 6, 6, 8]] - 0.000810924380859275734 # B[1392, [36, 6, 2, 8], [43, 7, 0, 7]] - -0.00488922361819911239 # B[1393, [36, 6, 2, 8], [44, 7, 1, 8]] - 0.00170426259508682162 # B[1394, [36, 6, 2, 8], [45, 7, 2, 7]] - -0.000698037236981145087 # B[1395, [36, 6, 2, 8], [46, 7, 3, 8]] - -0.00159293071425275958 # B[1396, [36, 6, 2, 8], [47, 7, 4, 7]] - 0.00145526568566858513 # B[1397, [36, 6, 2, 8], [48, 7, 5, 8]] - -0.0034526631911915729 # B[1398, [36, 6, 2, 8], [49, 7, 6, 7]] - 0.00136118079841816148 # B[1399, [36, 6, 2, 8], [50, 7, 7, 8]] - -0.000519558666561149851 # B[1400, [36, 6, 2, 8], [51, 8, 0, 8]] - -0.00125430728243427136 # B[1401, [36, 6, 2, 8], [52, 8, 2, 8]] - 0.000225746730173992209 # B[1402, [36, 6, 2, 8], [53, 8, 4, 8]] - 0.000144081610870761424 # B[1403, [36, 6, 2, 8], [54, 8, 6, 8]] - 0.000848192939185923693 # B[1404, [36, 6, 2, 8], [55, 8, 8, 8]] - 0.00209760366601450393 # B[1405, [37, 6, 3, 7], [37, 6, 3, 7]] - -0.00114098142783233825 # B[1406, [37, 6, 3, 7], [38, 6, 4, 6]] - -0.00012482798433224862 # B[1407, [37, 6, 3, 7], [39, 6, 4, 8]] - 0.000414303981445450498 # B[1408, [37, 6, 3, 7], [40, 6, 5, 7]] - -2.06949976952613968e-05 # B[1409, [37, 6, 3, 7], [41, 6, 6, 6]] - 0.000986658381613915447 # B[1410, [37, 6, 3, 7], [42, 6, 6, 8]] - 0.000196361012595618056 # B[1411, [37, 6, 3, 7], [43, 7, 0, 7]] - 0.000421620511108736218 # B[1412, [37, 6, 3, 7], [44, 7, 1, 8]] - -0.00121366957406692996 # B[1413, [37, 6, 3, 7], [45, 7, 2, 7]] - 0.000319772245183778947 # B[1414, [37, 6, 3, 7], [46, 7, 3, 8]] - -0.00189440310525268441 # B[1415, [37, 6, 3, 7], [47, 7, 4, 7]] - -0.000420808921505540223 # B[1416, [37, 6, 3, 7], [48, 7, 5, 8]] - -0.000833056882638676111 # B[1417, [37, 6, 3, 7], [49, 7, 6, 7]] - -0.000210394181928773294 # B[1418, [37, 6, 3, 7], [50, 7, 7, 8]] - 4.67415997983874898e-05 # B[1419, [37, 6, 3, 7], [51, 8, 0, 8]] - -0.000629437221263145228 # B[1420, [37, 6, 3, 7], [52, 8, 2, 8]] - -0.000561739301858470846 # B[1421, [37, 6, 3, 7], [53, 8, 4, 8]] - -0.000244403089656959616 # B[1422, [37, 6, 3, 7], [54, 8, 6, 8]] - 0.000170058213410727299 # B[1423, [37, 6, 3, 7], [55, 8, 8, 8]] - 0.000190580820336867102 # B[1424, [38, 6, 4, 6], [38, 6, 4, 6]] - -5.17086422710446442e-05 # B[1425, [38, 6, 4, 6], [39, 6, 4, 8]] - -0.000870479233908965505 # B[1426, [38, 6, 4, 6], [40, 6, 5, 7]] - 8.56431173592298034e-05 # B[1427, [38, 6, 4, 6], [41, 6, 6, 6]] - -0.000219028113680014638 # B[1428, [38, 6, 4, 6], [42, 6, 6, 8]] - 6.99094597341239771e-05 # B[1429, [38, 6, 4, 6], [43, 7, 0, 7]] - -0.00217214753267054063 # B[1430, [38, 6, 4, 6], [44, 7, 1, 8]] - 0.00103452950595812193 # B[1431, [38, 6, 4, 6], [45, 7, 2, 7]] - 0.000131158053198399821 # B[1432, [38, 6, 4, 6], [46, 7, 3, 8]] - -0.000991288929959081421 # B[1433, [38, 6, 4, 6], [47, 7, 4, 7]] - -0.000321058899826150157 # B[1434, [38, 6, 4, 6], [48, 7, 5, 8]] - -0.000126379357764709599 # B[1435, [38, 6, 4, 6], [49, 7, 6, 7]] - 0.000513859397020456632 # B[1436, [38, 6, 4, 6], [50, 7, 7, 8]] - -2.72482190626921472e-05 # B[1437, [38, 6, 4, 6], [51, 8, 0, 8]] - 0.000742781076179950886 # B[1438, [38, 6, 4, 6], [52, 8, 2, 8]] - -9.17701606060090935e-05 # B[1439, [38, 6, 4, 6], [53, 8, 4, 8]] - 1.49768390447675703e-05 # B[1440, [38, 6, 4, 6], [54, 8, 6, 8]] - -5.94521118466549703e-05 # B[1441, [38, 6, 4, 6], [55, 8, 8, 8]] - 0.00161400415689978271 # B[1442, [39, 6, 4, 8], [39, 6, 4, 8]] - -0.000149892220376375129 # B[1443, [39, 6, 4, 8], [40, 6, 5, 7]] - -0.000242832088631229209 # B[1444, [39, 6, 4, 8], [41, 6, 6, 6]] - -4.23223006292567511e-05 # B[1445, [39, 6, 4, 8], [42, 6, 6, 8]] - 0.000145544599928226076 # B[1446, [39, 6, 4, 8], [43, 7, 0, 7]] - -0.000846976149028450323 # B[1447, [39, 6, 4, 8], [44, 7, 1, 8]] - 0.000313402576083809947 # B[1448, [39, 6, 4, 8], [45, 7, 2, 7]] - -0.00105304559168569421 # B[1449, [39, 6, 4, 8], [46, 7, 3, 8]] - -0.000563622717067245593 # B[1450, [39, 6, 4, 8], [47, 7, 4, 7]] - -0.000176248327800098206 # B[1451, [39, 6, 4, 8], [48, 7, 5, 8]] - -0.000523005481859822874 # B[1452, [39, 6, 4, 8], [49, 7, 6, 7]] - 0.000327425878709725754 # B[1453, [39, 6, 4, 8], [50, 7, 7, 8]] - -0.000214075091648432969 # B[1454, [39, 6, 4, 8], [51, 8, 0, 8]] - 0.000892962890338189208 # B[1455, [39, 6, 4, 8], [52, 8, 2, 8]] - 0.000483016760753301674 # B[1456, [39, 6, 4, 8], [53, 8, 4, 8]] - 0.000385986009520520711 # B[1457, [39, 6, 4, 8], [54, 8, 6, 8]] - 0.000210387221014841225 # B[1458, [39, 6, 4, 8], [55, 8, 8, 8]] - 0.000423894835630976054 # B[1459, [40, 6, 5, 7], [40, 6, 5, 7]] - 2.52152593651043533e-05 # B[1460, [40, 6, 5, 7], [41, 6, 6, 6]] - 0.0001406783760301792 # B[1461, [40, 6, 5, 7], [42, 6, 6, 8]] - -0.000402862939603353815 # B[1462, [40, 6, 5, 7], [43, 7, 0, 7]] - -0.000764679971924708997 # B[1463, [40, 6, 5, 7], [44, 7, 1, 8]] - 0.000690122720081854865 # B[1464, [40, 6, 5, 7], [45, 7, 2, 7]] - 0.00135911524951161378 # B[1465, [40, 6, 5, 7], [46, 7, 3, 8]] - 5.52075818169902449e-06 # B[1466, [40, 6, 5, 7], [47, 7, 4, 7]] - -0.000149902773226399076 # B[1467, [40, 6, 5, 7], [48, 7, 5, 8]] - 0.000389894625400750289 # B[1468, [40, 6, 5, 7], [49, 7, 6, 7]] - 0.000257807843360047251 # B[1469, [40, 6, 5, 7], [50, 7, 7, 8]] - -3.67912373811542237e-05 # B[1470, [40, 6, 5, 7], [51, 8, 0, 8]] - -0.000174743024771516643 # B[1471, [40, 6, 5, 7], [52, 8, 2, 8]] - 0.000276798622678277838 # B[1472, [40, 6, 5, 7], [53, 8, 4, 8]] - 0.000152459620483783032 # B[1473, [40, 6, 5, 7], [54, 8, 6, 8]] - -0.000616599602238733502 # B[1474, [40, 6, 5, 7], [55, 8, 8, 8]] - -5.12324624723156652e-05 # B[1475, [41, 6, 6, 6], [41, 6, 6, 6]] - -4.23334509430418893e-05 # B[1476, [41, 6, 6, 6], [42, 6, 6, 8]] - -0.000111212733055157664 # B[1477, [41, 6, 6, 6], [43, 7, 0, 7]] - 0.000882360189618891337 # B[1478, [41, 6, 6, 6], [44, 7, 1, 8]] - -0.000581964842687935843 # B[1479, [41, 6, 6, 6], [45, 7, 2, 7]] - 0.000211138997961872465 # B[1480, [41, 6, 6, 6], [46, 7, 3, 8]] - 7.79906436828414068e-05 # B[1481, [41, 6, 6, 6], [47, 7, 4, 7]] - -0.000201461425275273331 # B[1482, [41, 6, 6, 6], [48, 7, 5, 8]] - 6.87828589884392771e-05 # B[1483, [41, 6, 6, 6], [49, 7, 6, 7]] - 0.000150653067204437052 # B[1484, [41, 6, 6, 6], [50, 7, 7, 8]] - 3.87532549918634395e-05 # B[1485, [41, 6, 6, 6], [51, 8, 0, 8]] - 0.000361299779465781672 # B[1486, [41, 6, 6, 6], [52, 8, 2, 8]] - -0.000217385549744270783 # B[1487, [41, 6, 6, 6], [53, 8, 4, 8]] - 6.09508622621875856e-05 # B[1488, [41, 6, 6, 6], [54, 8, 6, 8]] - -0.000174447165900721429 # B[1489, [41, 6, 6, 6], [55, 8, 8, 8]] - 4.08451735536830007e-05 # B[1490, [42, 6, 6, 8], [42, 6, 6, 8]] - -0.000100109250872669128 # B[1491, [42, 6, 6, 8], [43, 7, 0, 7]] - 0.000543796967600337564 # B[1492, [42, 6, 6, 8], [44, 7, 1, 8]] - 0.000744432946735457124 # B[1493, [42, 6, 6, 8], [45, 7, 2, 7]] - 0.0010803210667922683 # B[1494, [42, 6, 6, 8], [46, 7, 3, 8]] - 0.000151445105968722347 # B[1495, [42, 6, 6, 8], [47, 7, 4, 7]] - -0.000100848877598445907 # B[1496, [42, 6, 6, 8], [48, 7, 5, 8]] - -0.000109088350721993355 # B[1497, [42, 6, 6, 8], [49, 7, 6, 7]] - -0.000287924009882135207 # B[1498, [42, 6, 6, 8], [50, 7, 7, 8]] - 1.48405987461727729e-05 # B[1499, [42, 6, 6, 8], [51, 8, 0, 8]] - 0.00133229142431166023 # B[1500, [42, 6, 6, 8], [52, 8, 2, 8]] - -0.00019157481902659472 # B[1501, [42, 6, 6, 8], [53, 8, 4, 8]] - -0.000214414469154704246 # B[1502, [42, 6, 6, 8], [54, 8, 6, 8]] - -0.000145460173238021184 # B[1503, [42, 6, 6, 8], [55, 8, 8, 8]] - 0.000122164068846408735 # B[1504, [43, 7, 0, 7], [43, 7, 0, 7]] - -0.000271198052548764657 # B[1505, [43, 7, 0, 7], [44, 7, 1, 8]] - -7.53020792218089818e-05 # B[1506, [43, 7, 0, 7], [45, 7, 2, 7]] - -0.000522043739406908344 # B[1507, [43, 7, 0, 7], [46, 7, 3, 8]] - -4.818852612961666e-05 # B[1508, [43, 7, 0, 7], [47, 7, 4, 7]] - -0.000220542438614808323 # B[1509, [43, 7, 0, 7], [48, 7, 5, 8]] - -0.000160998835878327362 # B[1510, [43, 7, 0, 7], [49, 7, 6, 7]] - -2.41628428966911279e-05 # B[1511, [43, 7, 0, 7], [50, 7, 7, 8]] - -1.41474469189661889e-05 # B[1512, [43, 7, 0, 7], [51, 8, 0, 8]] - -0.000160534811881916234 # B[1513, [43, 7, 0, 7], [52, 8, 2, 8]] - -1.73735621299461046e-05 # B[1514, [43, 7, 0, 7], [53, 8, 4, 8]] - 4.73251016045242445e-05 # B[1515, [43, 7, 0, 7], [54, 8, 6, 8]] - 0.000182463508348683356 # B[1516, [43, 7, 0, 7], [55, 8, 8, 8]] - -0.000629134879565343137 # B[1517, [44, 7, 1, 8], [44, 7, 1, 8]] - -0.00207361578267727673 # B[1518, [44, 7, 1, 8], [45, 7, 2, 7]] - 0.0031686999001355326 # B[1519, [44, 7, 1, 8], [46, 7, 3, 8]] - -0.000405403647932546952 # B[1520, [44, 7, 1, 8], [47, 7, 4, 7]] - -0.000111251617971438489 # B[1521, [44, 7, 1, 8], [48, 7, 5, 8]] - 0.0014482690523848242 # B[1522, [44, 7, 1, 8], [49, 7, 6, 7]] - 0.000818892450912583197 # B[1523, [44, 7, 1, 8], [50, 7, 7, 8]] - 0.000100422502558870572 # B[1524, [44, 7, 1, 8], [51, 8, 0, 8]] - -0.000412863674396233161 # B[1525, [44, 7, 1, 8], [52, 8, 2, 8]] - -0.000905494278120194153 # B[1526, [44, 7, 1, 8], [53, 8, 4, 8]] - 0.00126932173443552359 # B[1527, [44, 7, 1, 8], [54, 8, 6, 8]] - -0.000374814469421512735 # B[1528, [44, 7, 1, 8], [55, 8, 8, 8]] - -0.00330341133748704441 # B[1529, [45, 7, 2, 7], [45, 7, 2, 7]] - 0.00131616674488897398 # B[1530, [45, 7, 2, 7], [46, 7, 3, 8]] - -0.000483635326292886428 # B[1531, [45, 7, 2, 7], [47, 7, 4, 7]] - -0.00177550615332965067 # B[1532, [45, 7, 2, 7], [48, 7, 5, 8]] - 0.00226091969304176299 # B[1533, [45, 7, 2, 7], [49, 7, 6, 7]] - -0.00142635978155006456 # B[1534, [45, 7, 2, 7], [50, 7, 7, 8]] - 0.000289476939908078768 # B[1535, [45, 7, 2, 7], [51, 8, 0, 8]] - 0.000582488578419503846 # B[1536, [45, 7, 2, 7], [52, 8, 2, 8]] - -0.000228795123723987606 # B[1537, [45, 7, 2, 7], [53, 8, 4, 8]] - 0.000478658611037000373 # B[1538, [45, 7, 2, 7], [54, 8, 6, 8]] - -0.00101956994563059782 # B[1539, [45, 7, 2, 7], [55, 8, 8, 8]] - 0.00268648192223141895 # B[1540, [46, 7, 3, 8], [46, 7, 3, 8]] - 0.000515570689344949529 # B[1541, [46, 7, 3, 8], [47, 7, 4, 7]] - 0.000903689215066725768 # B[1542, [46, 7, 3, 8], [48, 7, 5, 8]] - 0.00180650309403464215 # B[1543, [46, 7, 3, 8], [49, 7, 6, 7]] - -7.48574841450792838e-05 # B[1544, [46, 7, 3, 8], [50, 7, 7, 8]] - -2.90930360741237237e-05 # B[1545, [46, 7, 3, 8], [51, 8, 0, 8]] - 0.00139057844941538594 # B[1546, [46, 7, 3, 8], [52, 8, 2, 8]] - -0.000263907165716330272 # B[1547, [46, 7, 3, 8], [53, 8, 4, 8]] - -5.74521512815137289e-05 # B[1548, [46, 7, 3, 8], [54, 8, 6, 8]] - -0.00030234445629373323 # B[1549, [46, 7, 3, 8], [55, 8, 8, 8]] - -0.000842080339294604824 # B[1550, [47, 7, 4, 7], [47, 7, 4, 7]] - -1.8677234631915389e-05 # B[1551, [47, 7, 4, 7], [48, 7, 5, 8]] - 0.000150434033167294937 # B[1552, [47, 7, 4, 7], [49, 7, 6, 7]] - 0.000201922161197246736 # B[1553, [47, 7, 4, 7], [50, 7, 7, 8]] - 5.63689077359152968e-05 # B[1554, [47, 7, 4, 7], [51, 8, 0, 8]] - 0.000490229079971716761 # B[1555, [47, 7, 4, 7], [52, 8, 2, 8]] - -0.00019335269881828529 # B[1556, [47, 7, 4, 7], [53, 8, 4, 8]] - -0.000118664083374402096 # B[1557, [47, 7, 4, 7], [54, 8, 6, 8]] - -0.000397263359111398734 # B[1558, [47, 7, 4, 7], [55, 8, 8, 8]] - -0.000724261739409587726 # B[1559, [48, 7, 5, 8], [48, 7, 5, 8]] - 0.000186853474209224685 # B[1560, [48, 7, 5, 8], [49, 7, 6, 7]] - -0.000533321040010020266 # B[1561, [48, 7, 5, 8], [50, 7, 7, 8]] - 9.95102706208284005e-08 # B[1562, [48, 7, 5, 8], [51, 8, 0, 8]] - -0.00093755398196557671 # B[1563, [48, 7, 5, 8], [52, 8, 2, 8]] - 0.000483236780374178207 # B[1564, [48, 7, 5, 8], [53, 8, 4, 8]] - -5.03524206302112531e-05 # B[1565, [48, 7, 5, 8], [54, 8, 6, 8]] - -0.000586245052440398373 # B[1566, [48, 7, 5, 8], [55, 8, 8, 8]] - -0.000207118017941997773 # B[1567, [49, 7, 6, 7], [49, 7, 6, 7]] - -9.40116364012005823e-05 # B[1568, [49, 7, 6, 7], [50, 7, 7, 8]] - 0.000124266884770383307 # B[1569, [49, 7, 6, 7], [51, 8, 0, 8]] - 0.00118479186165786239 # B[1570, [49, 7, 6, 7], [52, 8, 2, 8]] - -0.000129238345120056067 # B[1571, [49, 7, 6, 7], [53, 8, 4, 8]] - -0.000383875224777865259 # B[1572, [49, 7, 6, 7], [54, 8, 6, 8]] - -0.000457194559055141767 # B[1573, [49, 7, 6, 7], [55, 8, 8, 8]] - -0.000450510261664234871 # B[1574, [50, 7, 7, 8], [50, 7, 7, 8]] - 7.52704593073999506e-05 # B[1575, [50, 7, 7, 8], [51, 8, 0, 8]] - -0.00128732840082427732 # B[1576, [50, 7, 7, 8], [52, 8, 2, 8]] - 0.000293225651298797269 # B[1577, [50, 7, 7, 8], [53, 8, 4, 8]] - -0.000306521733645761033 # B[1578, [50, 7, 7, 8], [54, 8, 6, 8]] - -0.000370268243746852549 # B[1579, [50, 7, 7, 8], [55, 8, 8, 8]] - -4.00747887657759705e-06 # B[1580, [51, 8, 0, 8], [51, 8, 0, 8]] - -0.000179079356204300821 # B[1581, [51, 8, 0, 8], [52, 8, 2, 8]] - -6.37205046857824975e-06 # B[1582, [51, 8, 0, 8], [53, 8, 4, 8]] - 5.20087282658288075e-05 # B[1583, [51, 8, 0, 8], [54, 8, 6, 8]] - 6.68015373273544988e-05 # B[1584, [51, 8, 0, 8], [55, 8, 8, 8]] - 0.00160592146390294661 # B[1585, [52, 8, 2, 8], [52, 8, 2, 8]] - 0.000454049229948232103 # B[1586, [52, 8, 2, 8], [53, 8, 4, 8]] - 0.00110675066334388339 # B[1587, [52, 8, 2, 8], [54, 8, 6, 8]] - -0.000191060465051852771 # B[1588, [52, 8, 2, 8], [55, 8, 8, 8]] - -0.000131765455753670314 # B[1589, [53, 8, 4, 8], [53, 8, 4, 8]] - -7.05704764431217685e-05 # B[1590, [53, 8, 4, 8], [54, 8, 6, 8]] - -1.82263105369812051e-05 # B[1591, [53, 8, 4, 8], [55, 8, 8, 8]] - -0.00032731873727259329 # B[1592, [54, 8, 6, 8], [54, 8, 6, 8]] - -0.000198178389384386089 # B[1593, [54, 8, 6, 8], [55, 8, 8, 8]] - -0.000136309758672861769 # B[1594, [55, 8, 8, 8], [55, 8, 8, 8]] - -# End of potential diff --git a/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff b/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff new file mode 120000 index 0000000000..b0383dc323 --- /dev/null +++ b/examples/snap/C_SNAP_2021.10.15.quadratic.snapcoeff @@ -0,0 +1 @@ +../../potentials/C_SNAP_2021.10.15.quadratic.snapcoeff \ No newline at end of file diff --git a/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam b/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam deleted file mode 100644 index 26dddf627d..0000000000 --- a/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam +++ /dev/null @@ -1,10 +0,0 @@ - - # required - rcutfac 2.7 - twojmax 8 - - # optional - rfac0 0.99363 - rmin0 0.0 - bzeroflag 0 - quadraticflag 1 diff --git a/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam b/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam new file mode 120000 index 0000000000..bac9725d0d --- /dev/null +++ b/examples/snap/C_SNAP_2021.10.15.quadratic.snapparam @@ -0,0 +1 @@ +../../potentials/C_SNAP_2021.10.15.quadratic.snapparam \ No newline at end of file diff --git a/examples/snap/in.C_SNAP b/examples/snap/in.C_SNAP index b504881e90..de2f09d637 100644 --- a/examples/snap/in.C_SNAP +++ b/examples/snap/in.C_SNAP @@ -1,35 +1,31 @@ #Carbon SNAP example: 216 atom diamond unit cell simulated NVT at ~1,000GPa and 5,000K - units metal atom_style atomic boundary p p p -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -# User-defined variables # -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# - -variable alat equal "2.845" -variable nx equal "3" -variable ny equal "3" -variable nz equal "3" -variable tstep equal "0.000500" - #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Crystal orientation and MD box creation # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -lattice diamond ${alat} -region Bbox block 0 ${nx} 0 ${ny} 0 ${nz} +lattice diamond 2.845 +region Bbox block 0 3 0 3 0 3 create_box 1 Bbox create_atoms 1 region Bbox basis 1 1 + #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# # Interatomic potential parameters # #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -include pot_C.mod +# Specify hybrid with SNAP, ZBL, and long-range C_SNAP_2021.10.15.quadratic.ulomb + +pair_style hybrid/overlay zbl 0.1 0.2 snap +pair_coeff 1 1 zbl 10 10 +pair_coeff * * snap C_SNAP_2021.10.15.quadratic.snapcoeff C_SNAP_2021.10.15.quadratic.snapparam C + mass * 12.01 +velocity all create 8000.0 3412461 loop geom fix NVE all nve -fix NVT all langevin 5000. 5000. 0.1 3216548 -thermo 100 -thermo_style custom step temp ke pe etotal pxx pyy pzz xlo xhi ylo yhi zlo zhi cpu -run 2000 +fix NVT all langevin 5000.0 5000.0 0.1 3216548 +thermo 50 +thermo_style custom step temp ke pe etotal press pxx pyy pzz +run 500 diff --git a/examples/snap/log.23May23.C_SNAP b/examples/snap/log.23May23.C_SNAP deleted file mode 100644 index 5b8b9f0066..0000000000 --- a/examples/snap/log.23May23.C_SNAP +++ /dev/null @@ -1,136 +0,0 @@ -LAMMPS (3 Aug 2022) - -units metal -atom_style atomic -boundary p p p - -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -# User-defined variables # -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# - -variable alat equal "2.845" -variable nx equal "3" -variable ny equal "3" -variable nz equal "3" -variable tstep equal "0.000500" - -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -# Crystal orientation and MD box creation # -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -lattice diamond ${alat} -lattice diamond 2.845 -Lattice spacing in x,y,z = 2.845 2.845 2.845 -region Bbox block 0 ${nx} 0 ${ny} 0 ${nz} -region Bbox block 0 3 0 ${ny} 0 ${nz} -region Bbox block 0 3 0 3 0 ${nz} -region Bbox block 0 3 0 3 0 3 -create_box 1 Bbox -Created orthogonal box = (0 0 0) to (8.535 8.535 8.535) - 1 by 1 by 1 MPI processor grid -create_atoms 1 region Bbox basis 1 1 -Created 216 atoms - using lattice units in orthogonal box = (0 0 0) to (8.535 8.535 8.535) - create_atoms CPU = 0.000 seconds -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -# Interatomic potential parameters # -#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# -include pot_C.mod -# Definition of SNAP+ZBL potential. -variable zblcutinner equal 0.1 #0.38 -variable zblcutouter equal 0.2 -variable zblz equal 10 #500 - -# Specify hybrid with SNAP, ZBL, and long-range C_SNAP_2021.10.15.quadratic.ulomb - -pair_style hybrid/overlay zbl ${zblcutinner} ${zblcutouter} snap -pair_style hybrid/overlay zbl 0.1 ${zblcutouter} snap -pair_style hybrid/overlay zbl 0.1 0.2 snap -pair_coeff 1 1 zbl ${zblz} ${zblz} -pair_coeff 1 1 zbl 10 ${zblz} -pair_coeff 1 1 zbl 10 10 -pair_coeff * * snap C_SNAP_2021.10.15.quadratic.snapcoeff C_SNAP_2021.10.15.quadratic.snapparam C -SNAP Element = C, Radius 0.5, Weight 1 -SNAP keyword rcutfac 2.7 -SNAP keyword twojmax 8 -SNAP keyword rfac0 0.99363 -SNAP keyword rmin0 0.0 -SNAP keyword bzeroflag 0 -SNAP keyword quadraticflag 1 - -mass * 12.01 - -fix NVE all nve -fix NVT all langevin 5000. 5000. 0.1 3216548 -thermo 100 -thermo_style custom step temp ke pe etotal pxx pyy pzz xlo xhi ylo yhi zlo zhi cpu -run 2000 -Neighbor list info ... - update: every = 1 steps, delay = 10 steps, check = yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 4.7 - ghost atom cutoff = 4.7 - binsize = 2.35, bins = 4 4 4 - 2 neighbor lists, perpetual/occasional/extra = 2 0 0 - (1) pair zbl, perpetual, half/full trim from (2) - attributes: half, newton on, cut 2.2 - pair build: halffull/newton/trim - stencil: none - bin: none - (2) pair snap, perpetual - attributes: full, newton on - pair build: full/bin/atomonly - stencil: full/bin/3d - bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.835 | 4.835 | 4.835 Mbytes - Step Temp KinEng PotEng TotEng Pxx Pyy Pzz Xlo Xhi Ylo Yhi Zlo Zhi CPU - 0 0 0 -846.66062 -846.66062 9852302.8 9852302.8 9852302.8 0 8.535 0 8.535 0 8.535 0 - 100 2994.9404 83.232183 -760.46784 -677.23566 10153319 10162613 10089556 0 8.535 0 8.535 0 8.535 8.5637966 - 200 4138.1573 115.00324 -718.21196 -603.20871 10328838 10278023 10147395 0 8.535 0 8.535 0 8.535 17.231147 - 300 4231.1241 117.58688 -703.12914 -585.54226 10229126 10278574 10244536 0 8.535 0 8.535 0 8.535 25.883724 - 400 4902.5771 136.24718 -693.59525 -557.34807 10258619 10309837 10270759 0 8.535 0 8.535 0 8.535 34.454573 - 500 5231.01 145.37464 -703.59176 -558.21712 10380296 10313494 10261486 0 8.535 0 8.535 0 8.535 43.03519 - 600 4962.4828 137.91202 -701.69725 -563.78524 10405175 10240153 10223683 0 8.535 0 8.535 0 8.535 51.617418 - 700 5158.8211 143.36844 -696.3068 -552.93836 10224265 10353872 10237323 0 8.535 0 8.535 0 8.535 60.216592 - 800 5566.4588 154.69707 -691.80266 -537.10558 10345764 10333822 10328272 0 8.535 0 8.535 0 8.535 68.836406 - 900 4763.5973 132.38481 -699.56143 -567.17663 10265807 10264115 10292086 0 8.535 0 8.535 0 8.535 77.557491 - 1000 5374.1522 149.35269 -707.77182 -558.41912 10353688 10245807 10289801 0 8.535 0 8.535 0 8.535 86.134981 - 1100 4729.9838 131.45065 -687.84753 -556.39687 10236271 10295262 10280036 0 8.535 0 8.535 0 8.535 94.80143 - 1200 5524.4648 153.53002 -688.33164 -534.80162 10376941 10311014 10272151 0 8.535 0 8.535 0 8.535 103.66054 - 1300 5424.1134 150.74116 -710.48851 -559.74735 10269935 10381675 10208553 0 8.535 0 8.535 0 8.535 112.29193 - 1400 5082.4497 141.24601 -703.51889 -562.27288 10289096 10270701 10360960 0 8.535 0 8.535 0 8.535 120.98393 - 1500 4782.7699 132.91763 -709.97393 -577.0563 10264631 10200017 10341446 0 8.535 0 8.535 0 8.535 129.56238 - 1600 5080.7401 141.1985 -693.90867 -552.71017 10263936 10300165 10411302 0 8.535 0 8.535 0 8.535 138.13256 - 1700 5192.8466 144.31404 -698.99608 -554.68204 10309414 10291531 10256424 0 8.535 0 8.535 0 8.535 146.75162 - 1800 5105.1385 141.87655 -702.43759 -560.56104 10325438 10245469 10330602 0 8.535 0 8.535 0 8.535 155.63637 - 1900 5015.6808 139.39044 -706.73213 -567.34169 10345833 10310789 10319358 0 8.535 0 8.535 0 8.535 164.26556 - 2000 4894.0288 136.00962 -697.34077 -561.33115 10259839 10328896 10230941 0 8.535 0 8.535 0 8.535 172.92786 -Loop time of 172.928 on 1 procs for 2000 steps with 216 atoms - -Performance: 0.999 ns/day, 24.018 hours/ns, 11.566 timesteps/s -99.8% CPU use with 1 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 172.88 | 172.88 | 172.88 | 0.0 | 99.97 -Neigh | 0.0050877 | 0.0050877 | 0.0050877 | 0.0 | 0.00 -Comm | 0.013326 | 0.013326 | 0.013326 | 0.0 | 0.01 -Output | 0.001194 | 0.001194 | 0.001194 | 0.0 | 0.00 -Modify | 0.022687 | 0.022687 | 0.022687 | 0.0 | 0.01 -Other | | 0.006874 | | | 0.00 - -Nlocal: 216 ave 216 max 216 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 1806 ave 1806 max 1806 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 1782 ave 1782 max 1782 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -FullNghs: 32872 ave 32872 max 32872 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 32872 -Ave neighs/atom = 152.18519 -Neighbor list builds = 5 -Dangerous builds = 0 - -Total wall time: 0:02:53 diff --git a/examples/snap/log.30May23.C_SNAP.g++.1 b/examples/snap/log.30May23.C_SNAP.g++.1 new file mode 100644 index 0000000000..65f6d152a4 --- /dev/null +++ b/examples/snap/log.30May23.C_SNAP.g++.1 @@ -0,0 +1,105 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +#Carbon SNAP example: 216 atom diamond unit cell simulated NVT at ~1,000GPa and 5,000K + +units metal +atom_style atomic +boundary p p p + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Crystal orientation and MD box creation # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +lattice diamond 2.845 +Lattice spacing in x,y,z = 2.845 2.845 2.845 +region Bbox block 0 3 0 3 0 3 +create_box 1 Bbox +Created orthogonal box = (0 0 0) to (8.535 8.535 8.535) + 1 by 1 by 1 MPI processor grid +create_atoms 1 region Bbox basis 1 1 +Created 216 atoms + using lattice units in orthogonal box = (0 0 0) to (8.535 8.535 8.535) + create_atoms CPU = 0.000 seconds + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Interatomic potential parameters # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Specify hybrid with SNAP, ZBL, and long-range C_SNAP_2021.10.15.quadratic.ulomb + +pair_style hybrid/overlay zbl 0.1 0.2 snap +pair_coeff 1 1 zbl 10 10 +pair_coeff * * snap C_SNAP_2021.10.15.quadratic.snapcoeff C_SNAP_2021.10.15.quadratic.snapparam C +SNAP Element = C, Radius 0.5, Weight 1 +SNAP keyword rcutfac 2.7 +SNAP keyword twojmax 8 +SNAP keyword rfac0 0.99363 +SNAP keyword rmin0 0.0 +SNAP keyword bzeroflag 0 +SNAP keyword quadraticflag 1 + +mass * 12.01 +velocity all create 8000.0 3412461 loop geom + +fix NVE all nve +fix NVT all langevin 5000.0 5000.0 0.1 3216548 +thermo 50 +thermo_style custom step temp ke pe etotal press pxx pyy pzz +run 500 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 4.7 + ghost atom cutoff = 4.7 + binsize = 2.35, bins = 4 4 4 + 2 neighbor lists, perpetual/occasional/extra = 2 0 0 + (1) pair zbl, perpetual, half/full trim from (2) + attributes: half, newton on, cut 2.2 + pair build: halffull/newton/trim + stencil: none + bin: none + (2) pair snap, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 4.835 | 4.835 | 4.835 Mbytes + Step Temp KinEng PotEng TotEng Press Pxx Pyy Pzz + 0 8000 222.32745 -846.66062 -624.33318 10234249 10210805 10267435 10224506 + 50 4199.4229 116.70587 -723.2423 -606.53643 10256033 10157803 10280166 10330129 + 100 3820.2509 106.16833 -710.43537 -604.26704 10232872 10216484 10241309 10240825 + 150 4413.2948 122.64957 -710.09702 -587.44745 10254093 10323013 10265454 10173810 + 200 4688.024 130.28455 -702.26198 -571.97742 10306186 10281632 10342390 10294536 + 250 4997.165 138.87587 -720.58476 -581.70889 10284438 10220856 10360231 10272226 + 300 4640.4911 128.96357 -710.75063 -581.78706 10263301 10264007 10290526 10235369 + 350 4929.5117 136.99572 -707.2526 -570.25688 10290742 10359920 10284236 10228071 + 400 4700.9354 130.64337 -697.90277 -567.2594 10250682 10277287 10246032 10228729 + 450 5108.4971 141.96989 -700.57144 -558.60155 10289765 10323648 10306588 10239058 + 500 5146.7039 143.03169 -700.33221 -557.30052 10334303 10349736 10358785 10294387 +Loop time of 36.7771 on 1 procs for 500 steps with 216 atoms + +Performance: 1.175 ns/day, 20.432 hours/ns, 13.595 timesteps/s, 2.937 katom-step/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 36.766 | 36.766 | 36.766 | 0.0 | 99.97 +Neigh | 0.0010226 | 0.0010226 | 0.0010226 | 0.0 | 0.00 +Comm | 0.0033205 | 0.0033205 | 0.0033205 | 0.0 | 0.01 +Output | 0.00020657 | 0.00020657 | 0.00020657 | 0.0 | 0.00 +Modify | 0.0047621 | 0.0047621 | 0.0047621 | 0.0 | 0.01 +Other | | 0.001464 | | | 0.00 + +Nlocal: 216 ave 216 max 216 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1746 ave 1746 max 1746 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 1767 ave 1767 max 1767 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 32846 ave 32846 max 32846 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 32846 +Ave neighs/atom = 152.06481 +Neighbor list builds = 1 +Dangerous builds = 0 +Total wall time: 0:00:36 diff --git a/examples/snap/log.30May23.C_SNAP.g++.4 b/examples/snap/log.30May23.C_SNAP.g++.4 new file mode 100644 index 0000000000..f7a71b5b41 --- /dev/null +++ b/examples/snap/log.30May23.C_SNAP.g++.4 @@ -0,0 +1,105 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +#Carbon SNAP example: 216 atom diamond unit cell simulated NVT at ~1,000GPa and 5,000K + +units metal +atom_style atomic +boundary p p p + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Crystal orientation and MD box creation # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +lattice diamond 2.845 +Lattice spacing in x,y,z = 2.845 2.845 2.845 +region Bbox block 0 3 0 3 0 3 +create_box 1 Bbox +Created orthogonal box = (0 0 0) to (8.535 8.535 8.535) + 1 by 2 by 2 MPI processor grid +create_atoms 1 region Bbox basis 1 1 +Created 216 atoms + using lattice units in orthogonal box = (0 0 0) to (8.535 8.535 8.535) + create_atoms CPU = 0.000 seconds + +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Interatomic potential parameters # +#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# +# Specify hybrid with SNAP, ZBL, and long-range C_SNAP_2021.10.15.quadratic.ulomb + +pair_style hybrid/overlay zbl 0.1 0.2 snap +pair_coeff 1 1 zbl 10 10 +pair_coeff * * snap C_SNAP_2021.10.15.quadratic.snapcoeff C_SNAP_2021.10.15.quadratic.snapparam C +SNAP Element = C, Radius 0.5, Weight 1 +SNAP keyword rcutfac 2.7 +SNAP keyword twojmax 8 +SNAP keyword rfac0 0.99363 +SNAP keyword rmin0 0.0 +SNAP keyword bzeroflag 0 +SNAP keyword quadraticflag 1 + +mass * 12.01 +velocity all create 8000.0 3412461 loop geom + +fix NVE all nve +fix NVT all langevin 5000.0 5000.0 0.1 3216548 +thermo 50 +thermo_style custom step temp ke pe etotal press pxx pyy pzz +run 500 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 4.7 + ghost atom cutoff = 4.7 + binsize = 2.35, bins = 4 4 4 + 2 neighbor lists, perpetual/occasional/extra = 2 0 0 + (1) pair zbl, perpetual, half/full trim from (2) + attributes: half, newton on, cut 2.2 + pair build: halffull/newton/trim + stencil: none + bin: none + (2) pair snap, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 4.681 | 4.681 | 4.681 Mbytes + Step Temp KinEng PotEng TotEng Press Pxx Pyy Pzz + 0 8000 222.32745 -846.66062 -624.33318 10234249 10210805 10267435 10224506 + 50 4382.3571 121.78978 -715.70492 -593.91513 10262157 10278549 10181545 10326376 + 100 4546.1549 126.34188 -713.11818 -586.77631 10261694 10257647 10333666 10193770 + 150 5109.4576 141.99658 -708.87952 -566.88294 10268132 10248182 10248240 10307974 + 200 4764.2181 132.40206 -712.16881 -579.76675 10329903 10238991 10379394 10371323 + 250 4989.5099 138.66313 -710.39748 -571.73435 10282678 10321057 10274124 10252854 + 300 4853.3102 134.87801 -699.98167 -565.10366 10343314 10204138 10430172 10395634 + 350 4788.1153 133.06618 -705.14381 -572.07763 10325571 10312657 10267999 10396058 + 400 5055.7813 140.50487 -707.38537 -566.8805 10323176 10357258 10310733 10301536 + 450 5182.3198 144.02149 -695.11614 -551.09465 10345564 10358486 10346325 10331881 + 500 5311.077 147.59977 -691.32767 -543.7279 10308823 10242668 10214102 10469700 +Loop time of 11.5932 on 4 procs for 500 steps with 216 atoms + +Performance: 3.726 ns/day, 6.441 hours/ns, 43.129 timesteps/s, 9.316 katom-step/s +94.9% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 10.241 | 10.446 | 10.695 | 5.0 | 90.11 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0.87613 | 1.1187 | 1.3179 | 14.9 | 9.65 +Output | 0.0002656 | 0.0010016 | 0.0015521 | 1.5 | 0.01 +Modify | 0.0019493 | 0.0020668 | 0.0021577 | 0.2 | 0.02 +Other | | 0.02508 | | | 0.22 + +Nlocal: 54 ave 54 max 54 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Nghost: 1082 ave 1082 max 1082 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Neighs: 432 ave 432 max 432 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 8532 ave 8532 max 8532 min +Histogram: 4 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 34128 +Ave neighs/atom = 158 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:11 diff --git a/examples/snap/pot_C.mod b/examples/snap/pot_C.mod deleted file mode 100644 index 3851fb598d..0000000000 --- a/examples/snap/pot_C.mod +++ /dev/null @@ -1,12 +0,0 @@ -# Definition of SNAP+ZBL potential. -variable zblcutinner equal 0.1 -variable zblcutouter equal 0.2 -variable zblz equal 10 - -# Specify hybrid with SNAP, ZBL, and long-range C_SNAP_2021.10.15.quadratic.ulomb - -pair_style hybrid/overlay & -zbl ${zblcutinner} ${zblcutouter} & -snap -pair_coeff 1 1 zbl ${zblz} ${zblz} -pair_coeff * * snap C_SNAP_2021.10.15.quadratic.snapcoeff C_SNAP_2021.10.15.quadratic.snapparam C From 088d870e2062e7613b60f317eaccccd1dfff41cf Mon Sep 17 00:00:00 2001 From: jrgissing Date: Tue, 30 May 2023 17:17:54 -0400 Subject: [PATCH 273/448] check remaining per-atom initializations --- src/atom.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/atom.cpp b/src/atom.cpp index d5f8b64a52..3e9e177ae0 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2131,13 +2131,16 @@ void Atom::add_molecule_atom(Molecule *onemol, int iatom, int ilocal, tagint off for (int i = 0; i < nivector; ++i) if (ivname[i] != nullptr) ivector[i][ilocal] = 0; - for (int i = 0; i < ndvector; ++i) dvector[i][ilocal] = 0.0; + for (int i = 0; i < ndvector; ++i) + if (dvname[i] != nullptr) dvector[i][ilocal] = 0.0; for (int i = 0; i < niarray; ++i) - for (int j = 0; j < icols[i]; ++j) - iarray[i][ilocal][j] = 0; + if (ianame[i] != nullptr) + for (int j = 0; j < icols[i]; ++j) + iarray[i][ilocal][j] = 0; for (int i = 0; i < ndarray; ++i) - for (int j = 0; j < dcols[i]; ++j) - darray[i][ilocal][j] = 0.0; + if (daname[i] != nullptr) + for (int j = 0; j < dcols[i]; ++j) + darray[i][ilocal][j] = 0.0; if (molecular != Atom::MOLECULAR) return; From 9ec55dcb1fb0d68e2bfcb0c675e63b1382218206 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 30 May 2023 19:10:11 -0400 Subject: [PATCH 274/448] silence compiler warning --- src/variable.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 4fb6939866..20fb5ccee8 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4068,12 +4068,16 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t std::string contents_copy(contents); auto pos = contents_copy.find_first_of(','); - if (pos == std::string::npos) - if (strcmp(word,"label2type") == 0) + if (pos == std::string::npos) { + if (strcmp(word,"label2type") == 0) { print_var_error(FLERR, fmt::format("Invalid label2type({}) function in variable formula", contents_copy), ivar); - else print_var_error(FLERR, fmt::format("Invalid is_typelabel({}) function in variable formula", - contents_copy), ivar); + } else { + print_var_error(FLERR, fmt::format("Invalid is_typelabel({}) function in variable formula", + contents_copy), ivar); + } + } + std::string typestr = contents_copy.substr(pos+1); std::string kind = contents_copy.substr(0, pos); From ddc34e03d66452402993ec20203b12a089f2fe21 Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Wed, 31 May 2023 09:50:50 +0200 Subject: [PATCH 275/448] Revert removal of copies of pointers --- .../compute_stress_cartesian.cpp | 52 ++++++++++++------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index 2f6e75b528..106ffef8fb 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -232,12 +232,24 @@ void ComputeStressCartesian::compute_array() { double **x = atom->x; double **v = atom->v; + double *mass = atom->mass; tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + int nlocal = atom->nlocal; + double *special_coul = force->special_coul; + double *special_lj = force->special_lj; + int newton_pair = force->newton_pair; double *boxlo = domain->boxlo; // invoke half neighbor list (will copy or build if necessary) neighbor->build_one(list); + int inum = list->inum; + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + // Zero arrays for (int bin = 0; bin < nbins1 * nbins2; bin++) { tdens[bin] = 0; @@ -250,7 +262,7 @@ void ComputeStressCartesian::compute_array() } // calculate number density and kinetic contribution to pressure - for (int i = 0; i < atom->nlocal; i++) { + for (int i = 0; i < nlocal; i++) { int bin1 = (int) ((x[i][dir1] - boxlo[dir1]) / bin_width1) % nbins1; int bin2 = 0; if (dims == 2) bin2 = (int) ((x[i][dir2] - boxlo[dir2]) / bin_width2) % nbins2; @@ -278,31 +290,31 @@ void ComputeStressCartesian::compute_array() int j = bin1 + bin2 * nbins1; tdens[j] += 1; - tpkxx[j] += atom->mass[atom->type[i]] * v[i][0] * v[i][0]; - tpkyy[j] += atom->mass[atom->type[i]] * v[i][1] * v[i][1]; - tpkzz[j] += atom->mass[atom->type[i]] * v[i][2] * v[i][2]; + tpkxx[j] += mass[type[i]] * v[i][0] * v[i][0]; + tpkyy[j] += mass[type[i]] * v[i][1] * v[i][1]; + tpkzz[j] += mass[type[i]] * v[i][2] * v[i][2]; } // loop over neighbors of my atoms - for (int ii = 0; ii < list->inum; ii++) { - int i = list->ilist[ii]; + for (int ii = 0; ii < inum; ii++) { + int i = ilist[ii]; // skip if I or J are not in group - if (!(atom->mask[i] & groupbit)) continue; + if (!(mask[i] & groupbit)) continue; double xi1 = x[i][dir1] - boxlo[dir1]; double xi2 = x[i][dir2] - boxlo[dir2]; - for (int jj = 0; jj < list->numneigh[i]; jj++) { - int j = list->firstneigh[i][jj]; - double factor_lj = force->special_lj[sbmask(j)]; - double factor_coul = force->special_coul[sbmask(j)]; + for (int jj = 0; jj < numneigh[i]; jj++) { + int j = firstneigh[i][jj]; + double factor_lj = special_lj[sbmask(j)]; + double factor_coul = special_coul[sbmask(j)]; j &= NEIGHMASK; - if (!(atom->mask[j] & groupbit)) continue; + if (!(mask[j] & groupbit)) continue; // for newton = 0 and J = ghost atom, need to ensure I,J pair is only output by one proc // use same tag[i],tag[j] logic as in Neighbor::neigh_half_nsq() - if (force->newton_pair == 0 && j >= atom->nlocal) { + if (newton_pair == 0 && j >= nlocal) { if (tag[i] > tag[j]) { if ((tag[i] + tag[j]) % 2 == 0) continue; } else if (tag[i] < tag[j]) { @@ -323,8 +335,8 @@ void ComputeStressCartesian::compute_array() double rsq = delx * delx + dely * dely + delz * delz; // Check if inside cut-off - int itype = atom->type[i]; - int jtype = atom->type[j]; + int itype = type[i]; + int jtype = type[j]; if (rsq >= force->pair->cutsq[itype][jtype]) continue; double fpair; @@ -338,14 +350,14 @@ void ComputeStressCartesian::compute_array() // i == atom1, j == atom2 int i = neighbor->bondlist[i_bond][0]; int j = neighbor->bondlist[i_bond][1]; - int type = neighbor->bondlist[i_bond][2]; + int btype = neighbor->bondlist[i_bond][2]; // Skip if one of both atoms is not in group - if (!(atom->mask[i] & groupbit)) continue; - if (!(atom->mask[j] & groupbit)) continue; + if (!(mask[i] & groupbit)) continue; + if (!(mask[j] & groupbit)) continue; // if newton_bond is off and atom2 is a ghost atom, only compute this on one processor - if (!force->newton_bond && j >= atom->nlocal) { + if (!force->newton_bond && j >= nlocal) { if (tag[i] > tag[j]) { if ((tag[i] + tag[j]) % 2 == 0) continue; } else if (tag[i] < tag[j]) { @@ -361,7 +373,7 @@ void ComputeStressCartesian::compute_array() double yi = x[i][dir2] - boxlo[dir2]; double fbond; - force->bond->single(type, rsq, i, j, fbond); + force->bond->single(btype, rsq, i, j, fbond); compute_pressure(fbond, xi, yi, dx, dy, dz); } From 70709f2f0847aee69f8f13e11841b3d484328fc0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 08:24:26 -0400 Subject: [PATCH 276/448] simplify error messages --- src/variable.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/variable.cpp b/src/variable.cpp index 20fb5ccee8..e11eff2870 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -4064,7 +4064,7 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t if (strcmp(word,"label2type") == 0 || strcmp(word,"is_typelabel") == 0) { if (!atom->labelmapflag) - print_var_error(FLERR,"Cannot use label2type() or is_typelabel() function without a labelmap",ivar); + print_var_error(FLERR,fmt::format("Cannot use {}() function without a labelmap",word),ivar); std::string contents_copy(contents); auto pos = contents_copy.find_first_of(','); @@ -4093,12 +4093,13 @@ int Variable::special_function(char *word, char *contents, Tree **tree, Tree **t } else if (kind == "improper") { value = atom->lmap->find(typestr,Atom::IMPROPER); } else { - print_var_error(FLERR, fmt::format("Invalid kind {} in label2type() or is_typelabel() in variable",kind),ivar); + print_var_error(FLERR, fmt::format("Invalid kind {} in {}() in variable", kind, word),ivar); } if (strcmp(word,"label2type") == 0) { - if (value == -1) print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable", - kind, typestr), ivar); + if (value == -1) + print_var_error(FLERR, fmt::format("Invalid {} type label {} in label2type() in variable", + kind, typestr), ivar); } else value = (value == -1) ? 0.0 : 1.0; // save value in tree or on argstack From 4540427e2b8c76efc618512bf501bfd8300d58ca Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 08:50:21 -0400 Subject: [PATCH 277/448] add unit tests for is_typelabel() variable function --- unittest/commands/test_variables.cpp | 46 +++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/unittest/commands/test_variables.cpp b/unittest/commands/test_variables.cpp index 3939c9b71b..8374a10690 100644 --- a/unittest/commands/test_variables.cpp +++ b/unittest/commands/test_variables.cpp @@ -590,7 +590,7 @@ TEST_F(VariableTest, NextCommand) command("next five four");); } -TEST_F(VariableTest, Label2TypeAtomic) +TEST_F(VariableTest, LabelMapAtomic) { BEGIN_HIDE_OUTPUT(); command("region box block 0 2 0 2 0 2"); @@ -608,14 +608,20 @@ TEST_F(VariableTest, Label2TypeAtomic) ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,N1)"), 2.0); ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,O1)"), 3.0); ASSERT_DOUBLE_EQ(variable->compute_equal("label2type(atom,H1)"), 4.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,N1)"), 1.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,N2)"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,O)"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,H1)"), 1.0); TEST_FAILURE(".*ERROR: Variable t1: Invalid atom type label C1 in label2type.. in variable.*", command("print \"${t1}\"");); - TEST_FAILURE(".*ERROR: Invalid bond type label H1 in label2type.. in variable.*", - variable->compute_equal("label2type(bond,H1)");); + TEST_FAILURE(".*ERROR: Invalid kind xxx in label2type.. in variable.*", + variable->compute_equal("label2type(xxx,H1)");); + TEST_FAILURE(".*ERROR: Invalid kind xxx in is_typelabel.. in variable.*", + variable->compute_equal("is_typelabel(xxx,H1)");); } -TEST_F(VariableTest, Label2TypeMolecular) +TEST_F(VariableTest, LabelMapMolecular) { if (!info->has_style("atom", "full")) GTEST_SKIP(); @@ -637,6 +643,14 @@ TEST_F(VariableTest, Label2TypeMolecular) command("variable a2 equal \"\"\"label2type(angle,N2'-C1\"-N2')\"\"\""); command("variable d1 equal label2type(dihedral,C1-N2-C1-N2)"); command("variable i1 equal label2type(improper,C1-N2-C1-N2)"); + + command("variable l1 equal is_typelabel(atom,C2)+is_typelabel(bond,C2-N1)" + "+is_typelabel(bond,[X1][Y1])+is_typelabel(angle,C1-C2-N1)" + "+is_typelabel(dihedral,N2-C1-C1-N2)+is_typelabel(improper,N2-C1-C1-N2)"); + command("variable l2 equal is_typelabel(atom,C1)+is_typelabel(bond,C1-N2)" + "+is_typelabel(bond,[C1][C1])+is_typelabel(angle,C1-N2-C1)" + "+is_typelabel(dihedral,C1-N2-C1-N2)+is_typelabel(improper,C1-N2-C1-N2)"); + END_HIDE_OUTPUT(); ASSERT_THAT(variable->retrieve("t1"), StrEq("1")); @@ -647,6 +661,30 @@ TEST_F(VariableTest, Label2TypeMolecular) ASSERT_THAT(variable->retrieve("a2"), StrEq("2")); ASSERT_THAT(variable->retrieve("d1"), StrEq("1")); ASSERT_THAT(variable->retrieve("i1"), StrEq("1")); + ASSERT_THAT(variable->retrieve("l1"), StrEq("0")); + ASSERT_THAT(variable->retrieve("l2"), StrEq("6")); + + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,N2')"), 1.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(atom,\"N2'\")"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,C1-N2)"), 1.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,C2-N1)"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,[C1][C1])"), 1.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(bond,[X1][Y1])"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(angle,C1-C2-N1)"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(angle,C1-N2-C1)"), 1.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(dihedral,C1-N2-C1-N2)"), 1.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(dihedral,N2-C1-C1-N2)"), 0.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(improper,C1-N2-C1-N2)"), 1.0); + ASSERT_DOUBLE_EQ(variable->compute_equal("is_typelabel(improper,N2-C1-C1-N2)"), 0.0); + + TEST_FAILURE(".*ERROR: Invalid bond type label H1 in label2type.. in variable.*", + variable->compute_equal("label2type(bond,H1)");); + TEST_FAILURE(".*ERROR: Invalid angle type label H1 in label2type.. in variable.*", + variable->compute_equal("label2type(angle,H1)");); + TEST_FAILURE(".*ERROR: Invalid dihedral type label H1 in label2type.. in variable.*", + variable->compute_equal("label2type(dihedral,H1)");); + TEST_FAILURE(".*ERROR: Invalid improper type label H1 in label2type.. in variable.*", + variable->compute_equal("label2type(improper,H1)");); } TEST_F(VariableTest, Format) From 8602ecd57f99da54eefd9f81357bad2ab362f137 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 08:59:36 -0400 Subject: [PATCH 278/448] update/correct docs --- doc/src/variable.rst | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/doc/src/variable.rst b/doc/src/variable.rst index b39fb55caa..ed7d09716b 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -532,7 +532,7 @@ variables. +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Region functions | count(ID,IDR), mass(ID,IDR), charge(ID,IDR), xcm(ID,dim,IDR), vcm(ID,dim,IDR), fcm(ID,dim,IDR), bound(ID,dir,IDR), gyration(ID,IDR), ke(ID,IDR), angmom(ID,dim,IDR), torque(ID,dim,IDR), inertia(ID,dimdim,IDR), omega(ID,dim,IDR) | +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -| Special functions | sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label), is_typelabel(kind,label) | +| Special functions | sum(x), min(x), max(x), ave(x), trap(x), slope(x), gmask(x), rmask(x), grmask(x,y), next(x), is_file(name), is_os(name), extract_setting(name), label2type(kind,label), is_typelabel(kind,label) | +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Feature functions | is_available(category,feature), is_active(category,feature), is_defined(category,id) | +--------------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -996,13 +996,19 @@ via the link in this paragraph. The label2type(kind,label) function converts type labels into numeric types, using label maps created by the :doc:`labelmap ` or -:doc:`read_data ` commands. The first argument is the -label map kind (atom, bond, angle, dihedral, or improper) and the -second argument is the label. The function returns the corresponding -numeric type. The is_typelabel(kind,label) function has the same -arguments, but returns 1 if the type label has been assigned, otherwise -it returns 0. This function can be used to check if a particular type -label already exists in the simulation. +:doc:`read_data ` commands. The first argument is the label +map kind (atom, bond, angle, dihedral, or improper) and the second +argument is the label. The function returns the corresponding numeric +type or -1 in case the specified label for the given kind of type does +not exist. + +.. versionadded:: TBD + +The is_typelabel(kind,label) function has the same arguments as +label2type(), but returns 1 if the type label has been assigned, +otherwise it returns 0. This function can be used to check if a +particular type label already exists in the simulation. It is +equivalent to `(label2type(kind,label)!=-1)`. ---------- From 69c549363171fb98524e49b09ac2461ff079f2eb Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 09:09:35 -0400 Subject: [PATCH 279/448] silence compiler warning --- src/variable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variable.cpp b/src/variable.cpp index 783ceab832..81f0bdcfd6 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -1052,7 +1052,7 @@ char *Variable::retrieve(const char *name) if (vecs[ivar].dynamic || vecs[ivar].currentstep != update->ntimestep) { eval_in_progress[ivar] = 0; double *result; - int nvec = compute_vector(ivar,&result); + compute_vector(ivar,&result); delete[] data[ivar][1]; std::vector vectmp(vecs[ivar].values,vecs[ivar].values + vecs[ivar].n); std::string str = fmt::format("[{}]", fmt::join(vectmp,",")); From 407324141355a499d77316f71fa89b957444c65a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 09:57:19 -0400 Subject: [PATCH 280/448] correct docs about label2type() function --- doc/src/variable.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/doc/src/variable.rst b/doc/src/variable.rst index ed7d09716b..7b49493fef 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -999,16 +999,14 @@ types, using label maps created by the :doc:`labelmap ` or :doc:`read_data ` commands. The first argument is the label map kind (atom, bond, angle, dihedral, or improper) and the second argument is the label. The function returns the corresponding numeric -type or -1 in case the specified label for the given kind of type does -not exist. +type or triggers an error if the queried label does not exist. .. versionadded:: TBD The is_typelabel(kind,label) function has the same arguments as label2type(), but returns 1 if the type label has been assigned, otherwise it returns 0. This function can be used to check if a -particular type label already exists in the simulation. It is -equivalent to `(label2type(kind,label)!=-1)`. +particular type label already exists in the simulation. ---------- From c0602b65000f654bfa8e19619e63ab899342ad88 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 13:20:35 -0400 Subject: [PATCH 281/448] make using energy and potential keyword at the same time an error --- src/fix_efield.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/fix_efield.cpp b/src/fix_efield.cpp index d2c0dc1ef6..d01a498d39 100644 --- a/src/fix_efield.cpp +++ b/src/fix_efield.cpp @@ -58,7 +58,7 @@ FixEfield::FixEfield(LAMMPS *lmp, int narg, char **arg) : virial_global_flag = virial_peratom_flag = 1; qe2f = force->qe2f; - xstr = ystr = zstr = nullptr; + xstyle = ystyle = zstyle = estyle = pstyle = NONE; if (utils::strmatch(arg[3], "^v_")) { xstr = utils::strdup(arg[3] + 2); @@ -113,6 +113,9 @@ FixEfield::FixEfield(LAMMPS *lmp, int narg, char **arg) : } } + if (estr && pstr) + error->all(FLERR, "Must not use energy and potential keywords at the same time with fix efield"); + force_flag = 0; fsum[0] = fsum[1] = fsum[2] = fsum[3] = 0.0; @@ -174,6 +177,7 @@ void FixEfield::init() else error->all(FLERR, "Variable {} for x-field in fix {} is invalid style", xstr, style); } + if (ystr) { yvar = input->variable->find(ystr); if (yvar < 0) error->all(FLERR, "Variable {} for y-field in fix {} does not exist", ystr, style); @@ -184,6 +188,7 @@ void FixEfield::init() else error->all(FLERR, "Variable {} for y-field in fix {} is invalid style", ystr, style); } + if (zstr) { zvar = input->variable->find(zstr); if (zvar < 0) error->all(FLERR, "Variable {} for z-field in fix {} does not exist", zstr, style); @@ -194,6 +199,7 @@ void FixEfield::init() else error->all(FLERR, "Variable {} for z-field in fix {} is invalid style", zstr, style); } + if (estr) { evar = input->variable->find(estr); if (evar < 0) error->all(FLERR, "Variable {} for energy in fix {} does not exist", estr, style); @@ -201,8 +207,8 @@ void FixEfield::init() estyle = ATOM; else error->all(FLERR, "Variable {} for energy in fix {} must be atom-style", estr, style); - } else - estyle = NONE; + } + if (pstr) { pvar = input->variable->find(pstr); if (pvar < 0) error->all(FLERR, "Variable {} for potential in fix {} does not exist", pstr, style); @@ -210,11 +216,7 @@ void FixEfield::init() pstyle = ATOM; else error->all(FLERR, "Variable {} for potential in fix {} must be atom-style", pstr, style); - if (estyle != NONE) - error->warning(FLERR, "fix {} will ignore variable {} for energy " - "because atom-style potential has been specified", estr, style); - } else - pstyle = NONE; + } // set index and check validity of region From cb02563d3d749d46a8ee69dc2c64a6bf27f5c226 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 13:29:41 -0400 Subject: [PATCH 282/448] the potential keyword is not (yet) supported by fix efield/tip4p --- src/EXTRA-FIX/fix_efield_tip4p.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EXTRA-FIX/fix_efield_tip4p.cpp b/src/EXTRA-FIX/fix_efield_tip4p.cpp index 3d6a2f66b7..47b1d9e27a 100644 --- a/src/EXTRA-FIX/fix_efield_tip4p.cpp +++ b/src/EXTRA-FIX/fix_efield_tip4p.cpp @@ -47,6 +47,7 @@ void FixEfieldTIP4P::init() if (atom->tag_enable == 0) error->all(FLERR, "Fix efield/tip4p requires atom IDs"); if (!atom->q_flag) error->all(FLERR, "Fix efield/tip4p requires atom attribute q"); if (!force->pair) error->all(FLERR, "A TIP4P pair style must be defined fix efield/tip4p"); + if (pstr) error->all(FLERR, "Fix efield/tip4p does not support the potential keyword"); int itmp; double *p_qdist = (double *) force->pair->extract("qdist", itmp); From 90000ca166c14c34e59306c7751b6d77ee71a168 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 13:29:48 -0400 Subject: [PATCH 283/448] update docs --- doc/src/fix_efield.rst | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/doc/src/fix_efield.rst b/doc/src/fix_efield.rst index 0b94f80b8c..4cf92cf946 100644 --- a/doc/src/fix_efield.rst +++ b/doc/src/fix_efield.rst @@ -28,7 +28,7 @@ Syntax *energy* value = v_name v_name = variable with name that calculates the potential energy of each atom in the added E-field *potential* value = v_name - v_name = variable with name that calculates the electric potential of each atom in the added E-field (overrides *energy*) + v_name = variable with name that calculates the electric potential of each atom in the added E-field Examples """""""" @@ -136,6 +136,8 @@ due to the electric field were a spring-like F = kx, then the energy formula should be E = -0.5kx\^2. If you don't do this correctly, the minimization will not converge properly. +.. versionadded:: TBD + The *potential* keyword can be used as an alternative to the *energy* keyword to specify the name of an atom-style variable, which is used to compute the added electric potential to each atom as a function of its position. The @@ -144,14 +146,16 @@ in `units real`, the potential should be in volts). As with the *energy* keyword, the variable name is specified as "v_name". The energy added by this fix is then calculated as the electric potential multiplied by charge. -The *potential* keyword is mainly intended for correct charge equilibration -in simulations with :doc:`fix qeq/reaxff`, since with variable -charges the electric potential can be known beforehand but the energy cannot. -A small additional benefit is that the *energy* keyword requires an additional -conversion to energy units which the *potential* keyword avoids. Thus, when the -*potential* keyword is specified, the *energy* keyword is ignored (the simulation -will proceed but with a warning issued). As with *energy*, the *potential* -keyword is not allowed if the added field is a constant vector. +The *potential* keyword is mainly intended for correct charge +equilibration in simulations with :doc:`fix qeq/reaxff`, +since with variable charges the electric potential can be known +beforehand but the energy cannot. A small additional benefit is that +the *energy* keyword requires an additional conversion to energy units +which the *potential* keyword avoids. Thus, when the *potential* +keyword is specified, the *energy* keyword must not be used. As with +*energy*, the *potential* keyword is not allowed if the added field is a +constant vector. The *potential* keyword is not supported by *fix +efield/tip4p*. ---------- From 6138b2b1f78e223c5e0d00d614d5399c3849a8ed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 31 May 2023 13:31:45 -0400 Subject: [PATCH 284/448] fix grammar --- src/variable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/variable.cpp b/src/variable.cpp index 81f0bdcfd6..437e4ac917 100644 --- a/src/variable.cpp +++ b/src/variable.cpp @@ -224,7 +224,7 @@ void Variable::set(int narg, char **arg) if (narg == 5 && strcmp(arg[4],"pad") == 0) { pad[nvar] = fmt::format("{}",nlast).size(); } else pad[nvar] = 0; - } else error->all(FLERR,"Illegal variable loop command: too much arguments"); + } else error->all(FLERR,"Illegal variable loop command: too many arguments"); num[nvar] = nlast; which[nvar] = nfirst-1; data[nvar] = new char*[1]; From cae2414126faa47448a8d7d4822cc5659b2b3241 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Wed, 31 May 2023 13:09:07 -0600 Subject: [PATCH 285/448] Fix compiler warnings in Kokkos ACKS2 --- src/KOKKOS/fix_acks2_reaxff_kokkos.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/KOKKOS/fix_acks2_reaxff_kokkos.h b/src/KOKKOS/fix_acks2_reaxff_kokkos.h index 3e89cb4d43..127c8d0402 100644 --- a/src/KOKKOS/fix_acks2_reaxff_kokkos.h +++ b/src/KOKKOS/fix_acks2_reaxff_kokkos.h @@ -66,10 +66,10 @@ class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF, public KokkosBase { FixACKS2ReaxFFKokkos(class LAMMPS *, int, char **); ~FixACKS2ReaxFFKokkos(); + void init() override; + void setup_pre_force(int) override; + void pre_force(int) override; void cleanup_copy(); - void init(); - void setup_pre_force(int); - void pre_force(int); DAT::tdual_ffloat_1d get_s() {return k_s;} @@ -235,11 +235,11 @@ class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF, public KokkosBase { void init_shielding_k(); void init_hist(); - void allocate_matrix(); + void allocate_matrix() override; void allocate_array(); void deallocate_array(); int bicgstab_solve(); - void calculate_Q(); + void calculate_Q() override; int neighflag; int nlocal,nall,nmax,newton_pair; @@ -251,13 +251,13 @@ class FixACKS2ReaxFFKokkos : public FixACKS2ReaxFF, public KokkosBase { typename AT::t_int_2d d_sendlist; typename AT::t_xfloat_1d_um v_buf; - void grow_arrays(int); - void copy_arrays(int, int, int); + void grow_arrays(int) override; + void copy_arrays(int, int, int) override; void sort_kokkos(Kokkos::BinSort &Sorter) override; - int pack_exchange(int, double *); - int unpack_exchange(int, double *); - void get_chi_field(); - double memory_usage(); + int pack_exchange(int, double *) override; + int unpack_exchange(int, double *) override; + void get_chi_field() override; + double memory_usage() override; void sparse_matvec_acks2(typename AT::t_ffloat_1d &, typename AT::t_ffloat_1d &); }; From a0461d29ddc23485c5995490bdbb126b0e917cfb Mon Sep 17 00:00:00 2001 From: Jacob Gissinger Date: Wed, 31 May 2023 17:04:49 -0400 Subject: [PATCH 286/448] Update atom.cpp --- src/atom.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/atom.cpp b/src/atom.cpp index 3e9e177ae0..08e9639440 100644 --- a/src/atom.cpp +++ b/src/atom.cpp @@ -2130,15 +2130,15 @@ void Atom::add_molecule_atom(Molecule *onemol, int iatom, int ilocal, tagint off // initialize custom per-atom properties to zero if present for (int i = 0; i < nivector; ++i) - if (ivname[i] != nullptr) ivector[i][ilocal] = 0; + if (ivname[i]) ivector[i][ilocal] = 0; for (int i = 0; i < ndvector; ++i) - if (dvname[i] != nullptr) dvector[i][ilocal] = 0.0; + if (dvname[i]) dvector[i][ilocal] = 0.0; for (int i = 0; i < niarray; ++i) - if (ianame[i] != nullptr) + if (ianame[i]) for (int j = 0; j < icols[i]; ++j) iarray[i][ilocal][j] = 0; for (int i = 0; i < ndarray; ++i) - if (daname[i] != nullptr) + if (daname[i]) for (int j = 0; j < dcols[i]; ++j) darray[i][ilocal][j] = 0.0; From ea6ece510edc25cc8f381d7d67e546f62bbd8058 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Thu, 1 Jun 2023 10:22:01 +0300 Subject: [PATCH 287/448] turning warning into errors for unsupported styles --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 9249e4ce2d..0199a49c01 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -205,26 +205,25 @@ void ComputeStressMop::init() if (force->pair->single_enable == 0) error->all(FLERR,"Pair style does not support compute stress/mop"); - // Warnings + // Errors if (me==0) { - //Compute stress/mop only accounts for pair interactions. - // issue a warning if any intramolecular potential or Kspace is defined. + // issue an error for unimplemented intramolecular potentials or Kspace. if (force->bond!=nullptr) bondflag = 1; if (force->angle!=nullptr) if (force->angle->born_matrix_enable == 0) { - error->warning(FLERR,"compute stress/mop does not account for angle potentials"); + error->all(FLERR,"compute stress/mop does not account for angle potentials"); } else { angleflag = 1; } if (force->dihedral!=nullptr) - error->warning(FLERR,"compute stress/mop does not account for dihedral potentials"); + error->all(FLERR,"compute stress/mop does not account for dihedral potentials"); if (force->improper!=nullptr) - error->warning(FLERR,"compute stress/mop does not account for improper potentials"); + error->all(FLERR,"compute stress/mop does not account for improper potentials"); if (force->kspace!=nullptr) - error->warning(FLERR,"compute stress/mop does not account for kspace contributions"); + error->all(FLERR,"compute stress/mop does not account for kspace contributions"); } // need an occasional half neighbor list From b01db47b2d83a5d4656ef279c318c717cfefe192 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Thu, 1 Jun 2023 10:33:50 +0300 Subject: [PATCH 288/448] consistency in issuing errors between mop and mop/profile --- src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index 709f109cb1..ffcc712548 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -178,23 +178,23 @@ void ComputeStressMopProfile::init() if (force->pair->single_enable == 0) error->all(FLERR,"Pair style does not support compute stress/mop/profile"); - // Warnings + // Errors if (me==0) { //Compute stress/mop/profile only accounts for pair interactions. - // issue a warning if any intramolecular potential or Kspace is defined. + // issue an error if any intramolecular potential or Kspace is defined. if (force->bond!=nullptr) - error->warning(FLERR,"compute stress/mop/profile does not account for bond potentials"); + error->all(FLERR,"compute stress/mop/profile does not account for bond potentials"); if (force->angle!=nullptr) - error->warning(FLERR,"compute stress/mop/profile does not account for angle potentials"); + error->all(FLERR,"compute stress/mop/profile does not account for angle potentials"); if (force->dihedral!=nullptr) - error->warning(FLERR,"compute stress/mop/profile does not account for dihedral potentials"); + error->all(FLERR,"compute stress/mop/profile does not account for dihedral potentials"); if (force->improper!=nullptr) - error->warning(FLERR,"compute stress/mop/profile does not account for improper potentials"); + error->all(FLERR,"compute stress/mop/profile does not account for improper potentials"); if (force->kspace!=nullptr) - error->warning(FLERR,"compute stress/mop/profile does not account for kspace contributions"); + error->all(FLERR,"compute stress/mop/profile does not account for kspace contributions"); } // need an occasional half neighbor list From 6bc27db58c2829dab6f13b8cb5e69702a2cd2b36 Mon Sep 17 00:00:00 2001 From: Yifan Li Date: Thu, 1 Jun 2023 06:17:11 -0400 Subject: [PATCH 289/448] do not delete c_pe and c_press in destructor --- src/REPLICA/fix_pimd_langevin.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 67d7cabe02..f9c7772d63 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -344,8 +344,6 @@ FixPIMDLangevin::~FixPIMDLangevin() delete[] id_pe; delete[] id_press; delete random; - delete c_pe; - delete c_press; delete[] mass; delete[] _omega_k; delete[] Lan_c; From f3bf20be8b15a9d82028934f27f33af019ae469e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yifan=20Li=E6=9D=8E=E4=B8=80=E5=B8=86?= Date: Thu, 1 Jun 2023 08:26:02 -0400 Subject: [PATCH 290/448] The first three p_flags for iso should be 1. --- src/REPLICA/fix_pimd_langevin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index f9c7772d63..2e4b1c17b8 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -205,6 +205,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : error->universe_all(FLERR, "Unknown barostat parameter for fix pimd/langevin"); } else if (strcmp(arg[i], "iso") == 0) { pstyle = ISO; + p_flag[0] = p_flag[1] = p_flag[2] = 1; Pext = utils::numeric(FLERR, arg[i + 1], false, lmp); p_target[0] = p_target[1] = p_target[2] = Pext; pdim = 3; From c1cec4565250c5a1b28c850badae0785b140c60d Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Thu, 1 Jun 2023 15:26:43 +0300 Subject: [PATCH 291/448] add keywords to specify contributions to stress/mop --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 0199a49c01..071bdf31ee 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -38,7 +38,7 @@ using namespace LAMMPS_NS; enum{X,Y,Z}; -enum{TOTAL,CONF,KIN}; +enum{TOTAL,CONF,KIN,PAIR,BOND,ANGLE}; #define BIG 1000000000 @@ -115,6 +115,21 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : which[nvalues] = TOTAL; nvalues++; } + } else if (strcmp(arg[iarg],"pair") == 0) { + for (i=0; i<3; i++) { + which[nvalues] = PAIR; + nvalues++; + } + } else if (strcmp(arg[iarg],"bond") == 0) { + for (i=0; i<3; i++) { + which[nvalues] = BOND; + nvalues++; + } + } else if (strcmp(arg[iarg],"angle") == 0) { + for (i=0; i<3; i++) { + which[nvalues] = ANGLE; + nvalues++; + } } else error->all(FLERR, "Illegal compute stress/mop command"); //break; iarg++; @@ -329,7 +344,7 @@ void ComputeStressMop::compute_pairs() m = 0; while (m Date: Thu, 1 Jun 2023 15:34:41 +0300 Subject: [PATCH 292/448] Update compute_stress_mop.rst to reflect the added keywords --- doc/src/compute_stress_mop.rst | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index a8a3bc5660..b4c15257af 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -18,7 +18,7 @@ Syntax * style = *stress/mop* or *stress/mop/profile* * dir = *x* or *y* or *z* is the direction normal to the plane * args = argument specific to the compute style -* keywords = *kin* or *conf* or *total* (one of more can be specified) +* keywords = *kin* or *conf* or *total* or *pair* or *bond* or *angle* (one or more can be specified) .. parsed-literal:: @@ -64,9 +64,11 @@ atoms have crossed the plane if their positions at times :math:`t-\Delta t` and :math:`t` are one on either side of the plane, and uses the velocity at time :math:`t-\Delta t/2` given by the velocity Verlet algorithm. -Between one and three keywords can be used to indicate which -contributions to the stress must be computed: kinetic stress (kin), -configurational stress (conf), and/or total stress (total). +Between one and six keywords can be used to indicate which +contributions to the stress must be computed: total stress (total), kinetic stress (kin), +configurational stress (conf), stress due to bond stretching (bond), +stress due to angle bending (angle) and/or due to pairwise non-bonded interactions (pair). +The last three keywords are currently available only for the stress/mop command and not the stress/mop/profile. NOTE 1: The configurational stress is computed considering all pairs of atoms where at least one atom belongs to group group-ID. From 1189661edc3fa2fe0ecfb54c8fc048bdf0d42b3c Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 1 Jun 2023 21:00:16 +0800 Subject: [PATCH 293/448] revise the code files of standard version based on latest version of LAMMPS --- src/INTERLAYER/pair_ilp_graphene_hbn.cpp | 21 ++++++------- src/INTERLAYER/pair_ilp_graphene_hbn.h | 38 +++++------------------- src/INTERLAYER/pair_ilp_tmd.cpp | 30 +++++++++---------- src/INTERLAYER/pair_ilp_tmd.h | 2 +- src/INTERLAYER/pair_ilp_water_2dm.cpp | 23 +++++++------- src/INTERLAYER/pair_ilp_water_2dm.h | 21 +------------ 6 files changed, 45 insertions(+), 90 deletions(-) diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index 956d7ba2be..401d7f7b12 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 @@ -47,11 +47,11 @@ using namespace InterLayer; static const char cite_ilp[] = "ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848\n" "@Article{Ouyang2018\n" - " author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod},\n" + " author = {W. Ouyang and D. Mandelli and M. Urbakh and O. Hod},\n" " title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials},\n" " journal = {Nano Letters},\n" " volume = 18,\n" - " pages = {6009}\n" + " pages = 6009,\n" " year = 2018,\n" "}\n\n"; @@ -59,10 +59,7 @@ static const char cite_ilp[] = static std::map variant_map = { {PairILPGrapheneHBN::ILP_GrhBN, "ilp/graphene/hbn"}, {PairILPGrapheneHBN::ILP_TMD, "ilp/tmd"}, - {PairILPGrapheneHBN::ILP_PHOSPHORUS, "ilp/phosphorus"}, - {PairILPGrapheneHBN::ILP_WATER_2DM, "ilp/water/2dm"}, - {PairILPGrapheneHBN::SAIP_METAL, "saip/metal"}, - {PairILPGrapheneHBN::SAIP_METAL_TMD, "saip/metal/tmd"}}; + {PairILPGrapheneHBN::SAIP_METAL, "saip/metal"}}; /* ---------------------------------------------------------------------- */ @@ -316,14 +313,14 @@ void PairILPGrapheneHBN::read_file(char *filename) for (int m = 0; m < nparams; m++) { if (i == params[m].ielement && j == params[m].jelement) { if (n >= 0) - error->all(FLERR, "{} potential file {} has a duplicate entry", variant_map[variant], - filename); + error->all(FLERR, "{} potential file {} has a duplicate entry for: {} {}", + variant_map[variant], filename, elements[i], elements[j]); n = m; } } if (n < 0) - error->all(FLERR, "{} potential file {} is missing an entry", variant_map[variant], - filename); + error->all(FLERR, "{} potential file {} is missing an entry for: {} {}", + variant_map[variant], filename, elements[i], elements[j]); elem2param[i][j] = n; cutILPsq[i][j] = params[n].rcut * params[n].rcut; } @@ -652,7 +649,7 @@ void PairILPGrapheneHBN::ILP_neigh() (int **) memory->smalloc(maxlocal * sizeof(int *), "ILPGrapheneHBN:firstneigh"); } - inum = list->inum; // + list->gnum; + inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.h b/src/INTERLAYER/pair_ilp_graphene_hbn.h index 6381fb8f35..9987830b1d 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.h +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 @@ -35,19 +35,11 @@ class PairILPGrapheneHBN : public Pair { double init_one(int, int) override; void init_style() override; void calc_FvdW(int, int); - virtual void calc_FRep(int, int); - virtual void ILP_neigh(); - virtual void calc_normal(); - void read_file(char *); - void allocate(); - double single(int, int, int, int, double, double, double, double &) override; static constexpr int NPARAMS_PER_LINE = 13; - // for telling class variants apart in shared code - enum { ILP_GrhBN, ILP_TMD, SAIP_METAL, - ILP_WATER_2DM, SAIP_METAL_TMD, ILP_PHOSPHORUS }; + enum { ILP_GrhBN, ILP_TMD, SAIP_METAL }; // for telling class variants apart in shared code protected: int me; @@ -59,7 +51,6 @@ class PairILPGrapheneHBN : public Pair { int *ILP_numneigh; // # of pair neighbors for each atom int **ILP_firstneigh; // ptr to 1st neighbor of each atom int tap_flag; // flag to turn on/off taper function - double ncf; // for ilp/phosphorus, coefficients for calcualting the normals struct Param { double z0, alpha, epsilon, C, delta, d, sR, reff, C6, S; @@ -85,28 +76,15 @@ class PairILPGrapheneHBN : public Pair { double ***dpvet1; double ***dpvet2; double ***dNave; + + virtual void ILP_neigh(); + virtual void calc_normal(); + virtual void calc_FRep(int, int); + void read_file(char *); + void allocate(); }; } // namespace LAMMPS_NS #endif #endif - -/* ERROR/WARNING messages: - -E: Illegal ... command - -Self-explanatory. Check the input script syntax and compare to the -documentation for the command. You can use -echo screen as a -command-line option when running LAMMPS to see the offending line. - -E: Incorrect args for pair coefficients - -Self-explanatory. Check the input script or data file. - -E: All pair coeffs are not set - -All pair coefficients must be set in the data file or by the -pair_coeff command before running a simulation. - -*/ diff --git a/src/INTERLAYER/pair_ilp_tmd.cpp b/src/INTERLAYER/pair_ilp_tmd.cpp index d855b9423d..f5636ce3fa 100644 --- a/src/INTERLAYER/pair_ilp_tmd.cpp +++ b/src/INTERLAYER/pair_ilp_tmd.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 @@ -22,14 +22,12 @@ #include "atom.h" #include "citeme.h" -#include "comm.h" #include "error.h" #include "force.h" #include "interlayer_taper.h" #include "memory.h" #include "my_page.h" #include "neigh_list.h" -#include "neighbor.h" #include #include @@ -37,20 +35,22 @@ using namespace LAMMPS_NS; using namespace InterLayer; +#define MAXLINE 1024 #define DELTA 4 #define PGDELTA 1 -static const char cite_ilp_tmd[] = "ilp/tmd potential doi/10.1021/acs.jctc.1c00782\n" - "@Article{Ouyang2021\n" - " author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. " - "Tkatchenko, L. Kronik, M. Urbakh, and O. Hod},\n" - " title = {Anisotropic Interlayer Force Field for Transition " - "Metal Dichalcogenides: The Case of Molybdenum Disulfide},\n" - " journal = {J. Chem. Theory Comput.},\n" - " volume = 17,\n" - " pages = {7237–7245}\n" - " year = 2021,\n" - "}\n\n"; +static const char cite_ilp_tmd[] = + "ilp/tmd potential doi:10.1021/acs.jctc.1c00782\n" + "@Article{Ouyang2021\n" + " author = {W. Ouyang and R. Sofer and X. Gao and J. Hermann and\n" + " A. Tkatchenko and L. Kronik and M. Urbakh and O. Hod},\n" + " title = {Anisotropic Interlayer Force Field for Transition\n" + " Metal Dichalcogenides: The Case of Molybdenum Disulfide},\n" + " journal = {J.~Chem.\\ Theory Comput.},\n" + " volume = 17,\n" + " pages = {7237--7245}\n" + " year = 2021,\n" + "}\n\n"; /* ---------------------------------------------------------------------- */ @@ -249,7 +249,7 @@ void PairILPTMD::ILP_neigh() ILP_firstneigh = (int **) memory->smalloc(maxlocal * sizeof(int *), "ILPTMD:firstneigh"); } - inum = list->inum; //+ list->gnum; + inum = list->inum; ilist = list->ilist; numneigh = list->numneigh; firstneigh = list->firstneigh; diff --git a/src/INTERLAYER/pair_ilp_tmd.h b/src/INTERLAYER/pair_ilp_tmd.h index 8d5446d49c..8381c2e830 100644 --- a/src/INTERLAYER/pair_ilp_tmd.h +++ b/src/INTERLAYER/pair_ilp_tmd.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 diff --git a/src/INTERLAYER/pair_ilp_water_2dm.cpp b/src/INTERLAYER/pair_ilp_water_2dm.cpp index 58e56894f5..2eb50305cc 100644 --- a/src/INTERLAYER/pair_ilp_water_2dm.cpp +++ b/src/INTERLAYER/pair_ilp_water_2dm.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 @@ -22,7 +22,6 @@ #include "atom.h" #include "citeme.h" -#include "comm.h" #include "error.h" #include "force.h" #include "interlayer_taper.h" @@ -30,7 +29,6 @@ #include "my_page.h" #include "neigh_list.h" #include "neigh_request.h" -#include "neighbor.h" #include #include @@ -42,15 +40,16 @@ using namespace InterLayer; #define DELTA 4 #define PGDELTA 1 -static const char cite_ilp_water[] = "ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464\n" - "@Article{Feng2023\n" - " author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang},\n" - " title = {Registry-Dependent Potential for Interfaces of Water with Graphene},\n" - " journal = {J. Phys. Chem. C},\n" - " volume = 127,\n" - " pages = {8704-8713}\n" - " year = 2023,\n" - "}\n\n"; +static const char cite_ilp_water[] = + "ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464\n" + "@Article{Feng2023\n" + " author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang},\n" + " title = {Registry-Dependent Potential for Interfaces of Water with Graphene},\n" + " journal = {J. Phys. Chem. C},\n" + " volume = 127,\n" + " pages = {8704-8713}\n" + " year = 2023,\n" + "}\n\n"; /* ---------------------------------------------------------------------- */ diff --git a/src/INTERLAYER/pair_ilp_water_2dm.h b/src/INTERLAYER/pair_ilp_water_2dm.h index c35d757ea0..fad9f99ff1 100644 --- a/src/INTERLAYER/pair_ilp_water_2dm.h +++ b/src/INTERLAYER/pair_ilp_water_2dm.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 @@ -46,22 +46,3 @@ class PairILPWATER2DM : virtual public PairILPTMD { #endif #endif - -/* ERROR/WARNING messages: - -E: Illegal ... command - -Self-explanatory. Check the input script syntax and compare to the -documentation for the command. You can use -echo screen as a -command-line option when running LAMMPS to see the offending line. - -E: Incorrect args for pair coefficients - -Self-explanatory. Check the input script or data file. - -E: All pair coeffs are not set - -All pair coefficients must be set in the data file or by the -pair_coeff command before running a simulation. - -*/ From 887534fd0211695a2086905ed568d6d0a4da3840 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 1 Jun 2023 21:12:11 +0800 Subject: [PATCH 294/448] fix checkstyle --- src/INTERLAYER/pair_ilp_tmd.cpp | 10 +++++----- src/INTERLAYER/pair_ilp_water_2dm.cpp | 2 +- src/OPT/pair_ilp_graphene_hbn_opt.cpp | 3 +-- src/OPT/pair_ilp_graphene_hbn_opt.h | 2 +- src/OPT/pair_ilp_water_2dm_opt.cpp | 2 +- src/OPT/pair_ilp_water_2dm_opt.h | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/INTERLAYER/pair_ilp_tmd.cpp b/src/INTERLAYER/pair_ilp_tmd.cpp index f5636ce3fa..c1af7098cd 100644 --- a/src/INTERLAYER/pair_ilp_tmd.cpp +++ b/src/INTERLAYER/pair_ilp_tmd.cpp @@ -488,11 +488,11 @@ void PairILPTMD::calc_normal() jH2 = atom->map(tag[i] - 2); iH1 = map[type[jH1]]; iH2 = map[type[jH2]]; - if (strcmp(elements[iH1], "Ow") == 0 ) { + if (strcmp(elements[iH1], "Ow") == 0 ) { vect[0][0] = x[jH1][0] - xtp; vect[0][1] = x[jH1][1] - ytp; vect[0][2] = x[jH1][2] - ztp; - } else if (strcmp(elements[iH2], "Ow") == 0 ) { + } else if (strcmp(elements[iH2], "Ow") == 0 ) { vect[0][0] = x[jH2][0] - xtp; vect[0][1] = x[jH2][1] - ytp; vect[0][2] = x[jH2][2] - ztp; @@ -518,7 +518,7 @@ void PairILPTMD::calc_normal() // Calculte dNave/dri, defined as dpvdri for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { - if (ip == id) { dpvdri[id][ip] = -1.0;} + if (ip == id) { dpvdri[id][ip] = -1.0;} else {dpvdri[id][ip] = 0.0;} } } @@ -682,12 +682,12 @@ void PairILPTMD::calc_normal() normal[i][2] = Nave[2] / nn; // derivatives of non-normalized normal vector, dNave:3xcontx3 array - // dNave[id][m][ip]: the derivatve of the id component of Nave + // dNave[id][m][ip]: the derivatve of the id component of Nave // respect to the ip component of atom m for (id = 0; id < 3; id++) { for (ip = 0; ip < 3; ip++) { for (m = 0; m < cont; m++) { - if (ip == id) { dNave[id][m][ip] = 0.5;} + if (ip == id) { dNave[id][m][ip] = 0.5;} else {dNave[id][m][ip] = 0.0;} } } diff --git a/src/INTERLAYER/pair_ilp_water_2dm.cpp b/src/INTERLAYER/pair_ilp_water_2dm.cpp index 2eb50305cc..3747d249de 100644 --- a/src/INTERLAYER/pair_ilp_water_2dm.cpp +++ b/src/INTERLAYER/pair_ilp_water_2dm.cpp @@ -40,7 +40,7 @@ using namespace InterLayer; #define DELTA 4 #define PGDELTA 1 -static const char cite_ilp_water[] = +static const char cite_ilp_water[] = "ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464\n" "@Article{Feng2023\n" " author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang},\n" diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.cpp b/src/OPT/pair_ilp_graphene_hbn_opt.cpp index 63822ad4c6..e8cb205a52 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.cpp +++ b/src/OPT/pair_ilp_graphene_hbn_opt.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 @@ -471,7 +471,6 @@ inline void deriv_hat(double dnhatdn[3][3], double *n, double rnnorm, double fac dnhatdn[0][2] = -n[0]*n[2]*cfactor; dnhatdn[1][2] = -n[1]*n[2]*cfactor; dnhatdn[2][2] = (n[0]*n[0]+n[1]*n[1])*cfactor; - } inline double normalize_factor(double *n) { diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.h b/src/OPT/pair_ilp_graphene_hbn_opt.h index bc22ab22b0..41d2178092 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.h +++ b/src/OPT/pair_ilp_graphene_hbn_opt.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 diff --git a/src/OPT/pair_ilp_water_2dm_opt.cpp b/src/OPT/pair_ilp_water_2dm_opt.cpp index 6cdac00ed9..316551c345 100644 --- a/src/OPT/pair_ilp_water_2dm_opt.cpp +++ b/src/OPT/pair_ilp_water_2dm_opt.cpp @@ -1,7 +1,7 @@ /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 diff --git a/src/OPT/pair_ilp_water_2dm_opt.h b/src/OPT/pair_ilp_water_2dm_opt.h index 25905643af..8062de880a 100644 --- a/src/OPT/pair_ilp_water_2dm_opt.h +++ b/src/OPT/pair_ilp_water_2dm_opt.h @@ -1,7 +1,7 @@ /* -*- c++ -*- ---------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov + 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 From a4f4f965e3f1688d0e7da135c8809081a4e6083a Mon Sep 17 00:00:00 2001 From: oywg11 Date: Thu, 1 Jun 2023 21:45:52 +0800 Subject: [PATCH 295/448] fix a bug in the codes --- src/INTERLAYER/pair_ilp_graphene_hbn.cpp | 1 + src/INTERLAYER/pair_ilp_graphene_hbn.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index 401d7f7b12..6d7526e3dd 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -59,6 +59,7 @@ static const char cite_ilp[] = static std::map variant_map = { {PairILPGrapheneHBN::ILP_GrhBN, "ilp/graphene/hbn"}, {PairILPGrapheneHBN::ILP_TMD, "ilp/tmd"}, + {PairILPGrapheneHBN::ILP_WATER_2DM, "ilp/water/2dm"}, {PairILPGrapheneHBN::SAIP_METAL, "saip/metal"}}; /* ---------------------------------------------------------------------- */ diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.h b/src/INTERLAYER/pair_ilp_graphene_hbn.h index 9987830b1d..e27fce420a 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.h +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.h @@ -39,7 +39,7 @@ class PairILPGrapheneHBN : public Pair { static constexpr int NPARAMS_PER_LINE = 13; - enum { ILP_GrhBN, ILP_TMD, SAIP_METAL }; // for telling class variants apart in shared code + enum { ILP_GrhBN, ILP_TMD, SAIP_METAL, ILP_WATER_2DM }; // for telling class variants apart in shared code protected: int me; From 08ffd268bff9734217ea14be6d223810fd983991 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 2 Jun 2023 09:43:58 +0300 Subject: [PATCH 296/448] remove unused symbolic constant --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 071bdf31ee..3ae758b875 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -40,8 +40,6 @@ using namespace LAMMPS_NS; enum{X,Y,Z}; enum{TOTAL,CONF,KIN,PAIR,BOND,ANGLE}; -#define BIG 1000000000 - /* ---------------------------------------------------------------------- */ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : From 8ef4e933b25610a841a8107412cdb7a69cbb50da Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 2 Jun 2023 10:17:38 -0600 Subject: [PATCH 297/448] Fix bug when Kokkos border comm is on host --- src/KOKKOS/comm_kokkos.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/comm_kokkos.cpp b/src/KOKKOS/comm_kokkos.cpp index 7d007a666c..b0394821fc 100644 --- a/src/KOKKOS/comm_kokkos.cpp +++ b/src/KOKKOS/comm_kokkos.cpp @@ -980,9 +980,9 @@ void CommKokkos::borders() } else { atomKK->sync(Host,ALL_MASK); k_sendlist.sync(); - CommBrick::borders(); k_sendlist.modify(); - atomKK->modified(Host,ALL_MASK); + atomKK->modified(Host,ALL_MASK); // needed here for atom map + CommBrick::borders(); } if (comm->nprocs == 1 && !ghost_velocity && !forward_comm_classic) From 70507462e9e04e8466e9e7c48a56f065235f871d Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 2 Jun 2023 19:22:28 +0300 Subject: [PATCH 298/448] Include method for bond contribution & variables to compute_stress_mop_profile.h --- src/EXTRA-COMPUTE/compute_stress_mop_profile.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.h b/src/EXTRA-COMPUTE/compute_stress_mop_profile.h index b58f762c12..7bb87fa4c6 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.h +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.h @@ -38,16 +38,20 @@ class ComputeStressMopProfile : public Compute { private: void compute_pairs(); + void compute_bonds(); void setup_bins(); int me, nvalues, dir; int *which; + int bondflag; + int originflag; double origin, delta, offset, invdelta; int nbins; double **coord, **coordp; double **values_local, **values_global; + double **bond_local, **bond_global; double dt, nktv2p, ftm2v; double area; From e7ae02dd2a53b12f8b6de5eabea4d9750d98b085 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 2 Jun 2023 19:33:15 +0300 Subject: [PATCH 299/448] Code for bond contribution to stress/mop/profile --- .../compute_stress_mop_profile.cpp | 169 +++++++++++++++++- 1 file changed, 162 insertions(+), 7 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index ffcc712548..d15067a266 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -19,8 +19,11 @@ #include "compute_stress_mop_profile.h" #include "atom.h" +#include "atom_vec.h" +#include "bond.h" #include "update.h" #include "domain.h" +#include "molecule.h" #include "neighbor.h" #include "force.h" #include "pair.h" @@ -35,9 +38,7 @@ using namespace LAMMPS_NS; enum{X,Y,Z}; enum{LOWER,CENTER,UPPER,COORD}; -enum{TOTAL,CONF,KIN}; - -#define BIG 1000000000 +enum{TOTAL,CONF,KIN,PAIR,BOND}; /* ---------------------------------------------------------------------- */ @@ -48,6 +49,8 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a MPI_Comm_rank(world,&me); + bondflag = 0; + // set compute mode and direction of plane(s) for pressure calculation if (strcmp(arg[3],"x")==0) { @@ -92,6 +95,16 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a which[nvalues] = TOTAL; nvalues++; } + } else if (strcmp(arg[iarg],"pair") == 0) { + for (i=0; i<3; i++) { + which[nvalues] = PAIR; + nvalues++; + } + } else if (strcmp(arg[iarg],"bond") == 0) { + for (i=0; i<3; i++) { + which[nvalues] = PAIR; + nvalues++; + } } else error->all(FLERR, "Illegal compute stress/mop/profile command"); //break; iarg++; @@ -114,6 +127,8 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a nbins = 0; coord = coordp = nullptr; values_local = values_global = array = nullptr; + bond_local = nullptr; + bond_global = nullptr; // bin setup @@ -140,6 +155,8 @@ ComputeStressMopProfile::~ComputeStressMopProfile() memory->destroy(coordp); memory->destroy(values_local); memory->destroy(values_global); + memory->destroy(bond_local); + memory->destroy(bond_global); memory->destroy(array); } @@ -185,8 +202,8 @@ void ComputeStressMopProfile::init() //Compute stress/mop/profile only accounts for pair interactions. // issue an error if any intramolecular potential or Kspace is defined. - if (force->bond!=nullptr) - error->all(FLERR,"compute stress/mop/profile does not account for bond potentials"); + if (force->bond!=nullptr) bondflag = 1; + if (force->angle!=nullptr) error->all(FLERR,"compute stress/mop/profile does not account for angle potentials"); if (force->dihedral!=nullptr) @@ -225,6 +242,21 @@ void ComputeStressMopProfile::compute_array() MPI_Allreduce(&values_local[0][0],&values_global[0][0],nbins*nvalues, MPI_DOUBLE,MPI_SUM,world); + if (bondflag) { + //Compute bond contribution on separate procs + compute_bonds(); + } else { + for (int m = 0; m < nbins; m++) { + for (int i = 0; i < nvalues; i++) { + bond_local[m][i] = 0.0; + } + } + } + + // sum bond contribution over all procs + MPI_Allreduce(&bond_local[0][0],&bond_global[0][0],nbins*nvalues, + MPI_DOUBLE,MPI_SUM,world); + int ibin,m,mo; for (ibin=0; ibinx; + tagint *tag = atom->tag; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + int *mask = atom->mask; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + int molecular = atom->molecular; + + Bond *bond = force->bond; + + double dx[3] {0}; + double x_bond_1[3] {0}; + double x_bond_2[3] {0}; + double local_contribution[nbins][3] {0}; + + // initialization + for (int m {0}; m < nbins; m++) { + for (int i {0}; i < nvalues; i++) { + bond_local[m][i] = 0.0; + } + } + + // loop over all bonded atoms in the current proc + for (atom1 = 0; atom1 < nlocal; atom1++) { + if (!(mask[atom1] & groupbit)) continue; + + if (molecular == 1) + nb = num_bond[atom1]; + else { + if (molindex[atom1] < 0) continue; + imol = molindex[atom1]; + iatom = molatom[atom1]; + nb = onemols[imol]->num_bond[iatom]; + } + + for (i = 0; i < nb; i++) { + if (molecular == 1) { + btype = bond_type[atom1][i]; + atom2 = atom->map(bond_atom[atom1][i]); + } else { + tagprev = tag[atom1] - iatom - 1; + btype = onemols[imol]->bond_type[iatom][i]; + atom2 = atom->map(onemols[imol]->bond_atom[iatom][i] + tagprev); + } + + if (atom2 < 0 || !(mask[atom2] & groupbit)) continue; + if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; + if (btype <= 0) continue; + + for (int ibin {0}; ibinminimum_image(dx[0], dx[1], dx[2]); + x_bond_1[0] = dx[0]; + x_bond_1[1] = dx[1]; + x_bond_1[2] = dx[2]; + x_bond_1[dir] += pos; + + // minimum image of atom2 with respect to atom1 + dx[0] = x[atom2][0] - x_bond_1[0]; + dx[1] = x[atom2][1] - x_bond_1[1]; + dx[2] = x[atom2][2] - x_bond_1[2]; + domain->minimum_image(dx[0], dx[1], dx[2]); + x_bond_2[0] = x_bond_1[0] + dx[0]; + x_bond_2[1] = x_bond_1[1] + dx[1]; + x_bond_2[2] = x_bond_1[2] + dx[2]; + + // check if the bond vector crosses the plane of interest + double tau = (x_bond_1[dir] - pos) / (x_bond_1[dir] - x_bond_2[dir]); + if ((tau <= 1) && (tau >= 0)) { + dx[0] = x_bond_1[0] - x_bond_2[0]; + dx[1] = x_bond_1[1] - x_bond_2[1]; + dx[2] = x_bond_1[2] - x_bond_2[2]; + rsq = dx[0] * dx[0] + dx[1] * dx[1] + dx[2] * dx[2]; + bond->single(btype, rsq, atom1, atom2, fpair); + + double sgn = copysign(1.0, x_bond_1[dir] - pos); + local_contribution[ibin][0] += sgn*fpair*dx[0]/area*nktv2p; + local_contribution[ibin][1] += sgn*fpair*dx[1]/area*nktv2p; + local_contribution[ibin][2] += sgn*fpair*dx[2]/area*nktv2p; + } + } + } + } + + // loop over the keywords and if necessary add the bond contribution + int m {0}; + while (mcreate(coordp,nbins,1,"stress/mop/profile:coordp"); memory->create(values_local,nbins,nvalues,"stress/mop/profile:values_local"); memory->create(values_global,nbins,nvalues,"stress/mop/profile:values_global"); + memory->create(bond_local,nbins,nvalues,"stress/mop/profile:bond_local"); + memory->create(bond_global,nbins,nvalues,"stress/mop/profile:bond_global"); // set bin coordinates for (i = 0; i < nbins; i++) { From c30762ca8bfd35bb8554e2024ea57462298fa2e5 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 2 Jun 2023 19:44:37 +0300 Subject: [PATCH 300/448] Update documentation for compute stress/mop/profile --- doc/src/compute_stress_mop.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index b4c15257af..e1b151ebbd 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -68,7 +68,7 @@ Between one and six keywords can be used to indicate which contributions to the stress must be computed: total stress (total), kinetic stress (kin), configurational stress (conf), stress due to bond stretching (bond), stress due to angle bending (angle) and/or due to pairwise non-bonded interactions (pair). -The last three keywords are currently available only for the stress/mop command and not the stress/mop/profile. +The angle keyword is currently available only for the stress/mop command and not the stress/mop/profile. NOTE 1: The configurational stress is computed considering all pairs of atoms where at least one atom belongs to group group-ID. @@ -120,8 +120,8 @@ size does not change in time, and axis-aligned planes. The method only works with two-body pair interactions, because it requires the class method pair->single() to be implemented. In particular, compute *stress/mop/profile* does not work with more than -two-body pair interactions, intra-molecular interactions, and long range -(kspace) interactions. Similarly, compute *stress/mop* does not work with more than +two-body pair interactions, long range (kspace) interactions and angle/dihedral/improper +intramolecular interactions. Similarly, compute *stress/mop* does not work with more than two-body pair interactions, long range (kspace) interactions and dihedral/improper intramolecular interactions but works with all bond interactions with the class method single() implemented and all angle interactions with the class method born_matrix() From 28e3a741a8e84d7512e10c34364ac198cf456266 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 2 Jun 2023 20:02:52 +0300 Subject: [PATCH 301/448] declare local_contribution as pointer in compute_stress_mop_profile.h --- src/EXTRA-COMPUTE/compute_stress_mop_profile.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.h b/src/EXTRA-COMPUTE/compute_stress_mop_profile.h index 7bb87fa4c6..1015d6e3eb 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.h +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.h @@ -52,6 +52,7 @@ class ComputeStressMopProfile : public Compute { double **coord, **coordp; double **values_local, **values_global; double **bond_local, **bond_global; + double **local_contribution; double dt, nktv2p, ftm2v; double area; From 9dc1f45e1e7df4915740479fb29bd1944c99aecf Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 2 Jun 2023 20:08:59 +0300 Subject: [PATCH 302/448] Create/destroy local_contribution --- src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index d15067a266..3a60342887 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -129,6 +129,7 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a values_local = values_global = array = nullptr; bond_local = nullptr; bond_global = nullptr; + local_contribution = nullptr; // bin setup @@ -157,6 +158,7 @@ ComputeStressMopProfile::~ComputeStressMopProfile() memory->destroy(values_global); memory->destroy(bond_local); memory->destroy(bond_global); + memory->destroy(local_contribution); memory->destroy(array); } @@ -514,13 +516,15 @@ void ComputeStressMopProfile::compute_bonds() double dx[3] {0}; double x_bond_1[3] {0}; double x_bond_2[3] {0}; - double local_contribution[nbins][3] {0}; // initialization for (int m {0}; m < nbins; m++) { for (int i {0}; i < nvalues; i++) { bond_local[m][i] = 0.0; } + local_contribution[m][0] = 0.0; + local_contribution[m][1] = 0.0; + local_contribution[m][2] = 0.0; } // loop over all bonded atoms in the current proc @@ -647,6 +651,7 @@ void ComputeStressMopProfile::setup_bins() memory->create(values_global,nbins,nvalues,"stress/mop/profile:values_global"); memory->create(bond_local,nbins,nvalues,"stress/mop/profile:bond_local"); memory->create(bond_global,nbins,nvalues,"stress/mop/profile:bond_global"); + memory->create(local_contribution,nbins,3,"stress/mop/profile:local_contribution"); // set bin coordinates for (i = 0; i < nbins; i++) { From 390888179fa2282ac9cd60f5eb5745260708d1a3 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Fri, 2 Jun 2023 20:24:32 +0300 Subject: [PATCH 303/448] Update compute_stress_mop_profile.cpp --- src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index 3a60342887..d299633731 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -102,7 +102,7 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a } } else if (strcmp(arg[iarg],"bond") == 0) { for (i=0; i<3; i++) { - which[nvalues] = PAIR; + which[nvalues] = BOND; nvalues++; } } else error->all(FLERR, "Illegal compute stress/mop/profile command"); //break; From 40cd3bbdc4f976790f484fdb1b560179cfb9096b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 2 Jun 2023 16:29:10 -0400 Subject: [PATCH 304/448] add cache line size padding to avoid false sharing with OPENMP package --- src/my_page.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/my_page.h b/src/my_page.h index 6c06abd71e..ea19dc8e74 100644 --- a/src/my_page.h +++ b/src/my_page.h @@ -104,6 +104,9 @@ template class MyPage { int errorflag; // flag > 0 if error has occurred // 1 = chunk size exceeded maxchunk // 2 = memory allocation error +#if defined(_OPENMP) + char pad[64]; // to avoid false sharing with multi-threading +#endif void allocate(); void deallocate(); }; From 241f3b751e38df598b5d32c6f9bf9812e05c24d2 Mon Sep 17 00:00:00 2001 From: jtclemm Date: Fri, 2 Jun 2023 15:45:53 -0600 Subject: [PATCH 305/448] Unifying syntax for BPM bond options --- doc/src/bond_bpm_rotational.rst | 12 ++++++------ doc/src/bond_bpm_spring.rst | 14 +++++++------- src/BPM/bond_bpm.cpp | 8 +++++--- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/doc/src/bond_bpm_rotational.rst b/doc/src/bond_bpm_rotational.rst index 0baf7e35b1..ca12d86ccc 100644 --- a/doc/src/bond_bpm_rotational.rst +++ b/doc/src/bond_bpm_rotational.rst @@ -24,7 +24,7 @@ Syntax *x, y, z* = the center of mass position of the 2 atoms when the bond broke (distance units) *x/ref, y/ref, z/ref* = the initial center of mass position of the 2 atoms (distance units) - *overlay/pair* value = none + *overlay/pair* value = *yes* or *no* bonded particles will still interact with pair forces *smooth* value = *yes* or *no* @@ -33,8 +33,8 @@ Syntax *normalize* value = *yes* or *no* normalizes normal and shear forces by the reference length - *break/no* - indicates that bonds should not break during a run + *break* value = *yes* or *no* + indicates whether bonds break during a run Examples """""""" @@ -144,14 +144,14 @@ by :math:`r_0` such that :math:`k_r` and :math:`k_s` are unit less. By default, pair forces are not calculated between bonded particles. Pair forces can alternatively be overlaid on top of bond forces using -the *overlay/pair* keyword. These settings require specific +the *overlay/pair* option. These settings require specific :doc:`special_bonds ` settings described in the restrictions. Further details can be found in the `:doc: how to ` page on BPMs. .. versionadded:: 28Mar2023 -If the *break/no* keyword is used, then LAMMPS assumes bonds should not break +If the *break* option is used, then LAMMPS assumes bonds should not break during a simulation run. This will prevent some unnecessary calculation. However, if a bond does break, it will trigger an error. @@ -257,7 +257,7 @@ Related commands Default """"""" -The option defaults are *smooth* = *yes* +The option defaults are *overlay/pair* = *no*, *smooth* = *yes*, *normalize* = *no*, and *break* = *yes* ---------- diff --git a/doc/src/bond_bpm_spring.rst b/doc/src/bond_bpm_spring.rst index 6da0d25a4a..d89035dcad 100644 --- a/doc/src/bond_bpm_spring.rst +++ b/doc/src/bond_bpm_spring.rst @@ -24,17 +24,17 @@ Syntax *x, y, z* = the center of mass position of the 2 atoms when the bond broke (distance units) *x/ref, y/ref, z/ref* = the initial center of mass position of the 2 atoms (distance units) - *overlay/pair* value = none + *overlay/pair* value = *yes* or *no* bonded particles will still interact with pair forces *smooth* value = *yes* or *no* smooths bond forces near the breaking point *normalize* value = *yes* or *no* - normalizes bond forces by their reference length + normalizes bond forces by the reference length - *break/no* - indicates that bonds should not break during a run + *break* value = *yes* or *no* + indicates whether bonds break during a run Examples """""""" @@ -110,14 +110,14 @@ However, the *normalize* option will normalize the elastic bond force by By default, pair forces are not calculated between bonded particles. Pair forces can alternatively be overlaid on top of bond forces using -the *overlay/pair* keyword. These settings require specific +the *overlay/pair* option. These settings require specific :doc:`special_bonds ` settings described in the restrictions. Further details can be found in the `:doc: how to ` page on BPMs. .. versionadded:: 28Mar2023 -If the *break/no* keyword is used, then LAMMPS assumes bonds should not break +If the *break* option is used, then LAMMPS assumes bonds should not break during a simulation run. This will prevent some unnecessary calculation. However, if a bond does break, it will trigger an error. @@ -212,7 +212,7 @@ Related commands Default """"""" -The option defaults are *smooth* = *yes* +The option defaults are *overlay/pair* = *no*, *smooth* = *yes*, *normalize* = *no*, and *break* = *yes* ---------- diff --git a/src/BPM/bond_bpm.cpp b/src/BPM/bond_bpm.cpp index a68aea3e68..da189ccaf5 100644 --- a/src/BPM/bond_bpm.cpp +++ b/src/BPM/bond_bpm.cpp @@ -187,10 +187,12 @@ void BondBPM::settings(int narg, char **arg) iarg++; } } else if (strcmp(arg[iarg], "overlay/pair") == 0) { - overlay_flag = 1; + if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command, missing option for overlay/pair"); + overlay_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); iarg++; - } else if (strcmp(arg[iarg], "break/no") == 0) { - break_flag = 0; + } else if (strcmp(arg[iarg], "break") == 0) { + if (iarg + 1 > narg) error->all(FLERR, "Illegal bond bpm command, missing option for break"); + break_flag = utils::logical(FLERR, arg[iarg + 1], false, lmp); iarg++; } else { leftover_iarg.push_back(iarg); From a42bfb0e26e8391076719f36a425c5d41ca41a23 Mon Sep 17 00:00:00 2001 From: rohskopf Date: Fri, 2 Jun 2023 17:26:40 -0600 Subject: [PATCH 306/448] Make cutoff factor 1 instead of 0 to prevent zero valued descriptors --- src/KOKKOS/sna_kokkos_impl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/sna_kokkos_impl.h b/src/KOKKOS/sna_kokkos_impl.h index fd58f1c4f3..d5690ea60a 100644 --- a/src/KOKKOS/sna_kokkos_impl.h +++ b/src/KOKKOS/sna_kokkos_impl.h @@ -2298,7 +2298,7 @@ void SNAKokkos::compute_s_dsfac(const real constexpr real_type zero = static_cast(0.0); constexpr real_type onehalf = static_cast(0.5); - if (switch_flag == 0) { sfac_outer = zero; dsfac_outer = zero; } + if (switch_flag == 0) { sfac_outer = one; dsfac_outer = zero; } else if (switch_flag == 1) { if (r <= rmin0) { sfac_outer = one; dsfac_outer = zero; } else if (r > rcut) { sfac = zero; dsfac = zero; return; } From 250eac93dccb4057e2abec357496624e1c3fbbee Mon Sep 17 00:00:00 2001 From: Xin Wu Date: Sat, 3 Jun 2023 07:34:39 +0200 Subject: [PATCH 307/448] fix bug in the reaxff HNS benchmark --- examples/reaxff/HNS/in.reaxc.hns | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/reaxff/HNS/in.reaxc.hns b/examples/reaxff/HNS/in.reaxc.hns index 775a389eca..5b83698917 100644 --- a/examples/reaxff/HNS/in.reaxc.hns +++ b/examples/reaxff/HNS/in.reaxc.hns @@ -37,4 +37,4 @@ velocity all create 300.0 41279 loop geom fix 1 all nve fix 2 all qeq/reax 1 0.0 10.0 1e-6 reax/c -run 100 +run $t From 2e7ca5f65cc8fd421a04b324a6815953e1641d37 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 18:14:45 +0800 Subject: [PATCH 308/448] rename the pair style --- .../{pair_ilp_water_2dm.cpp => pair_aip_water_2dm.cpp} | 0 src/INTERLAYER/{pair_ilp_water_2dm.h => pair_aip_water_2dm.h} | 0 src/INTERLAYER/pair_ilp_graphene_hbn.cpp | 2 +- src/INTERLAYER/pair_ilp_graphene_hbn.h | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) rename src/INTERLAYER/{pair_ilp_water_2dm.cpp => pair_aip_water_2dm.cpp} (100%) rename src/INTERLAYER/{pair_ilp_water_2dm.h => pair_aip_water_2dm.h} (100%) diff --git a/src/INTERLAYER/pair_ilp_water_2dm.cpp b/src/INTERLAYER/pair_aip_water_2dm.cpp similarity index 100% rename from src/INTERLAYER/pair_ilp_water_2dm.cpp rename to src/INTERLAYER/pair_aip_water_2dm.cpp diff --git a/src/INTERLAYER/pair_ilp_water_2dm.h b/src/INTERLAYER/pair_aip_water_2dm.h similarity index 100% rename from src/INTERLAYER/pair_ilp_water_2dm.h rename to src/INTERLAYER/pair_aip_water_2dm.h diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index 6d7526e3dd..e6711d0f19 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -59,7 +59,7 @@ static const char cite_ilp[] = static std::map variant_map = { {PairILPGrapheneHBN::ILP_GrhBN, "ilp/graphene/hbn"}, {PairILPGrapheneHBN::ILP_TMD, "ilp/tmd"}, - {PairILPGrapheneHBN::ILP_WATER_2DM, "ilp/water/2dm"}, + {PairILPGrapheneHBN::AIP_WATER_2DM, "aip/water/2dm"}, {PairILPGrapheneHBN::SAIP_METAL, "saip/metal"}}; /* ---------------------------------------------------------------------- */ diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.h b/src/INTERLAYER/pair_ilp_graphene_hbn.h index e27fce420a..e151ecc801 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.h +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.h @@ -39,7 +39,7 @@ class PairILPGrapheneHBN : public Pair { static constexpr int NPARAMS_PER_LINE = 13; - enum { ILP_GrhBN, ILP_TMD, SAIP_METAL, ILP_WATER_2DM }; // for telling class variants apart in shared code + enum { ILP_GrhBN, ILP_TMD, SAIP_METAL, AIP_WATER_2DM }; // for telling class variants apart in shared code protected: int me; From 8c6e2ca000b7ad201c3c2676582832066343fc00 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 20:34:42 +0800 Subject: [PATCH 309/448] rename the opt pair style --- ...2dm_opt.cpp => pair_aip_water_2dm_opt.cpp} | 0 ...ter_2dm_opt.h => pair_aip_water_2dm_opt.h} | 0 src/OPT/pair_ilp_graphene_hbn_opt.cpp | 24 +++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) rename src/OPT/{pair_ilp_water_2dm_opt.cpp => pair_aip_water_2dm_opt.cpp} (100%) rename src/OPT/{pair_ilp_water_2dm_opt.h => pair_aip_water_2dm_opt.h} (100%) diff --git a/src/OPT/pair_ilp_water_2dm_opt.cpp b/src/OPT/pair_aip_water_2dm_opt.cpp similarity index 100% rename from src/OPT/pair_ilp_water_2dm_opt.cpp rename to src/OPT/pair_aip_water_2dm_opt.cpp diff --git a/src/OPT/pair_ilp_water_2dm_opt.h b/src/OPT/pair_aip_water_2dm_opt.h similarity index 100% rename from src/OPT/pair_ilp_water_2dm_opt.h rename to src/OPT/pair_aip_water_2dm_opt.h diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.cpp b/src/OPT/pair_ilp_graphene_hbn_opt.cpp index e8cb205a52..b2abcec7be 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.cpp +++ b/src/OPT/pair_ilp_graphene_hbn_opt.cpp @@ -169,33 +169,33 @@ void PairILPGrapheneHBNOpt::compute(int eflag, int vflag) } } } - } else if (variant == ILP_WATER_2DM) { + } else if (variant == AIP_WATER_2DM) { if (eflag_global || eflag_atom) { if (vflag_either) { if (tap_flag) { - eval<6, 1, 1, 1, ILP_WATER_2DM>(); + eval<6, 1, 1, 1, AIP_WATER_2DM>(); } else { - eval<6, 1, 1, 0, ILP_WATER_2DM>(); + eval<6, 1, 1, 0, AIP_WATER_2DM>(); } } else { if (tap_flag) { - eval<6, 1, 0, 1, ILP_WATER_2DM>(); + eval<6, 1, 0, 1, AIP_WATER_2DM>(); } else { - eval<6, 1, 0, 0, ILP_WATER_2DM>(); + eval<6, 1, 0, 0, AIP_WATER_2DM>(); } } } else { if (vflag_either) { if (tap_flag) { - eval<6, 0, 1, 1, ILP_WATER_2DM>(); + eval<6, 0, 1, 1, AIP_WATER_2DM>(); } else { - eval<6, 0, 1, 0, ILP_WATER_2DM>(); + eval<6, 0, 1, 0, AIP_WATER_2DM>(); } } else { if (tap_flag) { - eval<6, 0, 0, 1, ILP_WATER_2DM>(); + eval<6, 0, 0, 1, AIP_WATER_2DM>(); } else { - eval<6, 0, 0, 0, ILP_WATER_2DM>(); + eval<6, 0, 0, 0, AIP_WATER_2DM>(); } } } @@ -286,7 +286,7 @@ void PairILPGrapheneHBNOpt::eval() rsq = delx * delx + dely * dely + delz * delz; if (rsq != 0 && rsq < cutILPsq[itype_map][jtype]) { - if ((VARIANT == ILP_TMD || VARIANT == ILP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue; + if ((VARIANT == ILP_TMD || VARIANT == AIP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue; if (ILP_nneigh >= MAX_NNEIGH) { error->one(FLERR, "There are too many neighbors for calculating normals"); } @@ -519,8 +519,8 @@ void PairILPGrapheneHBNOpt::calc_normal(int i, int itype, int *ILP_neigh, int nn vet[jj][2] = x[j][2] - x[i][2]; } - //specialize for ILP_WATER_2DM for hydrogen has special normal vector rule - if (variant == ILP_WATER_2DM && special_type[itype] == WATER) { + //specialize for AIP_WATER_2DM for hydrogen has special normal vector rule + if (variant == AIP_WATER_2DM && special_type[itype] == WATER) { if (nneigh == 1){ n[0] = vet[0][0]; n[1] = vet[0][1]; From a25100120bf59ac93f772b4ae158d9f1a8508304 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 20:36:12 +0800 Subject: [PATCH 310/448] update the doc file --- doc/src/{pair_ilp_water_2dm.rst => pair_aip_water_2dm.rst} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename doc/src/{pair_ilp_water_2dm.rst => pair_aip_water_2dm.rst} (100%) diff --git a/doc/src/pair_ilp_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst similarity index 100% rename from doc/src/pair_ilp_water_2dm.rst rename to doc/src/pair_aip_water_2dm.rst From d85342cd6da16eded485da0e544bc35eddf35b94 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sat, 3 Jun 2023 16:04:40 +0300 Subject: [PATCH 311/448] Update test_compute_global.cpp --- unittest/commands/test_compute_global.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/commands/test_compute_global.cpp b/unittest/commands/test_compute_global.cpp index 66a24f049f..04913f51b5 100644 --- a/unittest/commands/test_compute_global.cpp +++ b/unittest/commands/test_compute_global.cpp @@ -169,7 +169,7 @@ TEST_F(ComputeGlobalTest, Geometry) command("compute mom1 all momentum"); command("compute mom2 allwater momentum"); command("compute mop1 all stress/mop x 0.0 total"); - command("compute mop2 all stress/mop/profile z lower 0.5 kin conf"); + command("compute mop2 all stress/mop/profile z lower 0.5 kin pair"); thermo_style += " c_mu1 c_mu2 c_mop1[*] c_mop2[1][1]"; } From 738a955c4012397c0fadcbac740a6f48ad3d8909 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 22:37:57 +0800 Subject: [PATCH 312/448] fix checkstyle issues --- src/INTERLAYER/pair_aip_water_2dm.cpp | 14 +++++++------- src/INTERLAYER/pair_aip_water_2dm.h | 19 +++++-------------- src/OPT/pair_aip_water_2dm_opt.cpp | 12 ++++++------ src/OPT/pair_aip_water_2dm_opt.h | 12 ++++++------ 4 files changed, 24 insertions(+), 33 deletions(-) diff --git a/src/INTERLAYER/pair_aip_water_2dm.cpp b/src/INTERLAYER/pair_aip_water_2dm.cpp index 3747d249de..d88676a6e2 100644 --- a/src/INTERLAYER/pair_aip_water_2dm.cpp +++ b/src/INTERLAYER/pair_aip_water_2dm.cpp @@ -18,7 +18,7 @@ [Feng and Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023).] ------------------------------------------------------------------------- */ -#include "pair_ilp_water_2dm.h" +#include "pair_aip_water_2dm.h" #include "atom.h" #include "citeme.h" @@ -40,7 +40,7 @@ using namespace InterLayer; #define DELTA 4 #define PGDELTA 1 -static const char cite_ilp_water[] = +static const char cite_aip_water[] = "ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464\n" "@Article{Feng2023\n" " author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang},\n" @@ -53,26 +53,26 @@ static const char cite_ilp_water[] = /* ---------------------------------------------------------------------- */ -PairILPWATER2DM::PairILPWATER2DM(LAMMPS *lmp) : PairILPGrapheneHBN(lmp), PairILPTMD(lmp) +PairAIPWATER2DM::PairAIPWATER2DM(LAMMPS *lmp) : PairILPGrapheneHBN(lmp), PairILPTMD(lmp) { - variant = ILP_WATER_2DM; + variant = AIP_WATER_2DM; single_enable = 0; // for TMD, each atom have six neighbors Nnei = 6; - if (lmp->citeme) lmp->citeme->add(cite_ilp_water); + if (lmp->citeme) lmp->citeme->add(cite_aip_water); } /* ---------------------------------------------------------------------- global settings ------------------------------------------------------------------------- */ -void PairILPWATER2DM::settings(int narg, char **arg) +void PairAIPWATER2DM::settings(int narg, char **arg) { if (narg < 1 || narg > 2) error->all(FLERR, "Illegal pair_style command"); if (!utils::strmatch(force->pair_style, "^hybrid/overlay")) - error->all(FLERR, "Pair style ilp/water/2dm must be used as sub-style with hybrid/overlay"); + error->all(FLERR, "Pair style aip/water/2dm must be used as sub-style with hybrid/overlay"); cut_global = utils::numeric(FLERR, arg[0], false, lmp); if (narg == 2) tap_flag = utils::numeric(FLERR, arg[1], false, lmp); diff --git a/src/INTERLAYER/pair_aip_water_2dm.h b/src/INTERLAYER/pair_aip_water_2dm.h index fad9f99ff1..295cdfffb9 100644 --- a/src/INTERLAYER/pair_aip_water_2dm.h +++ b/src/INTERLAYER/pair_aip_water_2dm.h @@ -13,33 +13,24 @@ #ifdef PAIR_CLASS // clang-format off -PairStyle(ilp/water/2dm,PairILPWATER2DM); +PairStyle(aip/water/2dm,PairAIPWATER2DM); // clang-format on #else -#ifndef LMP_PAIR_ILP_WATER_2DM_H -#define LMP_PAIR_ILP_WATER_2DM_H +#ifndef LMP_PAIR_AIP_WATER_2DM_H +#define LMP_PAIR_AIP_WATER_2DM_H #include "pair_ilp_tmd.h" namespace LAMMPS_NS { -class PairILPWATER2DM : virtual public PairILPTMD { +class PairAIPWATER2DM : virtual public PairILPTMD { public: - PairILPWATER2DM(class LAMMPS *); + PairAIPWATER2DM(class LAMMPS *); protected: void settings(int, char **) override; - /**************************************************************/ - /* modulo operation with cycling around range */ - - inline int modulo(int k, int range) - { - if (k < 0) k += range; - return k % range; - } - /**************************************************************/ }; } // namespace LAMMPS_NS diff --git a/src/OPT/pair_aip_water_2dm_opt.cpp b/src/OPT/pair_aip_water_2dm_opt.cpp index 316551c345..17e981e479 100644 --- a/src/OPT/pair_aip_water_2dm_opt.cpp +++ b/src/OPT/pair_aip_water_2dm_opt.cpp @@ -11,7 +11,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - This is an optimized version of ilp/water/2dm based on the contribution of: + This is an optimized version of aip/water/2dm based on the contribution of: author: Wengen Ouyang (Wuhan University) e-mail: w.g.ouyang at gmail dot com @@ -30,7 +30,7 @@ Potential is described by: [Feng and Ouyang et al, J. Phys. Chem. C 127, 8704-8713 (2023).] */ -#include "pair_ilp_water_2dm_opt.h" +#include "pair_aip_water_2dm_opt.h" #include "atom.h" #include "citeme.h" @@ -49,15 +49,15 @@ using namespace LAMMPS_NS; using namespace InterLayer; -PairILPWATER2DMOpt::PairILPWATER2DMOpt(LAMMPS *lmp) : - PairILPGrapheneHBN(lmp), PairILPTMD(lmp), PairILPWATER2DM(lmp), PairILPGrapheneHBNOpt(lmp) +PairAIPWATER2DMOpt::PairAIPWATER2DMOpt(LAMMPS *lmp) : + PairILPGrapheneHBN(lmp), PairILPTMD(lmp), PairAIPWATER2DM(lmp), PairILPGrapheneHBNOpt(lmp) { } -void PairILPWATER2DMOpt::coeff(int narg, char **args) +void PairAIPWATER2DMOpt::coeff(int narg, char **args) { PairILPTMD::coeff(narg, args); - memory->create(special_type, atom->ntypes + 1, "PairILPWATER2DMOpt:check_sublayer"); + memory->create(special_type, atom->ntypes + 1, "PairAIPWATER2DMOpt:check_sublayer"); for (int i = 1; i <= atom->ntypes; i++) { int itype = map[i]; if (strcmp(elements[itype], "Mo") == 0 || strcmp(elements[itype], "W") == 0 || diff --git a/src/OPT/pair_aip_water_2dm_opt.h b/src/OPT/pair_aip_water_2dm_opt.h index 8062de880a..46280c2b82 100644 --- a/src/OPT/pair_aip_water_2dm_opt.h +++ b/src/OPT/pair_aip_water_2dm_opt.h @@ -13,21 +13,21 @@ #ifdef PAIR_CLASS // clang-format off -PairStyle(ilp/water/2dm/opt,PairILPWATER2DMOpt); +PairStyle(aip/water/2dm/opt,PairAIPWATER2DMOpt); // clang-format on #else -#ifndef LMP_PAIR_ILP_WATER_2DM_OPT_H -#define LMP_PAIR_ILP_WATER_2DM_OPT_H +#ifndef LMP_PAIR_AIP_WATER_2DM_OPT_H +#define LMP_PAIR_AIP_WATER_2DM_OPT_H #include "pair_ilp_graphene_hbn_opt.h" -#include "pair_ilp_water_2dm.h" +#include "pair_aip_water_2dm.h" namespace LAMMPS_NS { -class PairILPWATER2DMOpt : public PairILPWATER2DM, public PairILPGrapheneHBNOpt { +class PairAIPWATER2DMOpt : public PairAIPWATER2DM, public PairILPGrapheneHBNOpt { public: - PairILPWATER2DMOpt(class LAMMPS *); + PairAIPWATER2DMOpt(class LAMMPS *); void coeff(int narg, char **args) override; protected: From a40b87b05c1e278b2c836c5d131d8b2a1603cd67 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 22:46:33 +0800 Subject: [PATCH 313/448] rename potential files --- potentials/{COH.DMC.ILP => COH.DMC.aip.water.2dm} | 6 +++--- potentials/{COH.ILP => COH.aip.water.2dm} | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) rename potentials/{COH.DMC.ILP => COH.DMC.aip.water.2dm} (91%) mode change 100755 => 100644 rename potentials/{COH.ILP => COH.aip.water.2dm} (94%) mode change 100755 => 100644 diff --git a/potentials/COH.DMC.ILP b/potentials/COH.DMC.aip.water.2dm old mode 100755 new mode 100644 similarity index 91% rename from potentials/COH.DMC.ILP rename to potentials/COH.DMC.aip.water.2dm index 7235afcdab..f3619dd3f1 --- a/potentials/COH.DMC.ILP +++ b/potentials/COH.DMC.aip.water.2dm @@ -1,5 +1,5 @@ -# DATE: 2023-05-18 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127, 8704 (2023). -# Interlayer Potential (ILP) for water/graphene heterojunctions +# DATE: 2022-12-02 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127, 8704 (2023). +# Anisotropic Interfacial Potential (AIP) parameters for water/graphene heterojunctions # The parameters below are fitted against the DMC reference data that rescaled from PBE+MBD-NL. # # ----------------- Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ @@ -25,4 +25,4 @@ Hw H 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.232494 Ow Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 Hw Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 Ow Hw 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 -Hw Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 \ No newline at end of file +Hw Ow 5.45369612 6.18172364 1.25025450 0.00000000 0.00000000 9.05706482 1.23249498 2.77577173 0.00000000 1.0 1.2 diff --git a/potentials/COH.ILP b/potentials/COH.aip.water.2dm old mode 100755 new mode 100644 similarity index 94% rename from potentials/COH.ILP rename to potentials/COH.aip.water.2dm index bd815b5c00..5325399abe --- a/potentials/COH.ILP +++ b/potentials/COH.aip.water.2dm @@ -1,5 +1,5 @@ -# DATE: 2023-05-18 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127, 8704 (2023). -# Interlayer Potential (ILP) for water/graphene heterojunctions +# DATE: 2022-12-02 UNITS: metal CONTRIBUTOR: Wengen Ouyang w.g.ouyang@gmail.com CITATION: Z. Feng, ..., and W. Ouyang, J. Phys. Chem. C 127, 8704 (2023). +# Anisotropic Interfacial Potential (AIP) parameters for water/graphene heterojunctions # The parameters below are fitted against the PBE + MBD-NL DFT reference data from 2.5 A to 15 A. # # ----------------- Repulsion Potential ------------------++++++++++++++ Vdw Potential ++++++++++++++++************ From f507e30d3698a44103b6acc404d20aa484a977ea Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 22:52:45 +0800 Subject: [PATCH 314/448] update input files of examples --- .../aip_water_2dm/COH.aip.water.2dm | 1 + .../gra_water.data | 0 .../in.gr_water | 22 +++++++++---------- .../in.gr_water.opt | 22 +++++++++---------- .../log.18May23.water.g++.1 | 0 .../log.18May23.water.g++.4 | 0 .../log.18May23.water.opt.g++.1 | 0 .../log.18May23.water.opt.g++.4 | 0 .../PACKAGES/interlayer/ilp_water_2dm/COH.ILP | 1 - 9 files changed, 23 insertions(+), 23 deletions(-) create mode 120000 examples/PACKAGES/interlayer/aip_water_2dm/COH.aip.water.2dm rename examples/PACKAGES/interlayer/{ilp_water_2dm => aip_water_2dm}/gra_water.data (100%) rename examples/PACKAGES/interlayer/{ilp_water_2dm => aip_water_2dm}/in.gr_water (73%) rename examples/PACKAGES/interlayer/{ilp_water_2dm => aip_water_2dm}/in.gr_water.opt (73%) rename examples/PACKAGES/interlayer/{ilp_water_2dm => aip_water_2dm}/log.18May23.water.g++.1 (100%) rename examples/PACKAGES/interlayer/{ilp_water_2dm => aip_water_2dm}/log.18May23.water.g++.4 (100%) rename examples/PACKAGES/interlayer/{ilp_water_2dm => aip_water_2dm}/log.18May23.water.opt.g++.1 (100%) rename examples/PACKAGES/interlayer/{ilp_water_2dm => aip_water_2dm}/log.18May23.water.opt.g++.4 (100%) delete mode 120000 examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/COH.aip.water.2dm b/examples/PACKAGES/interlayer/aip_water_2dm/COH.aip.water.2dm new file mode 120000 index 0000000000..fe5cccfcd2 --- /dev/null +++ b/examples/PACKAGES/interlayer/aip_water_2dm/COH.aip.water.2dm @@ -0,0 +1 @@ +../../../../potentials/COH.aip.water.2dm \ No newline at end of file diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/gra_water.data b/examples/PACKAGES/interlayer/aip_water_2dm/gra_water.data similarity index 100% rename from examples/PACKAGES/interlayer/ilp_water_2dm/gra_water.data rename to examples/PACKAGES/interlayer/aip_water_2dm/gra_water.data diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water b/examples/PACKAGES/interlayer/aip_water_2dm/in.gr_water similarity index 73% rename from examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water rename to examples/PACKAGES/interlayer/aip_water_2dm/in.gr_water index 9fccbf733b..9f8e717a7e 100644 --- a/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water +++ b/examples/PACKAGES/interlayer/aip_water_2dm/in.gr_water @@ -12,13 +12,13 @@ group gr molecule 1 group water molecule 2 ######################## Potential defition ############################## # Interlayer potential -pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +pair_style hybrid/overlay aip/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 #################################################################### pair_coeff 1 1 none -pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H -pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H -pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw # C-water +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * aip/water/2dm COH.aip.water.2dm C Ow Hw # C-H2O # bond and angle bond_style harmonic bond_coeff 1 0.0 0.9572 @@ -32,7 +32,7 @@ neigh_modify every 1 delay 5 check yes page 1000000 one 100000 #################################################################### # Calculate pair energy compute 1 all pair lj/cut/tip4p/long -compute 2 all pair ilp/water/2dm +compute 2 all pair aip/water/2dm compute wt water temp variable TIP4P equal c_1 variable EILP equal c_2 # total interlayer energy @@ -42,10 +42,10 @@ thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt thermo 100 thermo_modify lost error -fix subf gr setforce 0.0 0.0 0.0 -fix 1 water shake 0.0001 20 100 b 1 a 1 +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 -timestep 1e-3 -velocity water create 300.0 12345 dist gaussian mom yes rot yes -fix 2 water nve -run 1000 +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water.opt b/examples/PACKAGES/interlayer/aip_water_2dm/in.gr_water.opt similarity index 73% rename from examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water.opt rename to examples/PACKAGES/interlayer/aip_water_2dm/in.gr_water.opt index 1b38ab6e6e..8494bfcb3e 100644 --- a/examples/PACKAGES/interlayer/ilp_water_2dm/in.gr_water.opt +++ b/examples/PACKAGES/interlayer/aip_water_2dm/in.gr_water.opt @@ -12,13 +12,13 @@ group gr molecule 1 group water molecule 2 ######################## Potential defition ############################## # Interlayer potential -pair_style hybrid/overlay ilp/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +pair_style hybrid/overlay aip/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 #################################################################### pair_coeff 1 1 none -pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H -pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H -pair_coeff * * ilp/water/2dm/opt COH.ILP C Ow Hw # C-water +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * aip/water/2dm/opt COH.aip.water.2dm C Ow Hw # C-H2O # bond and angle bond_style harmonic bond_coeff 1 0.0 0.9572 @@ -32,7 +32,7 @@ neigh_modify every 1 delay 5 check yes page 1000000 one 100000 #################################################################### # Calculate pair energy compute 1 all pair lj/cut/tip4p/long -compute 2 all pair ilp/water/2dm/opt +compute 2 all pair aip/water/2dm/opt compute wt water temp variable TIP4P equal c_1 variable EILP equal c_2 # total interlayer energy @@ -42,10 +42,10 @@ thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt thermo 100 thermo_modify lost error -fix subf gr setforce 0.0 0.0 0.0 -fix 1 water shake 0.0001 20 100 b 1 a 1 +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 -timestep 1e-3 -velocity water create 300.0 12345 dist gaussian mom yes rot yes -fix 2 water nve -run 1000 +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.1 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.1 similarity index 100% rename from examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.1 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.1 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.4 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.4 similarity index 100% rename from examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.g++.4 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.4 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.1 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.1 similarity index 100% rename from examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.1 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.1 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.4 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.4 similarity index 100% rename from examples/PACKAGES/interlayer/ilp_water_2dm/log.18May23.water.opt.g++.4 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.4 diff --git a/examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP b/examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP deleted file mode 120000 index 526995dae4..0000000000 --- a/examples/PACKAGES/interlayer/ilp_water_2dm/COH.ILP +++ /dev/null @@ -1 +0,0 @@ -../../../../potentials/COH.ILP \ No newline at end of file From 63f3d183fe57cd035e8989c1df9f28f56d414c1e Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 23:02:45 +0800 Subject: [PATCH 315/448] rename log files of examples --- .../{log.18May23.water.g++.1 => log.18May23.gr_water.g++.1} | 0 .../{log.18May23.water.g++.4 => log.18May23.gr_water.g++.4} | 0 ...log.18May23.water.opt.g++.1 => log.18May23.gr_water.opt.g++.1} | 0 ...log.18May23.water.opt.g++.4 => log.18May23.gr_water.opt.g++.4} | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename examples/PACKAGES/interlayer/aip_water_2dm/{log.18May23.water.g++.1 => log.18May23.gr_water.g++.1} (100%) rename examples/PACKAGES/interlayer/aip_water_2dm/{log.18May23.water.g++.4 => log.18May23.gr_water.g++.4} (100%) rename examples/PACKAGES/interlayer/aip_water_2dm/{log.18May23.water.opt.g++.1 => log.18May23.gr_water.opt.g++.1} (100%) rename examples/PACKAGES/interlayer/aip_water_2dm/{log.18May23.water.opt.g++.4 => log.18May23.gr_water.opt.g++.4} (100%) diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.1 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.1 similarity index 100% rename from examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.1 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.1 diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.4 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.4 similarity index 100% rename from examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.g++.4 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.4 diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.1 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.1 similarity index 100% rename from examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.1 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.1 diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.4 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.4 similarity index 100% rename from examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.water.opt.g++.4 rename to examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.4 From b5ab173763f7c6941c6f6b994f541ef3e9750017 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 23:03:12 +0800 Subject: [PATCH 316/448] update the doc file --- doc/src/pair_aip_water_2dm.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/doc/src/pair_aip_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst index 6a364f38ed..517cc00f4b 100644 --- a/doc/src/pair_aip_water_2dm.rst +++ b/doc/src/pair_aip_water_2dm.rst @@ -1,17 +1,17 @@ -.. index:: pair_style ilp/water/2dm -.. index:: pair_style ilp/water/2dm/opt +.. index:: pair_style aip/water/2dm +.. index:: pair_style aip/water/2dm/opt pair_style ilp/tmd command =================================== -Accelerator Variant: *ilp/water/2dm/opt* +Accelerator Variant: *aip/water/2dm/opt* Syntax """""" .. code-block:: LAMMPS - pair_style [hybrid/overlay ...] ilp/tmd cutoff tap_flag + pair_style [hybrid/overlay ...] aip/water/2dm cutoff tap_flag * cutoff = global cutoff (distance units) * tap_flag = 0/1 to turn off/on the taper function @@ -21,22 +21,22 @@ Examples .. code-block:: LAMMPS - pair_style hybrid/overlay ilp/water/2dm 16.0 1 - pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw + pair_style hybrid/overlay aip/water/2dm 16.0 1 + pair_coeff * * aip/water/2dm COH.aip.water.2dm C Ow Hw - pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 + pair_style hybrid/overlay aip/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H - pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw + pair_coeff * * aip/water/2dm COH.aip.water.2dm C Ow Hw Description """"""""""" .. versionadded:: xxxx2023 -The *ilp/water/2dm* style computes the registry-dependent interlayer -potential (ILP) potential for interfaces of water with two-dimensinal (2D) +The *aip/water/2dm* style computes the anisotropic interfacial +potential (AIP) potential for interfaces of water with two-dimensinal (2D) materials as described in :ref:`(Feng) `. .. math:: @@ -69,7 +69,7 @@ calculating the normals. oxygen-hydrogen bonds and the normal vector of the central oxygen atom is defined as their average. -The parameter file (e.g. COH.ILP), is intended for use with *metal* +The parameter file (e.g. COH.aip.water.2dm), is intended for use with *metal* :doc:`units `, with energies in meV. Two additional parameters, *S*, and *rcut* are included in the parameter file. *S* is designed to facilitate scaling of energies. *rcut* is designed to build the neighbor @@ -77,7 +77,7 @@ list for calculating the normals for each atom pair. .. note:: - The parameters presented in the parameter file (e.g. COH.ILP), + The parameters presented in the parameter file (e.g. COH.aip.water.2dm), are fitted with taper function by setting the cutoff equal to 16.0 Angstrom. Using different cutoff or taper function should be careful. These parameters provide a good description in both short- and long-range @@ -100,7 +100,7 @@ headings) the following commands could be included in an input script: .. code-block:: LAMMPS - compute 0 all pair ilp/water/2dm + compute 0 all pair aip/water/2dm variable Evdw equal c_0[1] variable Erep equal c_0[2] thermo_style custom step temp epair v_Erep v_Evdw @@ -132,10 +132,10 @@ if LAMMPS was built with that package. See the :doc:`Build package This pair style requires the newton setting to be *on* for pair interactions. -The COH.ILP potential file provided with LAMMPS (see the potentials +The COH.aip.water.2dm potential file provided with LAMMPS (see the potentials directory) are parameterized for *metal* units. You can use this potential with any LAMMPS units, but you would need to create your -COH.ILP potential file with coefficients listed in the appropriate +COH.aip.water.2dm potential file with coefficients listed in the appropriate units, if your simulation does not use *metal* units. Related commands From 196641927f6973ac76eca00b78b718a0f67cc925 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sat, 3 Jun 2023 23:07:55 +0800 Subject: [PATCH 317/448] correct a typo in the doc file --- doc/src/pair_aip_water_2dm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/pair_aip_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst index 517cc00f4b..3ae63e1e45 100644 --- a/doc/src/pair_aip_water_2dm.rst +++ b/doc/src/pair_aip_water_2dm.rst @@ -1,7 +1,7 @@ .. index:: pair_style aip/water/2dm .. index:: pair_style aip/water/2dm/opt -pair_style ilp/tmd command +pair_style aip/water/2dm command =================================== Accelerator Variant: *aip/water/2dm/opt* From bf8a4402cef5d2b9da6c0ffcc0c93e4f03ec0932 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sun, 4 Jun 2023 10:17:21 +0800 Subject: [PATCH 318/448] update log files in the examples --- .../aip_water_2dm/log.18May23.gr_water.g++.1 | 83 ++++++++++--------- .../aip_water_2dm/log.18May23.gr_water.g++.4 | 81 +++++++++--------- .../log.18May23.gr_water.opt.g++.1 | 83 ++++++++++--------- .../log.18May23.gr_water.opt.g++.4 | 81 +++++++++--------- 4 files changed, 174 insertions(+), 154 deletions(-) diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.1 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.1 index 6e13280f70..c8268c72f6 100644 --- a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.1 +++ b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.1 @@ -1,4 +1,4 @@ -LAMMPS (23 Jun 2022) +LAMMPS (23 Jun 2022 - Update 4) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) using 1 OpenMP thread(s) per MPI task # Initialization @@ -29,8 +29,8 @@ Finding 1-2 1-3 1-4 neighbors ... 1 = max # of 1-3 neighbors 1 = max # of 1-4 neighbors 2 = max # of special neighbors - special bonds CPU = 0.005 seconds - read_data CPU = 0.020 seconds + special bonds CPU = 0.000 seconds + read_data CPU = 0.012 seconds mass 1 12.0107 # carbon mass (g/mole) mass 2 15.9994 # oxygen mass (g/mole) mass 3 1.008 # hydrogen mass (g/mole) @@ -41,14 +41,14 @@ group water molecule 2 144 atoms in group water ######################## Potential defition ############################## # Interlayer potential -pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +pair_style hybrid/overlay aip/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 #################################################################### pair_coeff 1 1 none -pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H -pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H -pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw # C-water -Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * aip/water/2dm COH.aip.water.2dm C Ow Hw # C-H2O +Reading aip/water/2dm potential file COH.aip.water.2dm with DATE: 2022-12-02 # bond and angle bond_style harmonic bond_coeff 1 0.0 0.9572 @@ -62,7 +62,7 @@ neigh_modify every 1 delay 5 check yes page 1000000 one 100000 #################################################################### # Calculate pair energy compute 1 all pair lj/cut/tip4p/long -compute 2 all pair ilp/water/2dm +compute 2 all pair aip/water/2dm compute wt water temp variable TIP4P equal c_1 variable EILP equal c_2 # total interlayer energy @@ -72,18 +72,18 @@ thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt thermo 100 thermo_modify lost error -fix subf gr setforce 0.0 0.0 0.0 -fix 1 water shake 0.0001 20 100 b 1 a 1 +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 0 = # of size 2 clusters 0 = # of size 3 clusters 0 = # of size 4 clusters 48 = # of frozen angles - find clusters CPU = 0.001 seconds + find clusters CPU = 0.000 seconds -timestep 1e-3 -velocity water create 300.0 12345 dist gaussian mom yes rot yes -fix 2 water nve -run 1000 +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE @@ -91,22 +91,24 @@ Your simulation uses code contributions which should be cited: - ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 @Article{Ouyang2018 - author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + author = {W. Ouyang and D. Mandelli and M. Urbakh and O. Hod}, title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, journal = {Nano Letters}, volume = 18, - pages = {6009} + pages = 6009, year = 2018, } -- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +- ilp/tmd potential doi:10.1021/acs.jctc.1c00782 @Article{Ouyang2021 - author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, - title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, - journal = {J. Chem. Theory Comput.}, - volume = 17, - pages = {7237–7245} - year = 2021, + author = {W. Ouyang and R. Sofer and X. Gao and J. Hermann and + A. Tkatchenko and L. Kronik and M. Urbakh and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition + Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J.~Chem.\ Theory Comput.}, + volume = 17, + pages = {7237--7245} + year = 2021, } - ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 @@ -132,6 +134,8 @@ PPPM initialization ... using single precision MKL FFT 3d grid and FFT values/proc = 84320 48000 WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +WARNING: Communication cutoff 0 is shorter than a bond length based estimate of 3.4358. This may lead to errors. (../comm.cpp:727) +WARNING: Increasing communication cutoff to 11.6118 for TIP4P pair style (../pair_lj_cut_tip4p_long.cpp:484) Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 100000, page size: 1000000 @@ -139,7 +143,7 @@ Neighbor list info ... ghost atom cutoff = 18 binsize = 9, bins = 6 5 23 3 neighbor lists, perpetual/occasional/extra = 3 0 0 - (1) pair ilp/water/2dm, perpetual + (1) pair aip/water/2dm, perpetual attributes: full, newton on, ghost pair build: full/bin/ghost stencil: full/ghost/bin/3d @@ -154,10 +158,11 @@ Neighbor list info ... pair build: half/bin/newton stencil: half/bin/3d bin: standard +WARNING: Communication cutoff adjusted to 18 (../comm.cpp:736) SHAKE stats (type/ave/delta/count) on step 0 Bond: 1 0.957201 2.19705e-06 96 Angle: 1 104.52 0.000203056 48 -Per MPI rank memory allocation (min/avg/max) = 33.53 | 33.53 | 33.53 Mbytes +Per MPI rank memory allocation (min/avg/max) = 32.9 | 32.9 | 32.9 Mbytes Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 SHAKE stats (type/ave/delta/count) on step 100 @@ -200,22 +205,22 @@ SHAKE stats (type/ave/delta/count) on step 1000 Bond: 1 0.9572 1.00586e-06 96 Angle: 1 104.52 0.000111712 48 1000 -17.498465 -20.331545 2.8330804 188.87473 -1.812177 230.71225 -Loop time of 20.801 on 1 procs for 1000 steps with 936 atoms +Loop time of 20.3334 on 1 procs for 1000 steps with 936 atoms -Performance: 4.154 ns/day, 5.778 hours/ns, 48.075 timesteps/s -99.9% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 4.249 ns/day, 5.648 hours/ns, 49.180 timesteps/s +99.5% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 16.429 | 16.429 | 16.429 | 0.0 | 78.98 -Bond | 0.0010991 | 0.0010991 | 0.0010991 | 0.0 | 0.01 -Kspace | 3.4769 | 3.4769 | 3.4769 | 0.0 | 16.72 -Neigh | 0.83359 | 0.83359 | 0.83359 | 0.0 | 4.01 -Comm | 0.028825 | 0.028825 | 0.028825 | 0.0 | 0.14 -Output | 0.00046349 | 0.00046349 | 0.00046349 | 0.0 | 0.00 -Modify | 0.01943 | 0.01943 | 0.01943 | 0.0 | 0.09 -Other | | 0.01154 | | | 0.06 +Pair | 16.179 | 16.179 | 16.179 | 0.0 | 79.57 +Bond | 0.00021103 | 0.00021103 | 0.00021103 | 0.0 | 0.00 +Kspace | 3.3118 | 3.3118 | 3.3118 | 0.0 | 16.29 +Neigh | 0.79017 | 0.79017 | 0.79017 | 0.0 | 3.89 +Comm | 0.026379 | 0.026379 | 0.026379 | 0.0 | 0.13 +Output | 0.00046496 | 0.00046496 | 0.00046496 | 0.0 | 0.00 +Modify | 0.017013 | 0.017013 | 0.017013 | 0.0 | 0.08 +Other | | 0.008835 | | | 0.04 Nlocal: 936 ave 936 max 936 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -231,4 +236,4 @@ Ave neighs/atom = 460.87821 Ave special neighs/atom = 0.30769231 Neighbor list builds = 28 Dangerous builds = 0 -Total wall time: 0:00:21 +Total wall time: 0:00:20 diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.4 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.4 index 078ca76e2e..ab28c96657 100644 --- a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.4 +++ b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.g++.4 @@ -1,4 +1,4 @@ -LAMMPS (23 Jun 2022) +LAMMPS (23 Jun 2022 - Update 4) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) using 1 OpenMP thread(s) per MPI task # Initialization @@ -29,8 +29,8 @@ Finding 1-2 1-3 1-4 neighbors ... 1 = max # of 1-3 neighbors 1 = max # of 1-4 neighbors 2 = max # of special neighbors - special bonds CPU = 0.003 seconds - read_data CPU = 0.018 seconds + special bonds CPU = 0.001 seconds + read_data CPU = 0.017 seconds mass 1 12.0107 # carbon mass (g/mole) mass 2 15.9994 # oxygen mass (g/mole) mass 3 1.008 # hydrogen mass (g/mole) @@ -41,14 +41,14 @@ group water molecule 2 144 atoms in group water ######################## Potential defition ############################## # Interlayer potential -pair_style hybrid/overlay ilp/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +pair_style hybrid/overlay aip/water/2dm 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 #################################################################### pair_coeff 1 1 none -pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H -pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H -pair_coeff * * ilp/water/2dm COH.ILP C Ow Hw # C-water -Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * aip/water/2dm COH.aip.water.2dm C Ow Hw # C-H2O +Reading aip/water/2dm potential file COH.aip.water.2dm with DATE: 2022-12-02 # bond and angle bond_style harmonic bond_coeff 1 0.0 0.9572 @@ -62,7 +62,7 @@ neigh_modify every 1 delay 5 check yes page 1000000 one 100000 #################################################################### # Calculate pair energy compute 1 all pair lj/cut/tip4p/long -compute 2 all pair ilp/water/2dm +compute 2 all pair aip/water/2dm compute wt water temp variable TIP4P equal c_1 variable EILP equal c_2 # total interlayer energy @@ -72,18 +72,18 @@ thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt thermo 100 thermo_modify lost error -fix subf gr setforce 0.0 0.0 0.0 -fix 1 water shake 0.0001 20 100 b 1 a 1 +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 0 = # of size 2 clusters 0 = # of size 3 clusters 0 = # of size 4 clusters 48 = # of frozen angles - find clusters CPU = 0.001 seconds + find clusters CPU = 0.000 seconds -timestep 1e-3 -velocity water create 300.0 12345 dist gaussian mom yes rot yes -fix 2 water nve -run 1000 +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE @@ -91,22 +91,24 @@ Your simulation uses code contributions which should be cited: - ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 @Article{Ouyang2018 - author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + author = {W. Ouyang and D. Mandelli and M. Urbakh and O. Hod}, title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, journal = {Nano Letters}, volume = 18, - pages = {6009} + pages = 6009, year = 2018, } -- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +- ilp/tmd potential doi:10.1021/acs.jctc.1c00782 @Article{Ouyang2021 - author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, - title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, - journal = {J. Chem. Theory Comput.}, - volume = 17, - pages = {7237–7245} - year = 2021, + author = {W. Ouyang and R. Sofer and X. Gao and J. Hermann and + A. Tkatchenko and L. Kronik and M. Urbakh and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition + Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J.~Chem.\ Theory Comput.}, + volume = 17, + pages = {7237--7245} + year = 2021, } - ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 @@ -132,6 +134,8 @@ PPPM initialization ... using single precision MKL FFT 3d grid and FFT values/proc = 30685 12480 WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +WARNING: Communication cutoff 0 is shorter than a bond length based estimate of 3.4358. This may lead to errors. (../comm.cpp:727) +WARNING: Increasing communication cutoff to 11.6118 for TIP4P pair style (../pair_lj_cut_tip4p_long.cpp:484) Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 100000, page size: 1000000 @@ -139,7 +143,7 @@ Neighbor list info ... ghost atom cutoff = 18 binsize = 9, bins = 6 5 23 3 neighbor lists, perpetual/occasional/extra = 3 0 0 - (1) pair ilp/water/2dm, perpetual + (1) pair aip/water/2dm, perpetual attributes: full, newton on, ghost pair build: full/bin/ghost stencil: full/ghost/bin/3d @@ -154,10 +158,11 @@ Neighbor list info ... pair build: half/bin/newton stencil: half/bin/3d bin: standard +WARNING: Communication cutoff adjusted to 18 (../comm.cpp:736) SHAKE stats (type/ave/delta/count) on step 0 Bond: 1 0.957201 2.19705e-06 96 Angle: 1 104.52 0.000203056 48 -Per MPI rank memory allocation (min/avg/max) = 25.84 | 25.88 | 25.92 Mbytes +Per MPI rank memory allocation (min/avg/max) = 25.22 | 25.25 | 25.29 Mbytes Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 SHAKE stats (type/ave/delta/count) on step 100 @@ -200,22 +205,22 @@ SHAKE stats (type/ave/delta/count) on step 1000 Bond: 1 0.9572 1.00568e-06 96 Angle: 1 104.52 0.000111707 48 1000 -17.498474 -20.331607 2.833133 188.87466 -1.8121689 230.71654 -Loop time of 9.42273 on 4 procs for 1000 steps with 936 atoms +Loop time of 9.05361 on 4 procs for 1000 steps with 936 atoms -Performance: 9.169 ns/day, 2.617 hours/ns, 106.126 timesteps/s -97.1% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 9.543 ns/day, 2.515 hours/ns, 110.453 timesteps/s +99.6% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 2.2328 | 4.3228 | 7.5931 | 103.1 | 45.88 -Bond | 0.00084131 | 0.00088983 | 0.00095229 | 0.0 | 0.01 -Kspace | 1.3979 | 4.6476 | 6.7252 | 98.8 | 49.32 -Neigh | 0.34367 | 0.34371 | 0.34376 | 0.0 | 3.65 -Comm | 0.042806 | 0.062908 | 0.075887 | 5.4 | 0.67 -Output | 0.00037677 | 0.00041431 | 0.0004619 | 0.0 | 0.00 -Modify | 0.028432 | 0.031138 | 0.034528 | 1.3 | 0.33 -Other | | 0.01321 | | | 0.14 +Pair | 2.462 | 4.2266 | 7.1075 | 89.3 | 46.68 +Bond | 0.00018424 | 0.00019878 | 0.00022125 | 0.0 | 0.00 +Kspace | 1.4698 | 4.338 | 6.1001 | 87.8 | 47.91 +Neigh | 0.39462 | 0.39489 | 0.39518 | 0.0 | 4.36 +Comm | 0.043753 | 0.055826 | 0.062746 | 3.1 | 0.62 +Output | 0.00048755 | 0.00053971 | 0.00062785 | 0.0 | 0.01 +Modify | 0.027255 | 0.028664 | 0.030278 | 0.7 | 0.32 +Other | | 0.008904 | | | 0.10 Nlocal: 234 ave 302 max 198 min Histogram: 2 0 0 1 0 0 0 0 0 1 diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.1 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.1 index c6a11d209d..c795e85d56 100644 --- a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.1 +++ b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.1 @@ -1,4 +1,4 @@ -LAMMPS (23 Jun 2022) +LAMMPS (23 Jun 2022 - Update 4) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) using 1 OpenMP thread(s) per MPI task # Initialization @@ -29,8 +29,8 @@ Finding 1-2 1-3 1-4 neighbors ... 1 = max # of 1-3 neighbors 1 = max # of 1-4 neighbors 2 = max # of special neighbors - special bonds CPU = 0.005 seconds - read_data CPU = 0.020 seconds + special bonds CPU = 0.000 seconds + read_data CPU = 0.012 seconds mass 1 12.0107 # carbon mass (g/mole) mass 2 15.9994 # oxygen mass (g/mole) mass 3 1.008 # hydrogen mass (g/mole) @@ -41,14 +41,14 @@ group water molecule 2 144 atoms in group water ######################## Potential defition ############################## # Interlayer potential -pair_style hybrid/overlay ilp/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +pair_style hybrid/overlay aip/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 #################################################################### pair_coeff 1 1 none -pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H -pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H -pair_coeff * * ilp/water/2dm/opt COH.ILP C Ow Hw # C-water -Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * aip/water/2dm/opt COH.aip.water.2dm C Ow Hw # C-H2O +Reading aip/water/2dm potential file COH.aip.water.2dm with DATE: 2022-12-02 # bond and angle bond_style harmonic bond_coeff 1 0.0 0.9572 @@ -62,7 +62,7 @@ neigh_modify every 1 delay 5 check yes page 1000000 one 100000 #################################################################### # Calculate pair energy compute 1 all pair lj/cut/tip4p/long -compute 2 all pair ilp/water/2dm/opt +compute 2 all pair aip/water/2dm/opt compute wt water temp variable TIP4P equal c_1 variable EILP equal c_2 # total interlayer energy @@ -72,18 +72,18 @@ thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt thermo 100 thermo_modify lost error -fix subf gr setforce 0.0 0.0 0.0 -fix 1 water shake 0.0001 20 100 b 1 a 1 +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 0 = # of size 2 clusters 0 = # of size 3 clusters 0 = # of size 4 clusters 48 = # of frozen angles - find clusters CPU = 0.001 seconds + find clusters CPU = 0.000 seconds -timestep 1e-3 -velocity water create 300.0 12345 dist gaussian mom yes rot yes -fix 2 water nve -run 1000 +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE @@ -91,22 +91,24 @@ Your simulation uses code contributions which should be cited: - ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 @Article{Ouyang2018 - author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + author = {W. Ouyang and D. Mandelli and M. Urbakh and O. Hod}, title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, journal = {Nano Letters}, volume = 18, - pages = {6009} + pages = 6009, year = 2018, } -- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +- ilp/tmd potential doi:10.1021/acs.jctc.1c00782 @Article{Ouyang2021 - author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, - title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, - journal = {J. Chem. Theory Comput.}, - volume = 17, - pages = {7237–7245} - year = 2021, + author = {W. Ouyang and R. Sofer and X. Gao and J. Hermann and + A. Tkatchenko and L. Kronik and M. Urbakh and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition + Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J.~Chem.\ Theory Comput.}, + volume = 17, + pages = {7237--7245} + year = 2021, } - ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 @@ -149,6 +151,8 @@ PPPM initialization ... using single precision MKL FFT 3d grid and FFT values/proc = 84320 48000 WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +WARNING: Communication cutoff 0 is shorter than a bond length based estimate of 3.4358. This may lead to errors. (../comm.cpp:727) +WARNING: Increasing communication cutoff to 11.6118 for TIP4P pair style (../pair_lj_cut_tip4p_long.cpp:484) Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 100000, page size: 1000000 @@ -156,7 +160,7 @@ Neighbor list info ... ghost atom cutoff = 18 binsize = 9, bins = 6 5 23 3 neighbor lists, perpetual/occasional/extra = 3 0 0 - (1) pair ilp/water/2dm/opt, perpetual + (1) pair aip/water/2dm/opt, perpetual attributes: full, newton on pair build: full/bin stencil: full/bin/3d @@ -171,10 +175,11 @@ Neighbor list info ... pair build: halffull/newton stencil: none bin: none +WARNING: Communication cutoff adjusted to 18 (../comm.cpp:736) SHAKE stats (type/ave/delta/count) on step 0 Bond: 1 0.957201 2.19705e-06 96 Angle: 1 104.52 0.000203056 48 -Per MPI rank memory allocation (min/avg/max) = 25.89 | 25.89 | 25.89 Mbytes +Per MPI rank memory allocation (min/avg/max) = 25.27 | 25.27 | 25.27 Mbytes Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 SHAKE stats (type/ave/delta/count) on step 100 @@ -217,22 +222,22 @@ SHAKE stats (type/ave/delta/count) on step 1000 Bond: 1 0.9572 1.00586e-06 96 Angle: 1 104.52 0.000111711 48 1000 -17.498466 -20.331547 2.8330808 188.87473 -1.8121768 230.71228 -Loop time of 8.95265 on 1 procs for 1000 steps with 936 atoms +Loop time of 8.11929 on 1 procs for 1000 steps with 936 atoms -Performance: 9.651 ns/day, 2.487 hours/ns, 111.699 timesteps/s -100.0% CPU use with 1 MPI tasks x 1 OpenMP threads +Performance: 10.641 ns/day, 2.255 hours/ns, 123.163 timesteps/s +99.7% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 5.2127 | 5.2127 | 5.2127 | 0.0 | 58.23 -Bond | 0.00083377 | 0.00083377 | 0.00083377 | 0.0 | 0.01 -Kspace | 3.5005 | 3.5005 | 3.5005 | 0.0 | 39.10 -Neigh | 0.17946 | 0.17946 | 0.17946 | 0.0 | 2.00 -Comm | 0.028553 | 0.028553 | 0.028553 | 0.0 | 0.32 -Output | 0.00035446 | 0.00035446 | 0.00035446 | 0.0 | 0.00 -Modify | 0.01889 | 0.01889 | 0.01889 | 0.0 | 0.21 -Other | | 0.01135 | | | 0.13 +Pair | 4.6849 | 4.6849 | 4.6849 | 0.0 | 57.70 +Bond | 0.00017678 | 0.00017678 | 0.00017678 | 0.0 | 0.00 +Kspace | 3.2098 | 3.2098 | 3.2098 | 0.0 | 39.53 +Neigh | 0.17546 | 0.17546 | 0.17546 | 0.0 | 2.16 +Comm | 0.024693 | 0.024693 | 0.024693 | 0.0 | 0.30 +Output | 0.00037798 | 0.00037798 | 0.00037798 | 0.0 | 0.00 +Modify | 0.015853 | 0.015853 | 0.015853 | 0.0 | 0.20 +Other | | 0.007983 | | | 0.10 Nlocal: 936 ave 936 max 936 min Histogram: 1 0 0 0 0 0 0 0 0 0 @@ -248,4 +253,4 @@ Ave neighs/atom = 460.87821 Ave special neighs/atom = 0.30769231 Neighbor list builds = 28 Dangerous builds = 0 -Total wall time: 0:00:09 +Total wall time: 0:00:08 diff --git a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.4 b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.4 index 852c429323..f885c5708d 100644 --- a/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.4 +++ b/examples/PACKAGES/interlayer/aip_water_2dm/log.18May23.gr_water.opt.g++.4 @@ -1,4 +1,4 @@ -LAMMPS (23 Jun 2022) +LAMMPS (23 Jun 2022 - Update 4) OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (../comm.cpp:98) using 1 OpenMP thread(s) per MPI task # Initialization @@ -29,8 +29,8 @@ Finding 1-2 1-3 1-4 neighbors ... 1 = max # of 1-3 neighbors 1 = max # of 1-4 neighbors 2 = max # of special neighbors - special bonds CPU = 0.003 seconds - read_data CPU = 0.017 seconds + special bonds CPU = 0.001 seconds + read_data CPU = 0.014 seconds mass 1 12.0107 # carbon mass (g/mole) mass 2 15.9994 # oxygen mass (g/mole) mass 3 1.008 # hydrogen mass (g/mole) @@ -41,14 +41,14 @@ group water molecule 2 144 atoms in group water ######################## Potential defition ############################## # Interlayer potential -pair_style hybrid/overlay ilp/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 +pair_style hybrid/overlay aip/water/2dm/opt 16.0 lj/cut/tip4p/long 2 3 1 1 0.1546 10 8.5 #################################################################### pair_coeff 1 1 none -pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O +pair_coeff 2 2 lj/cut/tip4p/long 8.0313e-3 3.1589 # O-O pair_coeff 2 3 lj/cut/tip4p/long 0.0 0.0 # O-H -pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H -pair_coeff * * ilp/water/2dm/opt COH.ILP C Ow Hw # C-water -Reading ilp/water/2dm potential file COH.ILP with DATE: 2023-05-17 +pair_coeff 3 3 lj/cut/tip4p/long 0.0 0.0 # H-H +pair_coeff * * aip/water/2dm/opt COH.aip.water.2dm C Ow Hw # C-H2O +Reading aip/water/2dm potential file COH.aip.water.2dm with DATE: 2022-12-02 # bond and angle bond_style harmonic bond_coeff 1 0.0 0.9572 @@ -62,7 +62,7 @@ neigh_modify every 1 delay 5 check yes page 1000000 one 100000 #################################################################### # Calculate pair energy compute 1 all pair lj/cut/tip4p/long -compute 2 all pair ilp/water/2dm/opt +compute 2 all pair aip/water/2dm/opt compute wt water temp variable TIP4P equal c_1 variable EILP equal c_2 # total interlayer energy @@ -72,18 +72,18 @@ thermo_style custom step etotal pe ke v_TIP4P v_EILP v_temp_wt thermo 100 thermo_modify lost error -fix subf gr setforce 0.0 0.0 0.0 -fix 1 water shake 0.0001 20 100 b 1 a 1 +fix subf gr setforce 0.0 0.0 0.0 +fix 1 water shake 0.0001 20 100 b 1 a 1 0 = # of size 2 clusters 0 = # of size 3 clusters 0 = # of size 4 clusters 48 = # of frozen angles - find clusters CPU = 0.001 seconds + find clusters CPU = 0.000 seconds -timestep 1e-3 -velocity water create 300.0 12345 dist gaussian mom yes rot yes -fix 2 water nve -run 1000 +timestep 1e-3 +velocity water create 300.0 12345 dist gaussian mom yes rot yes +fix 2 water nve +run 1000 CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE-CITE @@ -91,22 +91,24 @@ Your simulation uses code contributions which should be cited: - ilp/graphene/hbn potential doi:10.1021/acs.nanolett.8b02848 @Article{Ouyang2018 - author = {W. Ouyang, D. Mandelli, M. Urbakh, and O. Hod}, + author = {W. Ouyang and D. Mandelli and M. Urbakh and O. Hod}, title = {Nanoserpents: Graphene Nanoribbon Motion on Two-Dimensional Hexagonal Materials}, journal = {Nano Letters}, volume = 18, - pages = {6009} + pages = 6009, year = 2018, } -- ilp/tmd potential doi/10.1021/acs.jctc.1c00782 +- ilp/tmd potential doi:10.1021/acs.jctc.1c00782 @Article{Ouyang2021 - author = {W. Ouyang, R. Sofer, X. Gao, J. Hermann, A. Tkatchenko, L. Kronik, M. Urbakh, and O. Hod}, - title = {Anisotropic Interlayer Force Field for Transition Metal Dichalcogenides: The Case of Molybdenum Disulfide}, - journal = {J. Chem. Theory Comput.}, - volume = 17, - pages = {7237–7245} - year = 2021, + author = {W. Ouyang and R. Sofer and X. Gao and J. Hermann and + A. Tkatchenko and L. Kronik and M. Urbakh and O. Hod}, + title = {Anisotropic Interlayer Force Field for Transition + Metal Dichalcogenides: The Case of Molybdenum Disulfide}, + journal = {J.~Chem.\ Theory Comput.}, + volume = 17, + pages = {7237--7245} + year = 2021, } - ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464 @@ -149,6 +151,8 @@ PPPM initialization ... using single precision MKL FFT 3d grid and FFT values/proc = 30685 12480 WARNING: Using a manybody potential with bonds/angles/dihedrals and special_bond exclusions (../pair.cpp:239) +WARNING: Communication cutoff 0 is shorter than a bond length based estimate of 3.4358. This may lead to errors. (../comm.cpp:727) +WARNING: Increasing communication cutoff to 11.6118 for TIP4P pair style (../pair_lj_cut_tip4p_long.cpp:484) Neighbor list info ... update every 1 steps, delay 5 steps, check yes max neighbors/atom: 100000, page size: 1000000 @@ -156,7 +160,7 @@ Neighbor list info ... ghost atom cutoff = 18 binsize = 9, bins = 6 5 23 3 neighbor lists, perpetual/occasional/extra = 3 0 0 - (1) pair ilp/water/2dm/opt, perpetual + (1) pair aip/water/2dm/opt, perpetual attributes: full, newton on pair build: full/bin stencil: full/bin/3d @@ -171,10 +175,11 @@ Neighbor list info ... pair build: halffull/newton stencil: none bin: none +WARNING: Communication cutoff adjusted to 18 (../comm.cpp:736) SHAKE stats (type/ave/delta/count) on step 0 Bond: 1 0.957201 2.19705e-06 96 Angle: 1 104.52 0.000203056 48 -Per MPI rank memory allocation (min/avg/max) = 22.03 | 22.06 | 22.1 Mbytes +Per MPI rank memory allocation (min/avg/max) = 21.4 | 21.44 | 21.48 Mbytes Step TotEng PotEng KinEng v_TIP4P v_EILP v_temp_wt 0 -16.131263 -19.815178 3.6839141 189.37246 -1.903543 300 SHAKE stats (type/ave/delta/count) on step 100 @@ -217,22 +222,22 @@ SHAKE stats (type/ave/delta/count) on step 1000 Bond: 1 0.9572 1.00568e-06 96 Angle: 1 104.52 0.000111707 48 1000 -17.498472 -20.331605 2.8331335 188.87466 -1.8121689 230.71657 -Loop time of 4.7828 on 4 procs for 1000 steps with 936 atoms +Loop time of 4.24862 on 4 procs for 1000 steps with 936 atoms -Performance: 18.065 ns/day, 1.329 hours/ns, 209.082 timesteps/s -96.3% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 20.336 ns/day, 1.180 hours/ns, 235.370 timesteps/s +99.6% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 0.26735 | 1.3839 | 3.2059 | 99.7 | 28.93 -Bond | 0.00079377 | 0.00086039 | 0.00093529 | 0.0 | 0.02 -Kspace | 1.4248 | 3.2254 | 4.3332 | 64.6 | 67.44 -Neigh | 0.061885 | 0.061916 | 0.061951 | 0.0 | 1.29 -Comm | 0.044281 | 0.065185 | 0.078628 | 5.1 | 1.36 -Output | 0.0003482 | 0.0003787 | 0.00040746 | 0.0 | 0.01 -Modify | 0.028727 | 0.031529 | 0.034914 | 1.3 | 0.66 -Other | | 0.01367 | | | 0.29 +Pair | 0.25749 | 1.1806 | 2.6872 | 89.0 | 27.79 +Bond | 0.00018656 | 0.00020786 | 0.00025377 | 0.0 | 0.00 +Kspace | 1.4259 | 2.9204 | 3.8414 | 56.3 | 68.74 +Neigh | 0.057504 | 0.057852 | 0.05818 | 0.1 | 1.36 +Comm | 0.041952 | 0.053593 | 0.05876 | 3.0 | 1.26 +Output | 0.0004296 | 0.00046809 | 0.00055317 | 0.0 | 0.01 +Modify | 0.026204 | 0.027251 | 0.028382 | 0.6 | 0.64 +Other | | 0.008209 | | | 0.19 Nlocal: 234 ave 302 max 198 min Histogram: 2 0 0 1 0 0 0 0 0 1 From 3282470cf5b56ae62a0ede29aa8c1519b691d4d3 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Sun, 4 Jun 2023 10:19:13 +0800 Subject: [PATCH 319/448] update the citation information --- src/INTERLAYER/pair_aip_water_2dm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/INTERLAYER/pair_aip_water_2dm.cpp b/src/INTERLAYER/pair_aip_water_2dm.cpp index d88676a6e2..f2d68f448b 100644 --- a/src/INTERLAYER/pair_aip_water_2dm.cpp +++ b/src/INTERLAYER/pair_aip_water_2dm.cpp @@ -41,7 +41,7 @@ using namespace InterLayer; #define PGDELTA 1 static const char cite_aip_water[] = - "ilp/water/2dm potential doi/10.1021/acs.jpcc.2c08464\n" + "aip/water/2dm potential doi/10.1021/acs.jpcc.2c08464\n" "@Article{Feng2023\n" " author = {Z. Feng, Y. Yao, J. Liu, B. Wu, Z. Liu, and W. Ouyang},\n" " title = {Registry-Dependent Potential for Interfaces of Water with Graphene},\n" From a0057d674ff2ef0c7f9e99fb713852f7c1d3ab49 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sun, 4 Jun 2023 13:40:31 +0300 Subject: [PATCH 320/448] Update compute_stress_mop_profile.cpp --- src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index d299633731..99f522096c 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -207,9 +207,11 @@ void ComputeStressMopProfile::init() if (force->bond!=nullptr) bondflag = 1; if (force->angle!=nullptr) - error->all(FLERR,"compute stress/mop/profile does not account for angle potentials"); + if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0)) + error->all(FLERR,"compute stress/mop/profile does not account for angle potentials"); if (force->dihedral!=nullptr) - error->all(FLERR,"compute stress/mop/profile does not account for dihedral potentials"); + if ((strcmp(force->dihedral_style, "zero") != 0) && (strcmp(force->dihedral_style, "none") != 0)) + error->all(FLERR,"compute stress/mop/profile does not account for dihedral potentials"); if (force->improper!=nullptr) error->all(FLERR,"compute stress/mop/profile does not account for improper potentials"); if (force->kspace!=nullptr) From d8fad4db1516f2a9a3d5a2ee1e9fda7b6959089c Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sun, 4 Jun 2023 13:45:00 +0300 Subject: [PATCH 321/448] remove white space from compute_stress_mop.cpp --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 3ae758b875..c9557a7ef3 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -83,7 +83,7 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : if (pos >domain->boxhi[dir] || pos boxlo[dir]) error->all(FLERR, "Plane for compute stress/mop is out of bounds"); } - + if (pos < (domain->boxlo[dir]+domain->prd_half[dir])) { pos1 = pos + domain->prd[dir]; } else { @@ -285,7 +285,7 @@ void ComputeStressMop::compute_vector() // sum angle contribution over all procs MPI_Allreduce(angle_local,angle_global,nvalues,MPI_DOUBLE,MPI_SUM,world); - + for (int m=0; m Date: Sun, 4 Jun 2023 13:45:52 +0300 Subject: [PATCH 322/448] remove whitespace from compute_stress_mop_profile.cpp --- src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index 99f522096c..4f91f8f7fb 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -609,7 +609,7 @@ void ComputeStressMopProfile::compute_bonds() } m += 3; } -} +} /* ---------------------------------------------------------------------- setup 1d bins and their extent and coordinates From 3782eeee2b2bca5435ef51f13082e96a1e0151df Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sun, 4 Jun 2023 13:47:54 +0300 Subject: [PATCH 323/448] remove whitespace from compute_stress_mop.rst --- doc/src/compute_stress_mop.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index e1b151ebbd..7ab8c58a76 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -68,7 +68,7 @@ Between one and six keywords can be used to indicate which contributions to the stress must be computed: total stress (total), kinetic stress (kin), configurational stress (conf), stress due to bond stretching (bond), stress due to angle bending (angle) and/or due to pairwise non-bonded interactions (pair). -The angle keyword is currently available only for the stress/mop command and not the stress/mop/profile. +The angle keyword is currently available only for the stress/mop command and not the stress/mop/profile. NOTE 1: The configurational stress is computed considering all pairs of atoms where at least one atom belongs to group group-ID. @@ -119,12 +119,12 @@ size does not change in time, and axis-aligned planes. The method only works with two-body pair interactions, because it requires the class method pair->single() to be implemented. In -particular, compute *stress/mop/profile* does not work with more than +particular, compute *stress/mop/profile* does not work with more than two-body pair interactions, long range (kspace) interactions and angle/dihedral/improper -intramolecular interactions. Similarly, compute *stress/mop* does not work with more than +intramolecular interactions. Similarly, compute *stress/mop* does not work with more than two-body pair interactions, long range (kspace) interactions and dihedral/improper intramolecular interactions but works with all bond interactions with the class method -single() implemented and all angle interactions with the class method born_matrix() +single() implemented and all angle interactions with the class method born_matrix() implemented. Related commands From c25999d2087c6b79b71ab1d0f6934a7c4598087a Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sun, 4 Jun 2023 16:08:33 +0300 Subject: [PATCH 324/448] Update compute_stress_mop_profile.cpp --- src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index 4f91f8f7fb..2c2260d22c 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -213,7 +213,8 @@ void ComputeStressMopProfile::init() if ((strcmp(force->dihedral_style, "zero") != 0) && (strcmp(force->dihedral_style, "none") != 0)) error->all(FLERR,"compute stress/mop/profile does not account for dihedral potentials"); if (force->improper!=nullptr) - error->all(FLERR,"compute stress/mop/profile does not account for improper potentials"); + if ((strcmp(force->improper_style, "zero") != 0) && (strcmp(force->improper_style, "none") != 0)) + error->all(FLERR,"compute stress/mop/profile does not account for improper potentials"); if (force->kspace!=nullptr) error->all(FLERR,"compute stress/mop/profile does not account for kspace contributions"); } From 0cff31060b5342f69d0b8d382fab423f29677fb4 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Sun, 4 Jun 2023 16:10:24 +0300 Subject: [PATCH 325/448] Update compute_stress_mop.cpp --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index c9557a7ef3..50eb3425f8 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -232,9 +232,11 @@ void ComputeStressMop::init() angleflag = 1; } if (force->dihedral!=nullptr) - error->all(FLERR,"compute stress/mop does not account for dihedral potentials"); + if ((strcmp(force->dihedral_style, "zero") != 0) && (strcmp(force->dihedral_style, "none") != 0)) + error->all(FLERR,"compute stress/mop does not account for dihedral potentials"); if (force->improper!=nullptr) - error->all(FLERR,"compute stress/mop does not account for improper potentials"); + if ((strcmp(force->improper_style, "zero") != 0) && (strcmp(force->improper_style, "none") != 0)) + error->all(FLERR,"compute stress/mop does not account for improper potentials"); if (force->kspace!=nullptr) error->all(FLERR,"compute stress/mop does not account for kspace contributions"); } From ead5a28d354297f20ea40b090aa19f87968a9ce6 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Mon, 5 Jun 2023 18:53:45 +0300 Subject: [PATCH 326/448] Update compute_stress_mop.cpp --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index 50eb3425f8..e5d0e2ed13 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -227,7 +227,8 @@ void ComputeStressMop::init() if (force->bond!=nullptr) bondflag = 1; if (force->angle!=nullptr) if (force->angle->born_matrix_enable == 0) { - error->all(FLERR,"compute stress/mop does not account for angle potentials"); + if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0)) + error->all(FLERR,"compute stress/mop does not account for angle potentials"); } else { angleflag = 1; } @@ -238,7 +239,7 @@ void ComputeStressMop::init() if ((strcmp(force->improper_style, "zero") != 0) && (strcmp(force->improper_style, "none") != 0)) error->all(FLERR,"compute stress/mop does not account for improper potentials"); if (force->kspace!=nullptr) - error->all(FLERR,"compute stress/mop does not account for kspace contributions"); + error->warning(FLERR,"compute stress/mop does not account for kspace contributions"); } // need an occasional half neighbor list From 8eed55b56c8330e46fd3715fca962140a0691b52 Mon Sep 17 00:00:00 2001 From: Evangelos Voyiatzis Date: Mon, 5 Jun 2023 18:54:26 +0300 Subject: [PATCH 327/448] Update compute_stress_mop_profile.cpp --- src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp index 2c2260d22c..807092b37e 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop_profile.cpp @@ -216,7 +216,7 @@ void ComputeStressMopProfile::init() if ((strcmp(force->improper_style, "zero") != 0) && (strcmp(force->improper_style, "none") != 0)) error->all(FLERR,"compute stress/mop/profile does not account for improper potentials"); if (force->kspace!=nullptr) - error->all(FLERR,"compute stress/mop/profile does not account for kspace contributions"); + error->warning(FLERR,"compute stress/mop/profile does not account for kspace contributions"); } // need an occasional half neighbor list From a12133ce03fabe7d5746ea8a49905ca1f84267b2 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 5 Jun 2023 09:59:38 -0600 Subject: [PATCH 328/448] Update Kokkos library in LAMMPS to v3.7.2 --- lib/kokkos/CHANGELOG.md | 23 +++++- lib/kokkos/CMakeLists.txt | 2 +- lib/kokkos/Makefile.kokkos | 2 +- lib/kokkos/algorithms/src/CMakeLists.txt | 2 +- lib/kokkos/cmake/kokkos_arch.cmake | 3 + lib/kokkos/cmake/kokkos_tribits.cmake | 7 -- .../containers/src/Kokkos_DynamicView.hpp | 4 +- .../containers/unit_tests/TestDynamicView.hpp | 77 +++++++++++++++++++ lib/kokkos/core/perf_test/test_atomic.cpp | 2 +- .../core/src/HIP/Kokkos_HIP_Instance.cpp | 2 + lib/kokkos/core/src/Kokkos_Macros.hpp | 8 +- lib/kokkos/core/src/Kokkos_ScratchSpace.hpp | 56 +++++++++----- lib/kokkos/core/src/Kokkos_Serial.hpp | 8 -- lib/kokkos/core/src/Kokkos_View.hpp | 24 ++++-- lib/kokkos/core/src/Serial/Kokkos_Serial.cpp | 8 +- .../Serial/Kokkos_Serial_Parallel_MDRange.hpp | 19 ++--- lib/kokkos/core/src/impl/Kokkos_Core.cpp | 5 +- .../impl/Kokkos_InitializationSettings.hpp | 4 +- lib/kokkos/core/src/impl/Kokkos_Profiling.cpp | 6 +- .../unit_test/TestDefaultDeviceTypeInit.hpp | 24 +++--- lib/kokkos/core/unit_test/TestSharedAlloc.hpp | 4 +- lib/kokkos/core/unit_test/TestTeam.hpp | 66 +++++++++++++++- .../unit_test/cuda/TestCuda_InterOp_Init.cpp | 4 +- .../cuda/TestCuda_InterOp_Streams.cpp | 4 +- .../unit_test/hip/TestHIP_InterOp_Init.cpp | 4 +- .../unit_test/hip/TestHIP_InterOp_Streams.cpp | 4 +- .../unit_test/sycl/TestSYCL_InterOp_Init.cpp | 2 +- .../sycl/TestSYCL_InterOp_Init_Context.cpp | 1 + .../sycl/TestSYCL_InterOp_Streams.cpp | 8 +- .../include/desul/atomics/Lock_Array_Cuda.hpp | 49 +++++++----- lib/kokkos/tpls/desul/src/Lock_Array_CUDA.cpp | 4 +- 31 files changed, 312 insertions(+), 124 deletions(-) diff --git a/lib/kokkos/CHANGELOG.md b/lib/kokkos/CHANGELOG.md index bdbc75604b..34df76a0fd 100644 --- a/lib/kokkos/CHANGELOG.md +++ b/lib/kokkos/CHANGELOG.md @@ -1,4 +1,25 @@ -# Change Log +# CHANGELOG + +## [3.7.02](https://github.com/kokkos/kokkos/tree/3.7.02) (2023-05-17) +[Full Changelog](https://github.com/kokkos/kokkos/compare/3.7.01...3.7.02) + +### Backends and Archs Enhancements: +#### CUDA +- Add Hopper support and update nvcc_wrapper to work with CUDA-12 [\#5693](https://github.com/kokkos/kokkos/pull/5693) +### General Enhancements: +- sprintf -> snprintf [\#5787](https://github.com/kokkos/kokkos/pull/5787) +### Build System: +- Add error message when not using `hipcc` and when `CMAKE_CXX_STANDARD` is not set [\#5945](https://github.com/kokkos/kokkos/pull/5945) +### Bug Fixes: +- Fix Scratch allocation alignment issues [\#5692](https://github.com/kokkos/kokkos/pull/5692) +- Fix Intel Classic Compiler ICE [\#5710](https://github.com/kokkos/kokkos/pull/5710) +- Don't install std algorithm headers multiple times [\#5711](https://github.com/kokkos/kokkos/pull/5711) +- Fix static init order issue in InitalizationSettings [\#5721](https://github.com/kokkos/kokkos/pull/5721) +- Fix src/dst Properties in deep_copy(DynamicView,View) [\#5732](https://github.com/kokkos/kokkos/pull/5732) +- Fix build on Fedora Rawhide [\#5782](https://github.com/kokkos/kokkos/pull/5782) +- Finalize HIP lock arrays [\#5694](https://github.com/kokkos/kokkos/pull/5694) +- Fix CUDA lock arrays for current Desul [\#5812](https://github.com/kokkos/kokkos/pull/5812) +- Set the correct device/context in InterOp tests [\#5701](https://github.com/kokkos/kokkos/pull/5701) ## [3.7.01](https://github.com/kokkos/kokkos/tree/3.7.01) (2022-12-01) [Full Changelog](https://github.com/kokkos/kokkos/compare/3.7.00...3.7.01) diff --git a/lib/kokkos/CMakeLists.txt b/lib/kokkos/CMakeLists.txt index 7b78f29d73..404aad8065 100644 --- a/lib/kokkos/CMakeLists.txt +++ b/lib/kokkos/CMakeLists.txt @@ -129,7 +129,7 @@ ENDIF() set(Kokkos_VERSION_MAJOR 3) set(Kokkos_VERSION_MINOR 7) -set(Kokkos_VERSION_PATCH 01) +set(Kokkos_VERSION_PATCH 02) set(Kokkos_VERSION "${Kokkos_VERSION_MAJOR}.${Kokkos_VERSION_MINOR}.${Kokkos_VERSION_PATCH}") math(EXPR KOKKOS_VERSION "${Kokkos_VERSION_MAJOR} * 10000 + ${Kokkos_VERSION_MINOR} * 100 + ${Kokkos_VERSION_PATCH}") diff --git a/lib/kokkos/Makefile.kokkos b/lib/kokkos/Makefile.kokkos index b873fd1e06..361995d847 100644 --- a/lib/kokkos/Makefile.kokkos +++ b/lib/kokkos/Makefile.kokkos @@ -12,7 +12,7 @@ endif KOKKOS_VERSION_MAJOR = 3 KOKKOS_VERSION_MINOR = 7 -KOKKOS_VERSION_PATCH = 01 +KOKKOS_VERSION_PATCH = 02 KOKKOS_VERSION = $(shell echo $(KOKKOS_VERSION_MAJOR)*10000+$(KOKKOS_VERSION_MINOR)*100+$(KOKKOS_VERSION_PATCH) | bc) # Options: Cuda,HIP,SYCL,OpenMPTarget,OpenMP,Threads,Serial diff --git a/lib/kokkos/algorithms/src/CMakeLists.txt b/lib/kokkos/algorithms/src/CMakeLists.txt index 597626b111..606d83d18b 100644 --- a/lib/kokkos/algorithms/src/CMakeLists.txt +++ b/lib/kokkos/algorithms/src/CMakeLists.txt @@ -25,7 +25,7 @@ INSTALL ( # These will get ignored for standalone CMake and a true interface library made KOKKOS_ADD_INTERFACE_LIBRARY( kokkosalgorithms - HEADERS ${ALGO_HEADERS} + NOINSTALLHEADERS ${ALGO_HEADERS} SOURCES ${ALGO_SOURCES} ) KOKKOS_LIB_INCLUDE_DIRECTORIES(kokkosalgorithms diff --git a/lib/kokkos/cmake/kokkos_arch.cmake b/lib/kokkos/cmake/kokkos_arch.cmake index f20a91e42f..3aff6857a3 100644 --- a/lib/kokkos/cmake/kokkos_arch.cmake +++ b/lib/kokkos/cmake/kokkos_arch.cmake @@ -214,6 +214,9 @@ GLOBAL_SET(KOKKOS_AMDGPU_OPTIONS) IF(KOKKOS_ENABLE_HIP) SET(AMDGPU_ARCH_FLAG "--offload-arch") IF(NOT KOKKOS_CXX_COMPILER_ID STREQUAL HIPCC) + IF(KOKKOS_CXX_STANDARD STREQUAL 14 AND NOT CMAKE_CXX_STANDARD) + message(FATAL_ERROR "Set CMAKE_CXX_STANDARD to 14") + ENDIF() GLOBAL_APPEND(KOKKOS_AMDGPU_OPTIONS -x hip) IF(DEFINED ENV{ROCM_PATH}) GLOBAL_APPEND(KOKKOS_AMDGPU_OPTIONS --rocm-path=$ENV{ROCM_PATH}) diff --git a/lib/kokkos/cmake/kokkos_tribits.cmake b/lib/kokkos/cmake/kokkos_tribits.cmake index 34e45ecf72..9a55d2a5e9 100644 --- a/lib/kokkos/cmake/kokkos_tribits.cmake +++ b/lib/kokkos/cmake/kokkos_tribits.cmake @@ -534,13 +534,6 @@ FUNCTION(KOKKOS_ADD_INTERFACE_LIBRARY NAME) IF (KOKKOS_HAS_TRILINOS) TRIBITS_ADD_LIBRARY(${NAME} ${ARGN}) ELSE() - CMAKE_PARSE_ARGUMENTS(PARSE - "" - "" - "HEADERS;SOURCES" - ${ARGN} - ) - ADD_LIBRARY(${NAME} INTERFACE) KOKKOS_INTERNAL_ADD_LIBRARY_INSTALL(${NAME}) ENDIF() diff --git a/lib/kokkos/containers/src/Kokkos_DynamicView.hpp b/lib/kokkos/containers/src/Kokkos_DynamicView.hpp index a2b68064de..8450c06077 100644 --- a/lib/kokkos/containers/src/Kokkos_DynamicView.hpp +++ b/lib/kokkos/containers/src/Kokkos_DynamicView.hpp @@ -915,8 +915,8 @@ inline void deep_copy(const View& dst, template inline void deep_copy(const Kokkos::Experimental::DynamicView& dst, const View& src) { - using dst_type = Kokkos::Experimental::DynamicView; - using src_type = View; + using dst_type = Kokkos::Experimental::DynamicView; + using src_type = View; using dst_execution_space = typename ViewTraits::execution_space; using src_memory_space = typename ViewTraits::memory_space; diff --git a/lib/kokkos/containers/unit_tests/TestDynamicView.hpp b/lib/kokkos/containers/unit_tests/TestDynamicView.hpp index 5345f8ea24..303e3643c9 100644 --- a/lib/kokkos/containers/unit_tests/TestDynamicView.hpp +++ b/lib/kokkos/containers/unit_tests/TestDynamicView.hpp @@ -240,6 +240,83 @@ struct TestDynamicView { ASSERT_EQ(new_result_sum, (value_type)(da_resize * (da_resize - 1) / 2)); #endif } // end scope + + // Test: Reproducer to demonstrate compile-time error of deep_copy + // of DynamicView to/from on-host View. + // Case 4: + { + using device_view_type = Kokkos::View; + using host_view_type = typename Kokkos::View::HostMirror; + + view_type device_dynamic_view("on-device DynamicView", 1024, + arg_total_size); + device_view_type device_view("on-device View", arg_total_size); + host_view_type host_view("on-host View", arg_total_size); + + unsigned da_size = arg_total_size / 8; + device_dynamic_view.resize_serial(da_size); + + // Use parallel_for to populate device_dynamic_view and verify values +#if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA) + Kokkos::parallel_for( + Kokkos::RangePolicy(0, da_size), + KOKKOS_LAMBDA(const int i) { device_dynamic_view(i) = Scalar(i); }); + + value_type result_sum = 0.0; + Kokkos::parallel_reduce( + Kokkos::RangePolicy(0, da_size), + KOKKOS_LAMBDA(const int i, value_type& partial_sum) { + partial_sum += (value_type)device_dynamic_view(i); + }, + result_sum); + + ASSERT_EQ(result_sum, (value_type)(da_size * (da_size - 1) / 2)); +#endif + + // Use an on-device View as intermediate to deep_copy the + // device_dynamic_view to host, zero out the device_dynamic_view, + // deep_copy from host back to the device_dynamic_view and verify + Kokkos::deep_copy(device_view, device_dynamic_view); + Kokkos::deep_copy(host_view, device_view); + Kokkos::deep_copy(device_view, host_view); +#if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA) + Kokkos::parallel_for( + Kokkos::RangePolicy(0, da_size), + KOKKOS_LAMBDA(const int i) { device_dynamic_view(i) = Scalar(0); }); +#endif + Kokkos::deep_copy(device_dynamic_view, device_view); +#if defined(KOKKOS_ENABLE_CXX11_DISPATCH_LAMBDA) + value_type new_result_sum = 0.0; + Kokkos::parallel_reduce( + Kokkos::RangePolicy(0, da_size), + KOKKOS_LAMBDA(const int i, value_type& partial_sum) { + partial_sum += (value_type)device_dynamic_view(i); + }, + new_result_sum); + + ASSERT_EQ(new_result_sum, (value_type)(da_size * (da_size - 1) / 2)); +#endif + + // Try to deep_copy device_dynamic_view directly to/from host. + // host-to-device currently fails to compile because DP and SP are + // swapped in the deep_copy implementation. + // Once that's fixed, both deep_copy's will fail at runtime because the + // destination execution space cannot access the source memory space. + try { + Kokkos::deep_copy(host_view, device_dynamic_view); + } catch (std::runtime_error const& error) { + std::string msg = error.what(); + std::cerr << "Copy from on-device DynamicView to on-host View failed:\n" + << msg << std::endl; + } + try { + Kokkos::deep_copy(device_dynamic_view, host_view); + } catch (std::runtime_error const& error) { + std::string msg = error.what(); + std::cerr << "Copy from on-host View to on-device DynamicView failed:\n" + << msg << std::endl; + } + } } }; diff --git a/lib/kokkos/core/perf_test/test_atomic.cpp b/lib/kokkos/core/perf_test/test_atomic.cpp index 54824e5b39..094c40bfa7 100644 --- a/lib/kokkos/core/perf_test/test_atomic.cpp +++ b/lib/kokkos/core/perf_test/test_atomic.cpp @@ -73,7 +73,7 @@ void textcolor(int attr, int fg, int bg) { char command[40]; /* Command is the control command to the terminal */ - sprintf(command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40); + snprintf(command, 40, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40); printf("%s", command); } void textcolor_standard() { textcolor(RESET, BLACK, WHITE); } diff --git a/lib/kokkos/core/src/HIP/Kokkos_HIP_Instance.cpp b/lib/kokkos/core/src/HIP/Kokkos_HIP_Instance.cpp index 3785cfe80b..bdba322fcc 100644 --- a/lib/kokkos/core/src/HIP/Kokkos_HIP_Instance.cpp +++ b/lib/kokkos/core/src/HIP/Kokkos_HIP_Instance.cpp @@ -428,6 +428,8 @@ void HIPInternal::finalize() { if (this == &singleton()) { (void)Kokkos::Impl::hip_global_unique_token_locks(true); + Kokkos::Impl::finalize_host_hip_lock_arrays(); + KOKKOS_IMPL_HIP_SAFE_CALL(hipHostFree(constantMemHostStaging)); KOKKOS_IMPL_HIP_SAFE_CALL(hipEventDestroy(constantMemReusable)); } diff --git a/lib/kokkos/core/src/Kokkos_Macros.hpp b/lib/kokkos/core/src/Kokkos_Macros.hpp index e42944d819..8d2aa4d188 100644 --- a/lib/kokkos/core/src/Kokkos_Macros.hpp +++ b/lib/kokkos/core/src/Kokkos_Macros.hpp @@ -228,11 +228,6 @@ #define KOKKOS_ENABLE_PRAGMA_SIMD 1 #endif -// FIXME Workaround for ICE with intel 17,18,19,20,21 in Trilinos -#if (KOKKOS_COMPILER_INTEL <= 2100) -#define KOKKOS_IMPL_WORKAROUND_ICE_IN_TRILINOS_WITH_OLD_INTEL_COMPILERS -#endif - // FIXME_SYCL #if !defined(KOKKOS_ENABLE_SYCL) #define KOKKOS_ENABLE_PRAGMA_IVDEP 1 @@ -653,7 +648,8 @@ static constexpr bool kokkos_omp_on_host() { return false; } #if (defined(KOKKOS_COMPILER_GNU) || defined(KOKKOS_COMPILER_CLANG) || \ defined(KOKKOS_COMPILER_INTEL) || defined(KOKKOS_COMPILER_PGI)) && \ !defined(_WIN32) -#if (!defined(__linux__) || defined(__GLIBC_MINOR__)) +// disable stacktrace for musl-libc +#if !defined(__linux__) || defined(__GLIBC_MINOR__) #define KOKKOS_IMPL_ENABLE_STACKTRACE #endif #define KOKKOS_IMPL_ENABLE_CXXABI diff --git a/lib/kokkos/core/src/Kokkos_ScratchSpace.hpp b/lib/kokkos/core/src/Kokkos_ScratchSpace.hpp index 3e37eb61dc..a1d77071f5 100644 --- a/lib/kokkos/core/src/Kokkos_ScratchSpace.hpp +++ b/lib/kokkos/core/src/Kokkos_ScratchSpace.hpp @@ -73,9 +73,8 @@ class ScratchMemorySpace { "Instantiating ScratchMemorySpace on non-execution-space type."); public: - // Alignment of memory chunks returned by 'get' - // must be a power of two - enum { ALIGN = 8 }; + // Minimal overalignment used by view scratch allocations + constexpr static int ALIGN = 8; private: mutable char* m_iter_L0 = nullptr; @@ -87,7 +86,9 @@ class ScratchMemorySpace { mutable int m_offset = 0; mutable int m_default_level = 0; - enum { MASK = ALIGN - 1 }; // Alignment used by View::shmem_size +#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 + constexpr static int DEFAULT_ALIGNMENT_MASK = ALIGN - 1; +#endif public: //! Tag this class as a memory space @@ -101,39 +102,59 @@ class ScratchMemorySpace { static constexpr const char* name() { return "ScratchMemorySpace"; } +#ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 + // This function is unused template - KOKKOS_INLINE_FUNCTION static IntType align(const IntType& size) { - return (size + MASK) & ~MASK; + KOKKOS_DEPRECATED KOKKOS_INLINE_FUNCTION static constexpr IntType align( + const IntType& size) { + return (size + DEFAULT_ALIGNMENT_MASK) & ~DEFAULT_ALIGNMENT_MASK; } +#endif template KOKKOS_INLINE_FUNCTION void* get_shmem(const IntType& size, int level = -1) const { - return get_shmem_common(size, 1, level); + return get_shmem_common(size, 1, level); } template KOKKOS_INLINE_FUNCTION void* get_shmem_aligned(const IntType& size, const ptrdiff_t alignment, int level = -1) const { - return get_shmem_common(size, alignment, level); + return get_shmem_common(size, alignment, + level); } private: - template + template KOKKOS_INLINE_FUNCTION void* get_shmem_common(const IntType& size, const ptrdiff_t alignment, int level = -1) const { if (level == -1) level = m_default_level; - auto& m_iter = (level == 0) ? m_iter_L0 : m_iter_L1; - auto& m_end = (level == 0) ? m_end_L0 : m_end_L1; - char* previous = m_iter; - const ptrdiff_t missalign = size_t(m_iter) % alignment; - if (missalign) m_iter += alignment - missalign; + auto& m_iter = (level == 0) ? m_iter_L0 : m_iter_L1; + auto& m_end = (level == 0) ? m_end_L0 : m_end_L1; - void* tmp = m_iter + m_offset * (aligned ? size : align(size)); - if (m_end < (m_iter += (aligned ? size : align(size)) * m_multiplier)) { - m_iter = previous; // put it back like it was + if (alignment_requested) { + const ptrdiff_t missalign = size_t(m_iter) % alignment; + if (missalign) m_iter += alignment - missalign; + } + + // This is each thread's start pointer for its allocation + // Note: for team scratch m_offset is 0, since every + // thread will get back the same shared pointer + void* tmp = m_iter + m_offset * size; + ptrdiff_t increment = size * m_multiplier; + + // increment m_iter first and decrement it again if not + // enough memory was available. In the non-failing path + // this will save instructions. + m_iter += increment; + + if (m_end < m_iter) { + // Request did overflow: reset the base team ptr, and + // return nullptr + m_iter -= increment; + tmp = nullptr; #ifdef KOKKOS_ENABLE_DEBUG // mfh 23 Jun 2015: printf call consumes 25 registers // in a CUDA build, so only print in debug mode. The @@ -143,7 +164,6 @@ class ScratchMemorySpace { "%ld byte(s); remaining capacity is %ld byte(s)\n", long(size), long(m_end - m_iter)); #endif // KOKKOS_ENABLE_DEBUG - tmp = nullptr; } return tmp; } diff --git a/lib/kokkos/core/src/Kokkos_Serial.hpp b/lib/kokkos/core/src/Kokkos_Serial.hpp index ffdd1e9fc8..b0d1d693fc 100644 --- a/lib/kokkos/core/src/Kokkos_Serial.hpp +++ b/lib/kokkos/core/src/Kokkos_Serial.hpp @@ -203,19 +203,11 @@ class Serial { static const char* name(); Impl::SerialInternal* impl_internal_space_instance() const { -#ifdef KOKKOS_IMPL_WORKAROUND_ICE_IN_TRILINOS_WITH_OLD_INTEL_COMPILERS - return m_space_instance; -#else return m_space_instance.get(); -#endif } private: -#ifdef KOKKOS_IMPL_WORKAROUND_ICE_IN_TRILINOS_WITH_OLD_INTEL_COMPILERS - Impl::SerialInternal* m_space_instance; -#else Kokkos::Impl::HostSharedPtr m_space_instance; -#endif //-------------------------------------------------------------------------- }; diff --git a/lib/kokkos/core/src/Kokkos_View.hpp b/lib/kokkos/core/src/Kokkos_View.hpp index f8dcfc869e..795ef91e6a 100644 --- a/lib/kokkos/core/src/Kokkos_View.hpp +++ b/lib/kokkos/core/src/Kokkos_View.hpp @@ -67,6 +67,8 @@ KOKKOS_IMPL_WARNING("Including non-public Kokkos header files is not allowed.") #include +#include + //---------------------------------------------------------------------------- //---------------------------------------------------------------------------- @@ -1692,19 +1694,27 @@ class View : public ViewTraits { arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7)); } + private: + // Want to be able to align to minimum scratch alignment or sizeof or alignof + // elements + static constexpr size_t scratch_value_alignment = + ::Kokkos::max(::Kokkos::max(sizeof(typename traits::value_type), + alignof(typename traits::value_type)), + static_cast( + traits::execution_space::scratch_memory_space::ALIGN)); + + public: static KOKKOS_INLINE_FUNCTION size_t shmem_size(typename traits::array_layout const& arg_layout) { - return map_type::memory_span(arg_layout) + - sizeof(typename traits::value_type); + return map_type::memory_span(arg_layout) + scratch_value_alignment; } explicit KOKKOS_INLINE_FUNCTION View( const typename traits::execution_space::scratch_memory_space& arg_space, const typename traits::array_layout& arg_layout) - : View(Impl::ViewCtorProp( - reinterpret_cast(arg_space.get_shmem_aligned( - map_type::memory_span(arg_layout), - sizeof(typename traits::value_type)))), + : View(Impl::ViewCtorProp(reinterpret_cast( + arg_space.get_shmem_aligned(map_type::memory_span(arg_layout), + scratch_value_alignment))), arg_layout) {} explicit KOKKOS_INLINE_FUNCTION View( @@ -1722,7 +1732,7 @@ class View : public ViewTraits { map_type::memory_span(typename traits::array_layout( arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7)), - sizeof(typename traits::value_type)))), + scratch_value_alignment))), typename traits::array_layout(arg_N0, arg_N1, arg_N2, arg_N3, arg_N4, arg_N5, arg_N6, arg_N7), check_input_args::yes) { diff --git a/lib/kokkos/core/src/Serial/Kokkos_Serial.cpp b/lib/kokkos/core/src/Serial/Kokkos_Serial.cpp index 9205e82560..25d220e45d 100644 --- a/lib/kokkos/core/src/Serial/Kokkos_Serial.cpp +++ b/lib/kokkos/core/src/Serial/Kokkos_Serial.cpp @@ -173,14 +173,8 @@ void SerialInternal::resize_thread_team_data(size_t pool_reduce_bytes, } // namespace Impl Serial::Serial() -#ifdef KOKKOS_IMPL_WORKAROUND_ICE_IN_TRILINOS_WITH_OLD_INTEL_COMPILERS - : m_space_instance(&Impl::SerialInternal::singleton()) { -} -#else : m_space_instance(&Impl::SerialInternal::singleton(), - [](Impl::SerialInternal*) {}) { -} -#endif + [](Impl::SerialInternal*) {}) {} void Serial::print_configuration(std::ostream& os, bool /*verbose*/) const { os << "Host Serial Execution Space:\n"; diff --git a/lib/kokkos/core/src/Serial/Kokkos_Serial_Parallel_MDRange.hpp b/lib/kokkos/core/src/Serial/Kokkos_Serial_Parallel_MDRange.hpp index d726a86f76..c3e28c59f4 100644 --- a/lib/kokkos/core/src/Serial/Kokkos_Serial_Parallel_MDRange.hpp +++ b/lib/kokkos/core/src/Serial/Kokkos_Serial_Parallel_MDRange.hpp @@ -63,11 +63,10 @@ class ParallelFor, const FunctorType m_functor; const MDRangePolicy m_mdr_policy; - const Policy m_policy; void exec() const { - const typename Policy::member_type e = m_policy.end(); - for (typename Policy::member_type i = m_policy.begin(); i < e; ++i) { + const typename Policy::member_type e = m_mdr_policy.m_num_tiles; + for (typename Policy::member_type i = 0; i < e; ++i) { iterate_type(m_mdr_policy, m_functor)(i); } } @@ -85,9 +84,7 @@ class ParallelFor, } inline ParallelFor(const FunctorType& arg_functor, const MDRangePolicy& arg_policy) - : m_functor(arg_functor), - m_mdr_policy(arg_policy), - m_policy(Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1)) {} + : m_functor(arg_functor), m_mdr_policy(arg_policy) {} }; template @@ -120,13 +117,12 @@ class ParallelReduce, ReducerType, const FunctorType m_functor; const MDRangePolicy m_mdr_policy; - const Policy m_policy; const ReducerType m_reducer; const pointer_type m_result_ptr; inline void exec(reference_type update) const { - const typename Policy::member_type e = m_policy.end(); - for (typename Policy::member_type i = m_policy.begin(); i < e; ++i) { + const typename Policy::member_type e = m_mdr_policy.m_num_tiles; + for (typename Policy::member_type i = 0; i < e; ++i) { iterate_type(m_mdr_policy, m_functor, update)(i); } } @@ -148,7 +144,8 @@ class ParallelReduce, ReducerType, const size_t team_shared_size = 0; // Never shrinks const size_t thread_local_size = 0; // Never shrinks - auto* internal_instance = m_policy.space().impl_internal_space_instance(); + auto* internal_instance = + m_mdr_policy.space().impl_internal_space_instance(); // Need to lock resize_thread_team_data std::lock_guard lock( internal_instance->m_thread_team_data_mutex); @@ -181,7 +178,6 @@ class ParallelReduce, ReducerType, void*> = nullptr) : m_functor(arg_functor), m_mdr_policy(arg_policy), - m_policy(Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1)), m_reducer(InvalidType()), m_result_ptr(arg_result_view.data()) { static_assert(Kokkos::is_view::value, @@ -197,7 +193,6 @@ class ParallelReduce, ReducerType, MDRangePolicy arg_policy, const ReducerType& reducer) : m_functor(arg_functor), m_mdr_policy(arg_policy), - m_policy(Policy(0, m_mdr_policy.m_num_tiles).set_chunk_size(1)), m_reducer(reducer), m_result_ptr(reducer.view().data()) { /*static_assert( std::is_same< typename ViewType::memory_space diff --git a/lib/kokkos/core/src/impl/Kokkos_Core.cpp b/lib/kokkos/core/src/impl/Kokkos_Core.cpp index a5bd003237..fc89e485fd 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Core.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Core.cpp @@ -1165,6 +1165,5 @@ void _kokkos_pgi_compiler_bug_workaround() {} #endif } // namespace Kokkos -Kokkos::Impl::InitializationSettingsHelper::storage_type const - Kokkos::Impl::InitializationSettingsHelper::unspecified = - "some string we don't expect user would ever provide"; +constexpr char + Kokkos::Impl::InitializationSettingsHelper::unspecified[]; diff --git a/lib/kokkos/core/src/impl/Kokkos_InitializationSettings.hpp b/lib/kokkos/core/src/impl/Kokkos_InitializationSettings.hpp index ceb35f0247..00b2335fd7 100644 --- a/lib/kokkos/core/src/impl/Kokkos_InitializationSettings.hpp +++ b/lib/kokkos/core/src/impl/Kokkos_InitializationSettings.hpp @@ -104,7 +104,9 @@ struct InitializationSettingsHelper { using value_type = std::string; using storage_type = std::string; - static storage_type const unspecified; + // prefer c-string to avoid static initialization order nightmare + static constexpr char unspecified[] = + "some string we don't expect user would ever provide"; }; } // namespace Impl diff --git a/lib/kokkos/core/src/impl/Kokkos_Profiling.cpp b/lib/kokkos/core/src/impl/Kokkos_Profiling.cpp index 480b1a392b..796552cead 100644 --- a/lib/kokkos/core/src/impl/Kokkos_Profiling.cpp +++ b/lib/kokkos/core/src/impl/Kokkos_Profiling.cpp @@ -655,9 +655,9 @@ void initialize(const std::string& profileLibrary) { char* envProfileLibrary = const_cast(profileLibrary.c_str()); - const auto envProfileCopy = - std::make_unique(strlen(envProfileLibrary) + 1); - sprintf(envProfileCopy.get(), "%s", envProfileLibrary); + const size_t envProfileLen = strlen(envProfileLibrary) + 1; + const auto envProfileCopy = std::make_unique(envProfileLen); + snprintf(envProfileCopy.get(), envProfileLen, "%s", envProfileLibrary); char* profileLibraryName = strtok(envProfileCopy.get(), ";"); diff --git a/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp b/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp index d915b7e472..55a29f1128 100644 --- a/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp +++ b/lib/kokkos/core/unit_test/TestDefaultDeviceTypeInit.hpp @@ -69,9 +69,10 @@ char** init_kokkos_args(bool do_threads, bool do_numa, bool do_device, nargs = (do_threads ? 1 : 0) + (do_numa ? 1 : 0) + (do_device ? 1 : 0) + (do_other ? 4 : 0) + (do_tune ? 1 : 0); - char** args_kokkos = new char*[nargs]; + char** args_kokkos = new char*[nargs]; + const int max_args_size = 45; for (int i = 0; i < nargs; i++) { - args_kokkos[i] = new char[45]; + args_kokkos[i] = new char[max_args_size]; delete_these.insert(args_kokkos[i]); } @@ -112,7 +113,7 @@ char** init_kokkos_args(bool do_threads, bool do_numa, bool do_device, #endif init_args.num_threads = nthreads; - sprintf(args_kokkos[threads_idx], "--threads=%i", nthreads); + snprintf(args_kokkos[threads_idx], max_args_size, "--threads=%i", nthreads); } if (do_numa) { @@ -130,24 +131,27 @@ char** init_kokkos_args(bool do_threads, bool do_numa, bool do_device, #endif init_args.num_numa = numa; - sprintf(args_kokkos[numa_idx], "--numa=%i", numa); + snprintf(args_kokkos[numa_idx], max_args_size, "--numa=%i", numa); } if (do_device) { init_args.device_id = 0; - sprintf(args_kokkos[device_idx], "--device-id=%i", 0); + snprintf(args_kokkos[device_idx], max_args_size, "--device-id=%i", 0); } if (do_other) { - sprintf(args_kokkos[0], "--dummyarg=1"); - sprintf(args_kokkos[threads_idx + (do_threads ? 1 : 0)], "--dummy2arg"); - sprintf(args_kokkos[threads_idx + (do_threads ? 1 : 0) + 1], "dummy3arg"); - sprintf(args_kokkos[device_idx + (do_device ? 1 : 0)], "dummy4arg=1"); + snprintf(args_kokkos[0], max_args_size, "--dummyarg=1"); + snprintf(args_kokkos[threads_idx + (do_threads ? 1 : 0)], max_args_size, + "--dummy2arg"); + snprintf(args_kokkos[threads_idx + (do_threads ? 1 : 0) + 1], max_args_size, + "dummy3arg"); + snprintf(args_kokkos[device_idx + (do_device ? 1 : 0)], max_args_size, + "dummy4arg=1"); } if (do_tune) { init_args.tune_internals = true; - sprintf(args_kokkos[tune_idx], "--kokkos-tune-internals"); + snprintf(args_kokkos[tune_idx], max_args_size, "--kokkos-tune-internals"); } return args_kokkos; diff --git a/lib/kokkos/core/unit_test/TestSharedAlloc.hpp b/lib/kokkos/core/unit_test/TestSharedAlloc.hpp index f66b35dc9f..18f3c9a777 100644 --- a/lib/kokkos/core/unit_test/TestSharedAlloc.hpp +++ b/lib/kokkos/core/unit_test/TestSharedAlloc.hpp @@ -91,7 +91,7 @@ void test_shared_alloc() { // Since always executed on host space, leave [=] Kokkos::parallel_for(range, [=](int i) { char name[64]; - sprintf(name, "test_%.2d", i); + snprintf(name, 64, "test_%.2d", i); r[i] = RecordMemS::allocate(s, name, size * (i + 1)); h[i] = Header::get_header(r[i]->data()); @@ -135,7 +135,7 @@ void test_shared_alloc() { Kokkos::parallel_for(range, [=](size_t i) { char name[64]; - sprintf(name, "test_%.2d", int(i)); + snprintf(name, 64, "test_%.2d", int(i)); RecordFull* rec = RecordFull::allocate(s, name, size * (i + 1)); diff --git a/lib/kokkos/core/unit_test/TestTeam.hpp b/lib/kokkos/core/unit_test/TestTeam.hpp index 3f05b2ef66..58db4360e5 100644 --- a/lib/kokkos/core/unit_test/TestTeam.hpp +++ b/lib/kokkos/core/unit_test/TestTeam.hpp @@ -1551,14 +1551,16 @@ struct TestScratchAlignment { double x, y, z; }; TestScratchAlignment() { - test(true); - test(false); + test_view(true); + test_view(false); + test_minimal(); + test_raw(); } using ScratchView = Kokkos::View; using ScratchViewInt = Kokkos::View; - void test(bool allocate_small) { + void test_view(bool allocate_small) { int shmem_size = ScratchView::shmem_size(11); #ifdef KOKKOS_ENABLE_OPENMPTARGET int team_size = @@ -1580,12 +1582,68 @@ struct TestScratchAlignment { }); Kokkos::fence(); } + + void test_minimal() { + using member_type = typename Kokkos::TeamPolicy::member_type; + Kokkos::TeamPolicy policy(1, 1); + size_t scratch_size = sizeof(int); + Kokkos::View flag("Flag"); + + Kokkos::parallel_for( + policy.set_scratch_size(0, Kokkos::PerTeam(scratch_size)), + KOKKOS_LAMBDA(const member_type &team) { + int *scratch_ptr = (int *)team.team_shmem().get_shmem(scratch_size); + if (scratch_ptr == nullptr) flag() = 1; + }); + Kokkos::fence(); + int minimal_scratch_allocation_failed = 0; + Kokkos::deep_copy(minimal_scratch_allocation_failed, flag); + ASSERT_TRUE(minimal_scratch_allocation_failed == 0); + } + + void test_raw() { + using member_type = typename Kokkos::TeamPolicy::member_type; + Kokkos::TeamPolicy policy(1, 1); + Kokkos::View flag("Flag"); + + Kokkos::parallel_for( + policy.set_scratch_size(0, Kokkos::PerTeam(1024)), + KOKKOS_LAMBDA(const member_type &team) { + int *scratch_ptr1 = (int *)team.team_shmem().get_shmem(24); + int *scratch_ptr2 = (int *)team.team_shmem().get_shmem(32); + int *scratch_ptr3 = (int *)team.team_shmem().get_shmem(12); + + if ((int(scratch_ptr2 - scratch_ptr1) != 6) || + (int(scratch_ptr3 - scratch_ptr2) != 8)) + flag() = 1; + + if (((scratch_ptr3 - static_cast(nullptr)) + 3) % 2 == 1) + scratch_ptr1 = (int *)team.team_shmem().get_shmem_aligned(24, 4); + else { + scratch_ptr1 = (int *)team.team_shmem().get_shmem_aligned(12, 4); + } + scratch_ptr2 = (int *)team.team_shmem().get_shmem_aligned(32, 8); + scratch_ptr3 = (int *)team.team_shmem().get_shmem_aligned(8, 4); + + if ((int(scratch_ptr2 - scratch_ptr1) != 7) && + (int(scratch_ptr2 - scratch_ptr1) != 4)) + flag() = 1; + if (int(scratch_ptr3 - scratch_ptr2) != 8) flag() = 1; + if ((int(size_t(scratch_ptr1) % 4) != 0) || + (int(size_t(scratch_ptr2) % 8) != 0) || + (int(size_t(scratch_ptr3) % 4) != 0)) + flag() = 1; + }); + Kokkos::fence(); + int raw_get_shmem_alignment_failed = 0; + Kokkos::deep_copy(raw_get_shmem_alignment_failed, flag); + ASSERT_TRUE(raw_get_shmem_alignment_failed == 0); + } }; } // namespace namespace { - template struct TestTeamPolicyHandleByValue { using scalar = double; diff --git a/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Init.cpp b/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Init.cpp index 31fd63f084..c4381b29e7 100644 --- a/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Init.cpp +++ b/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Init.cpp @@ -59,9 +59,11 @@ __global__ void offset(int* p) { // Test whether allocations survive Kokkos initialize/finalize if done via Raw // Cuda. TEST(cuda, raw_cuda_interop) { + // Make sure that we use the same device for all allocations + Kokkos::initialize(); + int* p; KOKKOS_IMPL_CUDA_SAFE_CALL(cudaMalloc(&p, sizeof(int) * 100)); - Kokkos::initialize(); Kokkos::View> v(p, 100); Kokkos::deep_copy(v, 5); diff --git a/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Streams.cpp b/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Streams.cpp index f11f657e00..69aef6f8d8 100644 --- a/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Streams.cpp +++ b/lib/kokkos/core/unit_test/cuda/TestCuda_InterOp_Streams.cpp @@ -48,9 +48,11 @@ namespace Test { // Test Interoperability with Cuda Streams TEST(cuda, raw_cuda_streams) { + // Make sure that we use the same device for all allocations + Kokkos::initialize(); + cudaStream_t stream; cudaStreamCreate(&stream); - Kokkos::initialize(); int* p; cudaMalloc(&p, sizeof(int) * 100); using MemorySpace = typename TEST_EXECSPACE::memory_space; diff --git a/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Init.cpp b/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Init.cpp index af20e753d4..ce76076f9b 100644 --- a/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Init.cpp +++ b/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Init.cpp @@ -59,9 +59,11 @@ __global__ void offset(int* p) { // Test whether allocations survive Kokkos initialize/finalize if done via Raw // HIP. TEST(hip, raw_hip_interop) { + // Make sure that we use the same device for all allocations + Kokkos::initialize(); + int* p; KOKKOS_IMPL_HIP_SAFE_CALL(hipMalloc(&p, sizeof(int) * 100)); - Kokkos::initialize(); Kokkos::View> v(p, 100); Kokkos::deep_copy(v, 5); diff --git a/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Streams.cpp b/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Streams.cpp index 95d102d4d1..6c7fdd7044 100644 --- a/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Streams.cpp +++ b/lib/kokkos/core/unit_test/hip/TestHIP_InterOp_Streams.cpp @@ -50,9 +50,11 @@ namespace Test { // The difference with the CUDA tests are: raw HIP vs raw CUDA and no launch // bound in HIP due to an error when computing the block size. TEST(hip, raw_hip_streams) { + // Make sure that we use the same device for all allocations + Kokkos::initialize(); + hipStream_t stream; KOKKOS_IMPL_HIP_SAFE_CALL(hipStreamCreate(&stream)); - Kokkos::initialize(); int* p; KOKKOS_IMPL_HIP_SAFE_CALL(hipMalloc(&p, sizeof(int) * 100)); using MemorySpace = typename TEST_EXECSPACE::memory_space; diff --git a/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init.cpp b/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init.cpp index e45d990745..1189aba26f 100644 --- a/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init.cpp +++ b/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init.cpp @@ -52,8 +52,8 @@ namespace Test { // Test whether allocations survive Kokkos initialize/finalize if done via Raw // SYCL. TEST(sycl, raw_sycl_interop) { + // Make sure all queues use the same context Kokkos::initialize(); - Kokkos::Experimental::SYCL default_space; sycl::context default_context = default_space.sycl_queue().get_context(); diff --git a/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init_Context.cpp b/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init_Context.cpp index 114d2a4aa2..7b9a664304 100644 --- a/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init_Context.cpp +++ b/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Init_Context.cpp @@ -51,6 +51,7 @@ namespace Test { // Test whether external allocations can be accessed by the default queue. TEST(sycl, raw_sycl_interop_context_1) { + // Make sure all queues use the same context Kokkos::Experimental::SYCL default_space; sycl::context default_context = default_space.sycl_queue().get_context(); diff --git a/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Streams.cpp b/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Streams.cpp index 8ffada1dab..be093d8edc 100644 --- a/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Streams.cpp +++ b/lib/kokkos/core/unit_test/sycl/TestSYCL_InterOp_Streams.cpp @@ -48,9 +48,13 @@ namespace Test { // Test Interoperability with SYCL Streams TEST(sycl, raw_sycl_queues) { - sycl::default_selector device_selector; - sycl::queue queue(device_selector); + // Make sure all queues use the same context Kokkos::initialize(); + Kokkos::Experimental::SYCL default_space; + sycl::context default_context = default_space.sycl_queue().get_context(); + + sycl::default_selector device_selector; + sycl::queue queue(default_context, device_selector); int* p = sycl::malloc_device(100, queue); using MemorySpace = typename TEST_EXECSPACE::memory_space; diff --git a/lib/kokkos/tpls/desul/include/desul/atomics/Lock_Array_Cuda.hpp b/lib/kokkos/tpls/desul/include/desul/atomics/Lock_Array_Cuda.hpp index 1815adb4a7..b55be52264 100644 --- a/lib/kokkos/tpls/desul/include/desul/atomics/Lock_Array_Cuda.hpp +++ b/lib/kokkos/tpls/desul/include/desul/atomics/Lock_Array_Cuda.hpp @@ -76,7 +76,7 @@ namespace Impl { /// instances in other translation units, we must update this CUDA global /// variable based on the Host global variable prior to running any kernels /// that will use it. -/// That is the purpose of the KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE macro. +/// That is the purpose of the ensure_cuda_lock_arrays_on_device function. __device__ #ifdef __CUDACC_RDC__ __constant__ extern @@ -138,33 +138,42 @@ namespace { static int lock_array_copied = 0; inline int eliminate_warning_for_lock_array() { return lock_array_copied; } } // namespace + +#ifdef __CUDACC_RDC__ +inline +#else +inline static +#endif + void + copy_cuda_lock_arrays_to_device() { + if (lock_array_copied == 0) { + cudaMemcpyToSymbol(CUDA_SPACE_ATOMIC_LOCKS_DEVICE, + &CUDA_SPACE_ATOMIC_LOCKS_DEVICE_h, + sizeof(int32_t*)); + cudaMemcpyToSymbol(CUDA_SPACE_ATOMIC_LOCKS_NODE, + &CUDA_SPACE_ATOMIC_LOCKS_NODE_h, + sizeof(int32_t*)); + } + lock_array_copied = 1; +} + } // namespace Impl } // namespace desul -/* It is critical that this code be a macro, so that it will - capture the right address for desul::Impl::CUDA_SPACE_ATOMIC_LOCKS_DEVICE - putting this in an inline function will NOT do the right thing! */ -#define DESUL_IMPL_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE() \ - { \ - if (::desul::Impl::lock_array_copied == 0) { \ - cudaMemcpyToSymbol(::desul::Impl::CUDA_SPACE_ATOMIC_LOCKS_DEVICE, \ - &::desul::Impl::CUDA_SPACE_ATOMIC_LOCKS_DEVICE_h, \ - sizeof(int32_t*)); \ - cudaMemcpyToSymbol(::desul::Impl::CUDA_SPACE_ATOMIC_LOCKS_NODE, \ - &::desul::Impl::CUDA_SPACE_ATOMIC_LOCKS_NODE_h, \ - sizeof(int32_t*)); \ - } \ - ::desul::Impl::lock_array_copied = 1; \ - } #endif /* defined( __CUDACC__ ) */ #endif /* defined( DESUL_HAVE_CUDA_ATOMICS ) */ +namespace desul { + #if defined(__CUDACC_RDC__) || (!defined(__CUDACC__)) -#define DESUL_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() +inline void ensure_cuda_lock_arrays_on_device() {} #else -#define DESUL_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() \ - DESUL_IMPL_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE() +static inline void ensure_cuda_lock_arrays_on_device() { + Impl::copy_cuda_lock_arrays_to_device(); +} #endif -#endif /* #ifndef KOKKOS_CUDA_LOCKS_HPP_ */ +} // namespace desul + +#endif /* #ifndef DESUL_ATOMICS_LOCK_ARRAY_CUDA_HPP_ */ diff --git a/lib/kokkos/tpls/desul/src/Lock_Array_CUDA.cpp b/lib/kokkos/tpls/desul/src/Lock_Array_CUDA.cpp index cb8482c5da..19944b378e 100644 --- a/lib/kokkos/tpls/desul/src/Lock_Array_CUDA.cpp +++ b/lib/kokkos/tpls/desul/src/Lock_Array_CUDA.cpp @@ -70,7 +70,7 @@ void init_lock_arrays_cuda() { "init_lock_arrays_cuda: cudaMalloc host locks"); auto error_sync1 = cudaDeviceSynchronize(); - DESUL_IMPL_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE(); + copy_cuda_lock_arrays_to_device(); check_error_and_throw_cuda(error_sync1, "init_lock_arrays_cuda: post mallocs"); init_lock_arrays_cuda_kernel<<<(CUDA_SPACE_ATOMIC_MASK + 1 + 255) / 256, 256>>>(); auto error_sync2 = cudaDeviceSynchronize(); @@ -85,7 +85,7 @@ void finalize_lock_arrays_cuda() { CUDA_SPACE_ATOMIC_LOCKS_DEVICE_h = nullptr; CUDA_SPACE_ATOMIC_LOCKS_NODE_h = nullptr; #ifdef __CUDACC_RDC__ - DESUL_IMPL_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE(); + copy_cuda_lock_arrays_to_device(); #endif } From 2e09ba2702639ca5c5ac311e624249ac1f682d42 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 5 Jun 2023 10:08:20 -0600 Subject: [PATCH 329/448] Update CMake --- cmake/Modules/Packages/KOKKOS.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/Modules/Packages/KOKKOS.cmake b/cmake/Modules/Packages/KOKKOS.cmake index aa93e0cd7c..8b695667ae 100644 --- a/cmake/Modules/Packages/KOKKOS.cmake +++ b/cmake/Modules/Packages/KOKKOS.cmake @@ -49,8 +49,8 @@ if(DOWNLOAD_KOKKOS) list(APPEND KOKKOS_LIB_BUILD_ARGS "-DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS}") list(APPEND KOKKOS_LIB_BUILD_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}") include(ExternalProject) - set(KOKKOS_URL "https://github.com/kokkos/kokkos/archive/3.7.01.tar.gz" CACHE STRING "URL for KOKKOS tarball") - set(KOKKOS_MD5 "f140e02b826223b1045207d9bc10d404" CACHE STRING "MD5 checksum of KOKKOS tarball") + set(KOKKOS_URL "https://github.com/kokkos/kokkos/archive/3.7.02.tar.gz" CACHE STRING "URL for KOKKOS tarball") + set(KOKKOS_MD5 "34d7860d548c06a4040236d959c9f99a" CACHE STRING "MD5 checksum of KOKKOS tarball") mark_as_advanced(KOKKOS_URL) mark_as_advanced(KOKKOS_MD5) GetFallbackURL(KOKKOS_URL KOKKOS_FALLBACK) @@ -75,7 +75,7 @@ if(DOWNLOAD_KOKKOS) add_dependencies(LAMMPS::KOKKOSCORE kokkos_build) add_dependencies(LAMMPS::KOKKOSCONTAINERS kokkos_build) elseif(EXTERNAL_KOKKOS) - find_package(Kokkos 3.7.01 REQUIRED CONFIG) + find_package(Kokkos 3.7.02 REQUIRED CONFIG) target_link_libraries(lammps PRIVATE Kokkos::kokkos) else() set(LAMMPS_LIB_KOKKOS_SRC_DIR ${LAMMPS_LIB_SOURCE_DIR}/kokkos) From 966efd8bd53cf170e90a809af696077f6b8b3351 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Mon, 5 Jun 2023 10:33:30 -0600 Subject: [PATCH 330/448] Add missed changes --- .../src/Cuda/Kokkos_Cuda_KernelLaunch.hpp | 2 +- .../core/src/Cuda/Kokkos_Cuda_Locks.cpp | 7 +-- .../core/src/Cuda/Kokkos_Cuda_Locks.hpp | 58 ++++++++++--------- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_KernelLaunch.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_KernelLaunch.hpp index ba43e362bb..a91d0eb313 100644 --- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_KernelLaunch.hpp +++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_KernelLaunch.hpp @@ -710,7 +710,7 @@ struct CudaParallelLaunchImpl< " occupancy requests are currently broken.")); } - KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE(); + ensure_cuda_lock_arrays_on_device(); // Invoke the driver function on the device base_t::invoke_kernel(driver, grid, block, shmem, cuda_instance); diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp index 84d4307cfd..3796534816 100644 --- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp +++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.cpp @@ -79,8 +79,7 @@ CudaLockArrays g_host_cuda_lock_arrays = {nullptr, 0}; void initialize_host_cuda_lock_arrays() { #ifdef KOKKOS_ENABLE_IMPL_DESUL_ATOMICS desul::Impl::init_lock_arrays(); - - DESUL_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE(); + desul::ensure_cuda_lock_arrays_on_device(); #endif if (g_host_cuda_lock_arrays.atomic != nullptr) return; KOKKOS_IMPL_CUDA_SAFE_CALL( @@ -89,7 +88,7 @@ void initialize_host_cuda_lock_arrays() { Impl::cuda_device_synchronize( "Kokkos::Impl::initialize_host_cuda_lock_arrays: Pre Init Lock Arrays"); g_host_cuda_lock_arrays.n = Cuda::concurrency(); - KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE(); + copy_cuda_lock_arrays_to_device(); init_lock_array_kernel_atomic<<<(CUDA_SPACE_ATOMIC_MASK + 1 + 255) / 256, 256>>>(); Impl::cuda_device_synchronize( @@ -106,7 +105,7 @@ void finalize_host_cuda_lock_arrays() { g_host_cuda_lock_arrays.atomic = nullptr; g_host_cuda_lock_arrays.n = 0; #ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE - KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE(); + copy_cuda_lock_arrays_to_device(); #endif } diff --git a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp index bdb7723985..84bfc953fd 100644 --- a/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp +++ b/lib/kokkos/core/src/Cuda/Kokkos_Cuda_Locks.hpp @@ -67,7 +67,7 @@ struct CudaLockArrays { /// \brief This global variable in Host space is the central definition /// of these arrays. -extern Kokkos::Impl::CudaLockArrays g_host_cuda_lock_arrays; +extern CudaLockArrays g_host_cuda_lock_arrays; /// \brief After this call, the g_host_cuda_lock_arrays variable has /// valid, initialized arrays. @@ -105,12 +105,12 @@ namespace Impl { /// instances in other translation units, we must update this CUDA global /// variable based on the Host global variable prior to running any kernels /// that will use it. -/// That is the purpose of the KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE macro. +/// That is the purpose of the ensure_cuda_lock_arrays_on_device function. __device__ #ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE __constant__ extern #endif - Kokkos::Impl::CudaLockArrays g_device_cuda_lock_arrays; + CudaLockArrays g_device_cuda_lock_arrays; #define CUDA_SPACE_ATOMIC_MASK 0x1FFFF @@ -123,9 +123,7 @@ __device__ inline bool lock_address_cuda_space(void* ptr) { size_t offset = size_t(ptr); offset = offset >> 2; offset = offset & CUDA_SPACE_ATOMIC_MASK; - return ( - 0 == - atomicCAS(&Kokkos::Impl::g_device_cuda_lock_arrays.atomic[offset], 0, 1)); + return (0 == atomicCAS(&g_device_cuda_lock_arrays.atomic[offset], 0, 1)); } /// \brief Release lock for the address @@ -138,7 +136,7 @@ __device__ inline void unlock_address_cuda_space(void* ptr) { size_t offset = size_t(ptr); offset = offset >> 2; offset = offset & CUDA_SPACE_ATOMIC_MASK; - atomicExch(&Kokkos::Impl::g_device_cuda_lock_arrays.atomic[offset], 0); + atomicExch(&g_device_cuda_lock_arrays.atomic[offset], 0); } } // namespace Impl @@ -151,45 +149,49 @@ namespace { static int lock_array_copied = 0; inline int eliminate_warning_for_lock_array() { return lock_array_copied; } } // namespace -} // namespace Impl -} // namespace Kokkos -/* Dan Ibanez: it is critical that this code be a macro, so that it will - capture the right address for Kokkos::Impl::g_device_cuda_lock_arrays! - putting this in an inline function will NOT do the right thing! */ -#define KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE() \ - { \ - if (::Kokkos::Impl::lock_array_copied == 0) { \ - KOKKOS_IMPL_CUDA_SAFE_CALL( \ - cudaMemcpyToSymbol(Kokkos::Impl::g_device_cuda_lock_arrays, \ - &Kokkos::Impl::g_host_cuda_lock_arrays, \ - sizeof(Kokkos::Impl::CudaLockArrays))); \ - } \ - lock_array_copied = 1; \ +#ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE +inline +#else +inline static +#endif + void + copy_cuda_lock_arrays_to_device() { + if (lock_array_copied == 0) { + KOKKOS_IMPL_CUDA_SAFE_CALL(cudaMemcpyToSymbol(g_device_cuda_lock_arrays, + &g_host_cuda_lock_arrays, + sizeof(CudaLockArrays))); } + lock_array_copied = 1; +} #ifndef KOKKOS_ENABLE_IMPL_DESUL_ATOMICS #ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE -#define KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() +inline void ensure_cuda_lock_arrays_on_device() {} #else -#define KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() \ - KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE() +inline static void ensure_cuda_lock_arrays_on_device() { + copy_cuda_lock_arrays_to_device(); +} #endif #else #ifdef KOKKOS_ENABLE_CUDA_RELOCATABLE_DEVICE_CODE -#define KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() +inline void ensure_cuda_lock_arrays_on_device() {} #else // Still Need COPY_CUDA_LOCK_ARRAYS for team scratch etc. -#define KOKKOS_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() \ - KOKKOS_COPY_CUDA_LOCK_ARRAYS_TO_DEVICE() \ - DESUL_ENSURE_CUDA_LOCK_ARRAYS_ON_DEVICE() +inline static void ensure_cuda_lock_arrays_on_device() { + copy_cuda_lock_arrays_to_device(); + desul::ensure_cuda_lock_arrays_on_device(); +} #endif #endif /* defined( KOKKOS_ENABLE_IMPL_DESUL_ATOMICS ) */ +} // namespace Impl +} // namespace Kokkos + #endif /* defined( KOKKOS_ENABLE_CUDA ) */ #endif /* #ifndef KOKKOS_CUDA_LOCKS_HPP */ From c558de3ce003e2f77744d82f30d3f967df7be81d Mon Sep 17 00:00:00 2001 From: oywg11 Date: Tue, 6 Jun 2023 08:27:14 +0800 Subject: [PATCH 331/448] remove the fprintf debug outputs --- src/INTERLAYER/pair_ilp_tmd.cpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/src/INTERLAYER/pair_ilp_tmd.cpp b/src/INTERLAYER/pair_ilp_tmd.cpp index c1af7098cd..f0d618687a 100644 --- a/src/INTERLAYER/pair_ilp_tmd.cpp +++ b/src/INTERLAYER/pair_ilp_tmd.cpp @@ -336,9 +336,6 @@ void PairILPTMD::ILP_neigh() } } // end of idenfying the first neighbor } else if (n > Nnei) { - fprintf(screen, "Molecule ID = %d\n", imol); - fprintf(screen, "Atom Type = %d\n", type[i]); - fprintf(screen, "Neinum = %d\n", n); error->one(FLERR, "There are too many neighbors for TMD atoms, please check your configuration"); } @@ -497,9 +494,6 @@ void PairILPTMD::calc_normal() vect[0][1] = x[jH2][1] - ytp; vect[0][2] = x[jH2][2] - ztp; } else { - fprintf(screen, "jH1 jH2 = %d %d\n", jH1,jH2); - fprintf(screen, "Atom Type = %d %d\n", type[jH1],type[jH2]); - fprintf(screen, "For atom i = %d %d\n", tag[i],type[i]); error->one(FLERR, "The order of atoms in water molecule should be O H H !"); } } @@ -662,9 +656,6 @@ void PairILPTMD::calc_normal() cont = 2; } else { - fprintf(screen, "jH1 jH2 = %d %d\n", jH1,jH2); - fprintf(screen, "Atom Type = %d %d\n", type[jH1],type[jH2]); - fprintf(screen, "ID and type of atom i = %d %d\n", tag[i],type[i]); error->one(FLERR, "The order of atoms in water molecule should be O H H !"); } } @@ -728,11 +719,6 @@ void PairILPTMD::calc_normal() dnormdri[i][id][ip] = dpvdri[id][ip] / nn - Nave[id] * dni[ip] / nn2; } } - // printf("%4d:\t%e %e %e\n\t%e %e %e\n\t%e %e %e\n", - // i, dnormdri[i][0][0], dnormdri[i][0][1], dnormdri[i][0][2], - // dnormdri[i][1][0],dnormdri[i][1][1],dnormdri[i][1][2], - // dnormdri[i][2][0],dnormdri[i][2][1],dnormdri[i][2][2]); - // exit(0); } else if (cont >= 3) { error->one(FLERR, From 409bced5fd74e2c9b75a1e153ee126a5507605ca Mon Sep 17 00:00:00 2001 From: oywg11 Date: Tue, 6 Jun 2023 08:35:42 +0800 Subject: [PATCH 332/448] update affiliations --- src/INTERLAYER/pair_coul_shield.cpp | 2 +- src/INTERLAYER/pair_ilp_graphene_hbn.cpp | 4 ++-- src/INTERLAYER/pair_kolmogorov_crespi_full.cpp | 2 +- src/MANYBODY/pair_tersoff.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/INTERLAYER/pair_coul_shield.cpp b/src/INTERLAYER/pair_coul_shield.cpp index e647e1ea91..a5e3e63442 100644 --- a/src/INTERLAYER/pair_coul_shield.cpp +++ b/src/INTERLAYER/pair_coul_shield.cpp @@ -11,7 +11,7 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Wengen Ouyang (Tel Aviv University) + Contributing author: Wengen Ouyang (Wuhan University) e-mail: w.g.ouyang at gmail dot com This is a Coulomb potential described in diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index e6711d0f19..eb37b39864 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -11,11 +11,11 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Wengen Ouyang (Tel Aviv University) + Contributing author: Wengen Ouyang (Wuhan University) e-mail: w.g.ouyang at gmail dot com This is a full version of the potential described in - [Maaravi et al, J. Phys. Chem. C 121, 22826-22835 (2017)] + [Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020)] The definition of normals are the same as that in [Kolmogorov & Crespi, Phys. Rev. B 71, 235415 (2005)] ------------------------------------------------------------------------- */ diff --git a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp index b2eba787b1..b497ae3568 100644 --- a/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp +++ b/src/INTERLAYER/pair_kolmogorov_crespi_full.cpp @@ -12,7 +12,7 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Contributing author: Wengen Ouyang (Tel Aviv University) + Contributing author: Wengen Ouyang (Wuhan University) e-mail: w.g.ouyang at gmail dot com based on previous versions by Jaap Kroes diff --git a/src/MANYBODY/pair_tersoff.cpp b/src/MANYBODY/pair_tersoff.cpp index f38ba00861..c7c45bc865 100644 --- a/src/MANYBODY/pair_tersoff.cpp +++ b/src/MANYBODY/pair_tersoff.cpp @@ -14,7 +14,7 @@ /* ---------------------------------------------------------------------- Contributing author: Aidan Thompson (SNL) - original Tersoff implementation - Wengen Ouyang (TAU) - Shift addition + Wengen Ouyang (WHU) - Shift addition ------------------------------------------------------------------------- */ #include "pair_tersoff.h" From 0ef0419a98adb1d804c17efc0c3d78cb2d549275 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Tue, 6 Jun 2023 21:45:51 +0800 Subject: [PATCH 333/448] rename function names in opt version --- src/OPT/pair_aip_water_2dm_opt.cpp | 2 +- src/OPT/pair_ilp_graphene_hbn_opt.cpp | 51 +++++++++++++++++---------- src/OPT/pair_ilp_graphene_hbn_opt.h | 2 +- src/OPT/pair_ilp_tmd_opt.cpp | 2 +- 4 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/OPT/pair_aip_water_2dm_opt.cpp b/src/OPT/pair_aip_water_2dm_opt.cpp index 17e981e479..3aba5b9dbd 100644 --- a/src/OPT/pair_aip_water_2dm_opt.cpp +++ b/src/OPT/pair_aip_water_2dm_opt.cpp @@ -23,7 +23,7 @@ e-mail: qdgaoping at gmail dot com Optimizations are described in: - Gao, Ping and Duan, Xiaohui, et al: + Gao, Ping and Duan, Xiaohui, et al.: LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors DOI: 10.1145/3458817.3476137 diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.cpp b/src/OPT/pair_ilp_graphene_hbn_opt.cpp index b2abcec7be..5bf21e5c24 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.cpp +++ b/src/OPT/pair_ilp_graphene_hbn_opt.cpp @@ -11,12 +11,24 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - Optimization author1: Ping Gao (National Supercomputing Center in Wuxi, China) - e-mail: qdgaoping at gmail dot com - Optimization author2: Xiaohui Duan (National Supercomputing Center in Wuxi, China) - e-mail: sunrise_duan at 126 dot com + This is an optimized version of ilp/graphene/hbn based on the contribution of: + author: Wengen Ouyang (Wuhan University) + e-mail: w.g.ouyang at gmail dot com - Provides some bugfixes and performance optimizations in this potential. + Optimizations are done by: + author1: Ping Gao (National Supercomputing Center in Wuxi, China) + e-mail: qdgaoping at gmail dot com + + author2: Xiaohui Duan (National Supercomputing Center in Wuxi, China) + e-mail: sunrise_duan at 126 dot com + + Optimizations are described in: + Gao, Ping and Duan, Xiaohui, et al.: + LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors + DOI: 10.1145/3458817.3476137 + + Potential is described by: + [Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020)] */ #include "pair_ilp_graphene_hbn_opt.h" @@ -169,33 +181,33 @@ void PairILPGrapheneHBNOpt::compute(int eflag, int vflag) } } } - } else if (variant == AIP_WATER_2DM) { + } else if (variant == ILP_WATER_2DM) { if (eflag_global || eflag_atom) { if (vflag_either) { if (tap_flag) { - eval<6, 1, 1, 1, AIP_WATER_2DM>(); + eval<6, 1, 1, 1, ILP_WATER_2DM>(); } else { - eval<6, 1, 1, 0, AIP_WATER_2DM>(); + eval<6, 1, 1, 0, ILP_WATER_2DM>(); } } else { if (tap_flag) { - eval<6, 1, 0, 1, AIP_WATER_2DM>(); + eval<6, 1, 0, 1, ILP_WATER_2DM>(); } else { - eval<6, 1, 0, 0, AIP_WATER_2DM>(); + eval<6, 1, 0, 0, ILP_WATER_2DM>(); } } } else { if (vflag_either) { if (tap_flag) { - eval<6, 0, 1, 1, AIP_WATER_2DM>(); + eval<6, 0, 1, 1, ILP_WATER_2DM>(); } else { - eval<6, 0, 1, 0, AIP_WATER_2DM>(); + eval<6, 0, 1, 0, ILP_WATER_2DM>(); } } else { if (tap_flag) { - eval<6, 0, 0, 1, AIP_WATER_2DM>(); + eval<6, 0, 0, 1, ILP_WATER_2DM>(); } else { - eval<6, 0, 0, 0, AIP_WATER_2DM>(); + eval<6, 0, 0, 0, ILP_WATER_2DM>(); } } } @@ -286,7 +298,7 @@ void PairILPGrapheneHBNOpt::eval() rsq = delx * delx + dely * dely + delz * delz; if (rsq != 0 && rsq < cutILPsq[itype_map][jtype]) { - if ((VARIANT == ILP_TMD || VARIANT == AIP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue; + if ((VARIANT == ILP_TMD || VARIANT == ILP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue; if (ILP_nneigh >= MAX_NNEIGH) { error->one(FLERR, "There are too many neighbors for calculating normals"); } @@ -301,7 +313,7 @@ void PairILPGrapheneHBNOpt::eval() double norm[3], dnormdxi[3][3], dnormdxk[MAX_NNEIGH][3][3]; - calc_normal(i, itype, ILP_neigh, ILP_nneigh, norm, dnormdxi, dnormdxk); + calc_atom_normal(i, itype, ILP_neigh, ILP_nneigh, norm, dnormdxi, dnormdxk); for (jj = 0; jj < jnum_inter; jj++) { j = jlist_inter[jj]; @@ -471,6 +483,7 @@ inline void deriv_hat(double dnhatdn[3][3], double *n, double rnnorm, double fac dnhatdn[0][2] = -n[0]*n[2]*cfactor; dnhatdn[1][2] = -n[1]*n[2]*cfactor; dnhatdn[2][2] = (n[0]*n[0]+n[1]*n[1])*cfactor; + } inline double normalize_factor(double *n) { @@ -485,7 +498,7 @@ inline double normalize_factor(double *n) Yet another normal calculation method for simpiler code. */ template -void PairILPGrapheneHBNOpt::calc_normal(int i, int itype, int *ILP_neigh, int nneigh, double *n, +void PairILPGrapheneHBNOpt::calc_atom_normal(int i, int itype, int *ILP_neigh, int nneigh, double *n, double (*dnormdri)[3], double (*dnormdrk)[3][3]) { double **x = atom->x; @@ -519,8 +532,8 @@ void PairILPGrapheneHBNOpt::calc_normal(int i, int itype, int *ILP_neigh, int nn vet[jj][2] = x[j][2] - x[i][2]; } - //specialize for AIP_WATER_2DM for hydrogen has special normal vector rule - if (variant == AIP_WATER_2DM && special_type[itype] == WATER) { + //specialize for ILP_WATER_2DM for hydrogen has special normal vector rule + if (variant == ILP_WATER_2DM && special_type[itype] == WATER) { if (nneigh == 1){ n[0] = vet[0][0]; n[1] = vet[0][1]; diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.h b/src/OPT/pair_ilp_graphene_hbn_opt.h index 41d2178092..01b66bb2fa 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.h +++ b/src/OPT/pair_ilp_graphene_hbn_opt.h @@ -35,7 +35,7 @@ class PairILPGrapheneHBNOpt : virtual public PairILPGrapheneHBN { protected: void update_internal_list(); template - void calc_normal(int i, int itype, int *ILP_neigh, int nneigh, double *normal, double (*dnormdri)[3], + void calc_atom_normal(int i, int itype, int *ILP_neigh, int nneigh, double *normal, double (*dnormdri)[3], double (*dnormdrk)[3][3]); template void eval(); diff --git a/src/OPT/pair_ilp_tmd_opt.cpp b/src/OPT/pair_ilp_tmd_opt.cpp index 834f2a0c9f..3fa95b7e10 100644 --- a/src/OPT/pair_ilp_tmd_opt.cpp +++ b/src/OPT/pair_ilp_tmd_opt.cpp @@ -23,7 +23,7 @@ e-mail: qdgaoping at gmail dot com Optimizations are described in: - Gao, Ping and Duan, Xiaohui, et al: + Gao, Ping and Duan, Xiaohui, et al.: LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors DOI: 10.1145/3458817.3476137 From f85474c9ecc64532c5197b96ba0d38c80547a729 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Tue, 6 Jun 2023 22:03:33 +0800 Subject: [PATCH 334/448] fix a typo --- src/OPT/pair_aip_water_2dm_opt.h | 1 - src/OPT/pair_ilp_graphene_hbn_opt.cpp | 48 +++++++++++++-------------- 2 files changed, 23 insertions(+), 26 deletions(-) diff --git a/src/OPT/pair_aip_water_2dm_opt.h b/src/OPT/pair_aip_water_2dm_opt.h index 46280c2b82..50b5043360 100644 --- a/src/OPT/pair_aip_water_2dm_opt.h +++ b/src/OPT/pair_aip_water_2dm_opt.h @@ -36,4 +36,3 @@ class PairAIPWATER2DMOpt : public PairAIPWATER2DM, public PairILPGrapheneHBNOpt } // namespace LAMMPS_NS #endif #endif - diff --git a/src/OPT/pair_ilp_graphene_hbn_opt.cpp b/src/OPT/pair_ilp_graphene_hbn_opt.cpp index 5bf21e5c24..5cb896223e 100644 --- a/src/OPT/pair_ilp_graphene_hbn_opt.cpp +++ b/src/OPT/pair_ilp_graphene_hbn_opt.cpp @@ -11,31 +11,30 @@ ------------------------------------------------------------------------- */ /* ---------------------------------------------------------------------- - This is an optimized version of ilp/graphene/hbn based on the contribution of: - author: Wengen Ouyang (Wuhan University) - e-mail: w.g.ouyang at gmail dot com + This is an optimized version of ilp/graphene/hbn based on the contirubtion of: + author: Wengen Ouyang (Wuhan University, China) + e-mail: w.g.ouyang at gmail dot com Optimizations are done by: - author1: Ping Gao (National Supercomputing Center in Wuxi, China) - e-mail: qdgaoping at gmail dot com + author1: Ping Gao (National Supercomputing Center in Wuxi, China) implements the base ILP potential. + e-mail: qdgaoping at gmail dot com - author2: Xiaohui Duan (National Supercomputing Center in Wuxi, China) - e-mail: sunrise_duan at 126 dot com + author2: Xiaohui Duan (Shandong University, China) adjusts the framework to adopt SAIP, TMD, WATER2DM, etc. + e-mail: sunrise_duan at 126 dot com Optimizations are described in: - Gao, Ping and Duan, Xiaohui, et al.: - LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors - DOI: 10.1145/3458817.3476137 + Gao, Ping and Duan, Xiaohui, et al: + LMFF: Efficient and Scalable Layered Materials Force Field on Heterogeneous Many-Core Processors + DOI: 10.1145/3458817.3476137 Potential is described by: - [Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020)] + [Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020)] */ #include "pair_ilp_graphene_hbn_opt.h" #include "atom.h" #include "citeme.h" -#include "comm.h" #include "error.h" #include "force.h" #include "interlayer_taper.h" @@ -181,33 +180,33 @@ void PairILPGrapheneHBNOpt::compute(int eflag, int vflag) } } } - } else if (variant == ILP_WATER_2DM) { + } else if (variant == AIP_WATER_2DM) { if (eflag_global || eflag_atom) { if (vflag_either) { if (tap_flag) { - eval<6, 1, 1, 1, ILP_WATER_2DM>(); + eval<6, 1, 1, 1, AIP_WATER_2DM>(); } else { - eval<6, 1, 1, 0, ILP_WATER_2DM>(); + eval<6, 1, 1, 0, AIP_WATER_2DM>(); } } else { if (tap_flag) { - eval<6, 1, 0, 1, ILP_WATER_2DM>(); + eval<6, 1, 0, 1, AIP_WATER_2DM>(); } else { - eval<6, 1, 0, 0, ILP_WATER_2DM>(); + eval<6, 1, 0, 0, AIP_WATER_2DM>(); } } } else { if (vflag_either) { if (tap_flag) { - eval<6, 0, 1, 1, ILP_WATER_2DM>(); + eval<6, 0, 1, 1, AIP_WATER_2DM>(); } else { - eval<6, 0, 1, 0, ILP_WATER_2DM>(); + eval<6, 0, 1, 0, AIP_WATER_2DM>(); } } else { if (tap_flag) { - eval<6, 0, 0, 1, ILP_WATER_2DM>(); + eval<6, 0, 0, 1, AIP_WATER_2DM>(); } else { - eval<6, 0, 0, 0, ILP_WATER_2DM>(); + eval<6, 0, 0, 0, AIP_WATER_2DM>(); } } } @@ -298,7 +297,7 @@ void PairILPGrapheneHBNOpt::eval() rsq = delx * delx + dely * dely + delz * delz; if (rsq != 0 && rsq < cutILPsq[itype_map][jtype]) { - if ((VARIANT == ILP_TMD || VARIANT == ILP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue; + if ((VARIANT == ILP_TMD || VARIANT == AIP_WATER_2DM) && special_type[itype] == TMD_METAL && itype != type[j]) continue; if (ILP_nneigh >= MAX_NNEIGH) { error->one(FLERR, "There are too many neighbors for calculating normals"); } @@ -483,7 +482,6 @@ inline void deriv_hat(double dnhatdn[3][3], double *n, double rnnorm, double fac dnhatdn[0][2] = -n[0]*n[2]*cfactor; dnhatdn[1][2] = -n[1]*n[2]*cfactor; dnhatdn[2][2] = (n[0]*n[0]+n[1]*n[1])*cfactor; - } inline double normalize_factor(double *n) { @@ -532,8 +530,8 @@ void PairILPGrapheneHBNOpt::calc_atom_normal(int i, int itype, int *ILP_neigh, i vet[jj][2] = x[j][2] - x[i][2]; } - //specialize for ILP_WATER_2DM for hydrogen has special normal vector rule - if (variant == ILP_WATER_2DM && special_type[itype] == WATER) { + //specialize for AIP_WATER_2DM for hydrogen has special normal vector rule + if (variant == AIP_WATER_2DM && special_type[itype] == WATER) { if (nneigh == 1){ n[0] = vet[0][0]; n[1] = vet[0][1]; From 51b45d683071f1985d59a9a25b1ebc8f29739017 Mon Sep 17 00:00:00 2001 From: oywg11 Date: Tue, 6 Jun 2023 22:16:41 +0800 Subject: [PATCH 335/448] fix small format issues --- src/INTERLAYER/pair_ilp_graphene_hbn.cpp | 2 -- src/INTERLAYER/pair_ilp_tmd.cpp | 2 +- src/INTERLAYER/pair_saip_metal.cpp | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp index eb37b39864..69896d7c0b 100644 --- a/src/INTERLAYER/pair_ilp_graphene_hbn.cpp +++ b/src/INTERLAYER/pair_ilp_graphene_hbn.cpp @@ -16,8 +16,6 @@ This is a full version of the potential described in [Ouyang et al., J. Chem. Theory Comput. 16(1), 666-676 (2020)] - The definition of normals are the same as that in - [Kolmogorov & Crespi, Phys. Rev. B 71, 235415 (2005)] ------------------------------------------------------------------------- */ #include "pair_ilp_graphene_hbn.h" diff --git a/src/INTERLAYER/pair_ilp_tmd.cpp b/src/INTERLAYER/pair_ilp_tmd.cpp index f0d618687a..f29ee34180 100644 --- a/src/INTERLAYER/pair_ilp_tmd.cpp +++ b/src/INTERLAYER/pair_ilp_tmd.cpp @@ -15,7 +15,7 @@ e-mail: w.g.ouyang at gmail dot com This is a full version of the potential described in - [Ouyang et al, J. Chem. Theory Comput. 17, 7237 (2021).] + [Ouyang et al., J. Chem. Theory Comput. 17, 7237 (2021).] ------------------------------------------------------------------------- */ #include "pair_ilp_tmd.h" diff --git a/src/INTERLAYER/pair_saip_metal.cpp b/src/INTERLAYER/pair_saip_metal.cpp index 05fbfbf7f4..bd327391a4 100644 --- a/src/INTERLAYER/pair_saip_metal.cpp +++ b/src/INTERLAYER/pair_saip_metal.cpp @@ -15,7 +15,7 @@ e-mail: w.g.ouyang at gmail dot com This is a full version of the potential described in - [Ouyang et al, J. Chem. Theory Comput. 17, 7215-7223 (2021)] + [Ouyang et al., J. Chem. Theory Comput. 17, 7215-7223 (2021)] ------------------------------------------------------------------------- */ #include "pair_saip_metal.h" From c4d49324b52f708d9e0d8fc6ef123cee84f68845 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 6 Jun 2023 16:08:50 -0400 Subject: [PATCH 336/448] various documentation updates - spelling fixes - formatting conventions - grammar fixes and clarifications - full integration into manual build procedure --- doc/src/Commands_pair.rst | 1 + doc/src/pair_aip_water_2dm.rst | 64 +++++++++++---------- doc/src/pair_style.rst | 1 + doc/utils/sphinx-config/false_positives.txt | 3 + 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 5f79015aaf..87d3129880 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -37,6 +37,7 @@ OPT. * * :doc:`adp (ko) ` * :doc:`agni (o) ` + * :doc:`aip/water/2dm (o) ` * :doc:`airebo (io) ` * :doc:`airebo/morse (io) ` * :doc:`amoeba (g) ` diff --git a/doc/src/pair_aip_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst index 3ae63e1e45..5218db9c37 100644 --- a/doc/src/pair_aip_water_2dm.rst +++ b/doc/src/pair_aip_water_2dm.rst @@ -35,8 +35,8 @@ Description .. versionadded:: xxxx2023 -The *aip/water/2dm* style computes the anisotropic interfacial -potential (AIP) potential for interfaces of water with two-dimensinal (2D) +The *aip/water/2dm* style computes the anisotropic interfacial potential +(AIP) potential for interfaces of water with two-dimensional (2D) materials as described in :ref:`(Feng) `. .. math:: @@ -56,41 +56,45 @@ materials as described in :ref:`(Feng) `. Where :math:`\mathrm{Tap}(r_{ij})` is the taper function which provides a continuous cutoff (up to third derivative) for interatomic separations -larger than :math:`r_c` :doc:`pair_style ilp_graphene_hbn `. +larger than :math:`r_c` :doc:`pair_style ilp_graphene_hbn +`. It is important to include all the pairs to build the neighbor list for calculating the normals. .. note:: - Since each water molecule contains one oxygen atom and two hydrogen atoms, - a new definition is proposed (see In :ref:`(Feng) `),the atomic - normal vectors of hydrogen atoms are assumed to lie along the corresponding - oxygen-hydrogen bonds and the normal vector of the central oxygen atom - is defined as their average. + Since each water molecule contains one oxygen atom and two hydrogen + atoms, a new definition is proposed (see In :ref:`(Feng) `),the + atomic normal vectors of hydrogen atoms are assumed to lie along the + corresponding oxygen-hydrogen bonds and the normal vector of the + central oxygen atom is defined as their average. -The parameter file (e.g. COH.aip.water.2dm), is intended for use with *metal* -:doc:`units `, with energies in meV. Two additional parameters, -*S*, and *rcut* are included in the parameter file. *S* is designed to -facilitate scaling of energies. *rcut* is designed to build the neighbor -list for calculating the normals for each atom pair. +The provided parameter file, ``COH.aip.water.2dm``, is intended for use +with *metal* :doc:`units `, with energies in meV. Two additional +parameters, *S*, and *rcut* are included in the parameter file. *S* is +designed to facilitate scaling of energies; *rcut* is designed to build +the neighbor list for calculating the normals for each atom pair. .. note:: - The parameters presented in the parameter file (e.g. COH.aip.water.2dm), - are fitted with taper function by setting the cutoff equal to 16.0 - Angstrom. Using different cutoff or taper function should be careful. - These parameters provide a good description in both short- and long-range - interaction regimes. This feature is essential for simulations in high pressure - regime (i.e., the interlayer distance is smaller than the equilibrium - distance). + The parameters presented in the provided parameter file, + ``COH.aip.water.2dm``, are fitted with the taper function enabled by + setting the cutoff equal to 16.0 Angstrom. Using a different cutoff + or taper function setting should be carefully checked as they can + lead to significant errors. These parameters provide a good + description in both short- and long-range interaction regimes. This + feature is essential for simulations in high pressure regime (i.e., + the interlayer distance is smaller than the equilibrium distance). -This potential must be used in combination with hybrid/overlay. -Other interactions can be set to zero using pair_style *none*\ . +This potential must be used in combination with hybrid/overlay. Other +interactions can be set to zero using :doc:`pair_coeff settings +` with the pair style set to *none*\ . This pair style tallies a breakdown of the total interlayer potential -energy into sub-categories, which can be accessed via the :doc:`compute pair ` command as a vector of values of length 2. -The 2 values correspond to the following sub-categories: +energy into sub-categories, which can be accessed via the :doc:`compute +pair ` command as a vector of values of length 2. The 2 +values correspond to the following sub-categories: 1. *E_vdW* = vdW (attractive) energy 2. *E_Rep* = Repulsive energy @@ -132,11 +136,11 @@ if LAMMPS was built with that package. See the :doc:`Build package This pair style requires the newton setting to be *on* for pair interactions. -The COH.aip.water.2dm potential file provided with LAMMPS (see the potentials -directory) are parameterized for *metal* units. You can use this -potential with any LAMMPS units, but you would need to create your -COH.aip.water.2dm potential file with coefficients listed in the appropriate -units, if your simulation does not use *metal* units. +The ``COH.aip.water.2dm`` potential file provided with LAMMPS is +parameterized for *metal* units. You can use this pair style with any +LAMMPS units, but you would need to create your own potential file with +parameters in the appropriate units, if your simulation does not use +*metal* units. Related commands """""""""""""""" @@ -158,8 +162,8 @@ Default tap_flag = 1 - ---------- .. _Feng: + **(Feng)** Z. Feng and W. Ouyang et al., J. Phys. Chem. C. 127, 8704-8713 (2023). diff --git a/doc/src/pair_style.rst b/doc/src/pair_style.rst index 441313b0b8..494a26aacf 100644 --- a/doc/src/pair_style.rst +++ b/doc/src/pair_style.rst @@ -114,6 +114,7 @@ accelerated styles exist. * :doc:`adp ` - angular dependent potential (ADP) of Mishin * :doc:`agni ` - AGNI machine-learning potential +* :doc:`aip/water/2dm ` - anisotropic interfacial potential for water in 2d geometries * :doc:`airebo ` - AIREBO potential of Stuart * :doc:`airebo/morse ` - AIREBO with Morse instead of LJ * :doc:`amoeba ` - diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index d2d15633af..ad2a255447 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -55,6 +55,7 @@ Ai Aidan aij aimd +aip airebo Aj ajaramil @@ -528,6 +529,7 @@ collisional Columic colvars Colvars +COH COLVARS comID Commun @@ -1090,6 +1092,7 @@ Fellinger femtosecond femtoseconds fene +Feng Fennell fep FEP From eafabf0fb1d0818b675953a7e5a56f044044491b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 6 Jun 2023 16:10:11 -0400 Subject: [PATCH 337/448] update .gitignore --- src/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/.gitignore b/src/.gitignore index 204eec5e0b..2db7bb4663 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -1058,6 +1058,10 @@ /pair_adp.h /pair_agni.cpp /pair_agni.h +/pair_aip_water_2dm.cpp +/pair_aip_water_2dm.h +/pair_aip_water_2dm_opt.cpp +/pair_aip_water_2dm_opt.h /pair_airebo.cpp /pair_airebo.h /pair_airebo_morse.cpp From e954d8f0507bc31869f083777e412e5b1ed1aaed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 6 Jun 2023 16:11:03 -0400 Subject: [PATCH 338/448] correctly indicate OPT package version of pair style --- doc/src/Commands_pair.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 87d3129880..c45a1d778c 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -37,7 +37,7 @@ OPT. * * :doc:`adp (ko) ` * :doc:`agni (o) ` - * :doc:`aip/water/2dm (o) ` + * :doc:`aip/water/2dm (t) ` * :doc:`airebo (io) ` * :doc:`airebo/morse (io) ` * :doc:`amoeba (g) ` From ee6b12ee300c8adb1c8cd62ba6f703b4a6bb73b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yifan=20Li=E6=9D=8E=E4=B8=80=E5=B8=86?= Date: Tue, 6 Jun 2023 18:04:26 -0400 Subject: [PATCH 339/448] Correct reference info --- doc/src/fix_pimd.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/fix_pimd.rst b/doc/src/fix_pimd.rst index 22c064b60b..c08a4005f5 100644 --- a/doc/src/fix_pimd.rst +++ b/doc/src/fix_pimd.rst @@ -445,7 +445,7 @@ Path Integrals, McGraw-Hill, New York (1965). **(Bussi)** G. Bussi, T. Zykova-Timan, M. Parrinello, J Chem Phys, 130, 074101 (2009). -.. _Ceriotti2: +.. _Ceriotti3: **(Ceriotti)** M. Ceriotti, M. Parrinello, T. Markland, D. Manolopoulos, J. Chem. Phys. 133, 124104 (2010). From a415d732fc354ba7af12c438ad869f5f9f5484c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yifan=20Li=E6=9D=8E=E4=B8=80=E5=B8=86?= Date: Tue, 6 Jun 2023 18:11:01 -0400 Subject: [PATCH 340/448] rename Langevin init --- src/REPLICA/fix_pimd_langevin.cpp | 4 ++-- src/REPLICA/fix_pimd_langevin.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 2e4b1c17b8..17ea07c845 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -451,7 +451,7 @@ void FixPIMDLangevin::init() nmpimd_init(); - Langevin_init(); + langevin_init(); c_pe = modify->get_compute_by_id(id_pe); c_press = modify->get_compute_by_id(id_press); @@ -888,7 +888,7 @@ void FixPIMDLangevin::press_o_step() /* ---------------------------------------------------------------------- */ -void FixPIMDLangevin::Langevin_init() +void FixPIMDLangevin::langevin_init() { double beta = 1.0 / kBT; _omega_np = np / beta / hbar; diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 79a2ee7477..1ef1dfae52 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -115,7 +115,7 @@ class FixPIMDLangevin : public Fix { class RanMars *random; int tstat_flag; // tstat_flat = 1 if thermostat if used - void Langevin_init(); + void langevin_init(); void b_step(); // integrate for dt/2 according to B part (v <- v + f * dt/2) void a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) void qc_step(); // integrate for dt/2 for the centroid mode (x <- x + v * dt/2) From 5ff6fd9aad41084521a1a48381c6ebba6f584426 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yifan=20Li=E6=9D=8E=E4=B8=80=E5=B8=86?= Date: Tue, 6 Jun 2023 18:14:28 -0400 Subject: [PATCH 341/448] rename kBT to kt --- src/REPLICA/fix_pimd_langevin.cpp | 16 ++++++++-------- src/REPLICA/fix_pimd_langevin.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 17ea07c845..c85edc99f9 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -257,7 +257,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : } } extvector = 1; - kBT = force->boltz * temp; + kt = force->boltz * temp; if (pstat_flag) baro_init(); // some initilizations @@ -800,10 +800,10 @@ void FixPIMDLangevin::baro_init() { vw[0] = vw[1] = vw[2] = vw[3] = vw[4] = vw[5] = 0.0; if (pstyle == ISO) { - W = 3 * (atom->natoms) * tau_p * tau_p * np * kBT; + W = 3 * (atom->natoms) * tau_p * tau_p * np * kt; } // consistent with the definition in i-Pi else if (pstyle == ANISO) { - W = atom->natoms * tau_p * tau_p * np * kBT; + W = atom->natoms * tau_p * tau_p * np * kt; } Vcoeff = 1.0; std::string out = fmt::format("\nInitializing PIMD {:s} barostat...\n", Barostats[barostat]); @@ -890,7 +890,7 @@ void FixPIMDLangevin::press_o_step() void FixPIMDLangevin::langevin_init() { - double beta = 1.0 / kBT; + double beta = 1.0 / kt; _omega_np = np / beta / hbar; double _omega_np_dt_half = _omega_np * update->dt * 0.5; @@ -1394,11 +1394,11 @@ void FixPIMDLangevin::compute_totenthalpy() if (barostat == BZP) { if (pstyle == ISO) { totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + p_hydro * volume / force->nktv2p - - Vcoeff * kBT * log(volume); + Vcoeff * kt * log(volume); } else if (pstyle == ANISO) { totenthalpy = tote + 0.5 * W * vw[0] * vw[0] * inverse_np + 0.5 * W * vw[1] * vw[1] * inverse_np + 0.5 * W * vw[2] * vw[2] * inverse_np + - p_hydro * volume / force->nktv2p - Vcoeff * kBT * log(volume); + p_hydro * volume / force->nktv2p - Vcoeff * kt * log(volume); } } else if (barostat == MTTK) totenthalpy = tote + 1.5 * W * vw[0] * vw[0] * inverse_np + p_hydro * (volume - vol0); @@ -1477,7 +1477,7 @@ double FixPIMDLangevin::compute_vector(int n) if (n == 11) return 1.5 * W * vw[0] * vw[0]; } if (n == 12) { return np * Pext * volume / force->nktv2p; } - if (n == 13) { return -Vcoeff * np * kBT * log(volume); } + if (n == 13) { return -Vcoeff * np * kt * log(volume); } if (n == 14) return totenthalpy; } else if (pstyle == ANISO) { if (n == 10) return vw[0]; @@ -1487,7 +1487,7 @@ double FixPIMDLangevin::compute_vector(int n) if (n == 14) { return np * Pext * volume / force->nktv2p; } if (n == 15) { volume = domain->xprd * domain->yprd * domain->zprd; - return -Vcoeff * np * kBT * log(volume); + return -Vcoeff * np * kt * log(volume); } if (n == 16) return totenthalpy; } diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index 1ef1dfae52..dc48832855 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -51,7 +51,7 @@ class FixPIMDLangevin : public Fix { double lj_epsilon, lj_sigma, lj_mass; // LJ unit energy, length, and mass scales double other_planck; double other_mvv2e; - double kBT; // k_B * temp + double kt; // k_B * temp double beta, beta_np; // beta = 1./kBT beta_np = 1./kBT/np int thermostat; // NHC or PILE_L int barostat; // BZP From f83867787c6eb7ed8b509a54be25b3ee46e7290d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yifan=20Li=E6=9D=8E=E4=B8=80=E5=B8=86?= Date: Tue, 6 Jun 2023 18:17:39 -0400 Subject: [PATCH 342/448] update error message --- src/REPLICA/fix_pimd_langevin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index c85edc99f9..0af08b43b3 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -155,7 +155,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : pstat_flag = 1; } else error->universe_all(FLERR, - "Unknown ensemble parameter for fix pimd/langevin. Only nve and nvt " + "Unknown ensemble parameter for fix pimd/langevin. Only nve, nvt, nph, and npt " "ensembles are supported!"); } else if (strcmp(arg[i], "fmass") == 0) { fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); From 14acb3e0ca5aa77662fbe4d96fc6463909e52be5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 6 Jun 2023 20:38:15 -0400 Subject: [PATCH 343/448] add multitype data type and unittest (including tests for ubuf) --- src/lmptype.h | 82 +++++++++++++++++++++++++++++++- unittest/utils/CMakeLists.txt | 4 ++ unittest/utils/test_lmptype.cpp | 84 +++++++++++++++++++++++++++++++++ 3 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 unittest/utils/test_lmptype.cpp diff --git a/src/lmptype.h b/src/lmptype.h index ecd6ee5761..6e0b54d988 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -95,7 +95,7 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT_MAX #define MAXBIGINT INT64_MAX -#define MAXDOUBLEINT 9007199254740992 // 2^53 +#define MAXDOUBLEINT 9007199254740992 // 2^53 #define MPI_LMP_TAGINT MPI_INT #define MPI_LMP_IMAGEINT MPI_INT @@ -133,7 +133,7 @@ typedef int64_t bigint; #define MAXSMALLINT INT_MAX #define MAXTAGINT INT64_MAX #define MAXBIGINT INT64_MAX -#define MAXDOUBLEINT 9007199254740992 // 2^53 +#define MAXDOUBLEINT 9007199254740992 // 2^53 #define MPI_LMP_TAGINT MPI_LL #define MPI_LMP_IMAGEINT MPI_LL @@ -232,6 +232,84 @@ union ubuf { ubuf(const int64_t &arg) : i(arg) {} ubuf(const int &arg) : i(arg) {} }; + +/** Data structure for dynamic typing of int, bigint, and double + * + * Using this union allows to store any of the supported data types + * in the same container and allows to "see" its current type. +\verbatim embed:rst + +**Usage:** + +.. code-block:: c++ + :caption: To store data in multitype array: + + multitype m[5]; + int foo = 1; + double bar = 2.5; + bigint baz = 1<<40 - 1; + m[0] = foo; + m[1] = bar; + m[2] = -1; + m[3] = 2.0; + m[4] = baz; + +.. code-block:: c++ + :caption: To format data from multitype array into a space separated string: + + std::string str; + for (int i = 0; i < 5; ++i) { + switch (m[i].type) { + case multitype::DOUBLE: + str += std::to_string(m[i].data.d) + ' '; + break; + case multitype::INT: + str += std::to_string(m[i].data.i) + ' '; + break; + case multitype::BIGINT: + str += std::to_string(m[i].data.b) + ' '; + break; + default: + break; + } + } +\endverbatim + */ +struct multitype { + enum { NONE, DOUBLE, INT, BIGINT }; + + int type; + union { + double d; + int i; + int64_t b; + } data; + + multitype() : type(NONE) { data.d = 0.0; } + multitype(const multitype &) = default; + multitype(multitype &&) = default; + ~multitype() = default; + + multitype &operator=(const double &_d) + { + type = DOUBLE; + data.d = _d; + return *this; + } + multitype &operator=(const int &_i) + { + type = INT; + data.i = _i; + return *this; + } + multitype &operator=(const int64_t &_b) + { + type = BIGINT; + data.b = _b; + return *this; + } +}; + } // namespace LAMMPS_NS // preprocessor macros for compiler specific settings diff --git a/unittest/utils/CMakeLists.txt b/unittest/utils/CMakeLists.txt index a6d5545873..8c1a5a3f6a 100644 --- a/unittest/utils/CMakeLists.txt +++ b/unittest/utils/CMakeLists.txt @@ -7,6 +7,10 @@ add_executable(test_mempool test_mempool.cpp) target_link_libraries(test_mempool PRIVATE lammps GTest::GMockMain) add_test(NAME MemPool COMMAND test_mempool) +add_executable(test_lmptype test_lmptype.cpp) +target_link_libraries(test_lmptype PRIVATE lammps GTest::GMockMain) +add_test(NAME LmpType COMMAND test_lmptype) + add_executable(test_argutils test_argutils.cpp) target_link_libraries(test_argutils PRIVATE lammps GTest::GMockMain) add_test(NAME ArgUtils COMMAND test_argutils) diff --git a/unittest/utils/test_lmptype.cpp b/unittest/utils/test_lmptype.cpp new file mode 100644 index 0000000000..6db340fddf --- /dev/null +++ b/unittest/utils/test_lmptype.cpp @@ -0,0 +1,84 @@ +/* ---------------------------------------------------------------------- + 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. +------------------------------------------------------------------------- */ + +#include "lmptype.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include + +using namespace LAMMPS_NS; + +TEST(Types, ubuf) +{ + double buf[3]; + double d1 = 0.1; + int i1 = -10; +#if defined(LAMMPS_SMALLSMALL) + bigint b1 = 2048; +#else + bigint b1 = (1L << 58) + (1L << 50); +#endif + buf[0] = d1; + buf[1] = ubuf(i1).d; + buf[2] = ubuf(b1).d; + + EXPECT_EQ(d1, buf[0]); + EXPECT_EQ(i1, (int)ubuf(buf[1]).i); + EXPECT_EQ(b1, (bigint)ubuf(buf[2]).i); +} + +TEST(Types, multitype) +{ + multitype m[6]; + int64_t b1 = (3L << 48) - 1; + int i1 = 20; + double d1 = 0.1; + + m[0] = b1; + m[1] = i1; + m[2] = d1; + +#if !defined(LAMMPS_SMALLSMALL) + m[3] = -((1L << 40) + (1L << 50)); +#endif + m[4] = -1023; + m[5] = -2.225; + +#if defined(LAMMPS_SMALLSMALL) + EXPECT_EQ(m[0].type, multitype::INT); +#else + EXPECT_EQ(m[0].type, multitype::BIGINT); +#endif + EXPECT_EQ(m[1].type, multitype::INT); + EXPECT_EQ(m[2].type, multitype::DOUBLE); + +#if defined(LAMMPS_SMALLSMALL) + EXPECT_EQ(m[3].type, multitype::NONE); +#else + EXPECT_EQ(m[3].type, multitype::BIGINT); +#endif + EXPECT_EQ(m[4].type, multitype::INT); + EXPECT_EQ(m[5].type, multitype::DOUBLE); + + EXPECT_EQ(m[0].data.b, b1); + EXPECT_EQ(m[1].data.i, i1); + EXPECT_EQ(m[2].data.d, d1); + +#if !defined(LAMMPS_SMALLSMALL) + EXPECT_EQ(m[3].data.b, -((1L << 40) + (1L << 50))); +#endif + EXPECT_EQ(m[4].data.i, -1023); + EXPECT_EQ(m[5].data.d, -2.225); +} From b81b1f5ecc587289538ee24160c6b23e45b92d8e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 6 Jun 2023 22:40:13 -0400 Subject: [PATCH 344/448] switch dump yaml/netcdf thermo output to use new caching API. remove old API. --- doc/src/dump_modify.rst | 9 +++-- src/EXTRA-DUMP/dump_yaml.cpp | 31 ++++++++++------- src/NETCDF/dump_netcdf.cpp | 58 ++++++++++++++------------------ src/NETCDF/dump_netcdf_mpiio.cpp | 54 ++++++++++++++--------------- src/thermo.cpp | 17 ++++------ src/thermo.h | 11 +++--- 6 files changed, 87 insertions(+), 93 deletions(-) diff --git a/doc/src/dump_modify.rst b/doc/src/dump_modify.rst index f00cc339cc..89b3766083 100644 --- a/doc/src/dump_modify.rst +++ b/doc/src/dump_modify.rst @@ -753,9 +753,12 @@ run, this option is ignored since the output is already balanced. ---------- The *thermo* keyword only applies the dump styles *netcdf* and *yaml*. -It triggers writing of :doc:`thermo ` information to the dump file -alongside per-atom data. The values included in the dump file are -identical to the values specified by :doc:`thermo_style `. +It triggers writing of :doc:`thermo ` information to the dump +file alongside per-atom data. The values included in the dump file are +cached values from the last thermo output and include the exact same the +values as specified by the :doc:`thermo_style ` command. +Because these are cached values, they are only up-to-date when dump +output is on a timestep that also has thermo output. ---------- diff --git a/src/EXTRA-DUMP/dump_yaml.cpp b/src/EXTRA-DUMP/dump_yaml.cpp index 3c35ec43ba..029415164f 100644 --- a/src/EXTRA-DUMP/dump_yaml.cpp +++ b/src/EXTRA-DUMP/dump_yaml.cpp @@ -60,21 +60,26 @@ void DumpYAML::write_header(bigint ndump) std::string thermo_data; if (thermo) { Thermo *th = output->thermo; - thermo_data += "thermo:\n - keywords: [ "; - for (int i = 0; i < th->nfield; ++i) thermo_data += fmt::format("{}, ", th->keyword[i]); - thermo_data += "]\n - data: [ "; + // output thermo data only on timesteps where it was computed + if (update->ntimestep == th->get_timestep()) { - for (int i = 0; i < th->nfield; ++i) { - th->call_vfunc(i); - if (th->vtype[i] == Thermo::FLOAT) - thermo_data += fmt::format("{}, ", th->dvalue); - else if (th->vtype[i] == Thermo::INT) - thermo_data += fmt::format("{}, ", th->ivalue); - else if (th->vtype[i] == Thermo::BIGINT) - thermo_data += fmt::format("{}, ", th->bivalue); + thermo_data += "thermo:\n - keywords: [ "; + for (auto key : th->get_keywords()) thermo_data += fmt::format("{}, ", key); + thermo_data += "]\n - data: [ "; + + for (auto val : th->get_fields()) { + if (val.type == multitype::DOUBLE) + thermo_data += fmt::format("{}, ", val.data.d); + else if (val.type == multitype::INT) + thermo_data += fmt::format("{}, ", val.data.i); + else if (val.type == multitype::BIGINT) + thermo_data += fmt::format("{}, ", val.data.b); + else + thermo_data += ", "; + } + thermo_data += "]\n"; + MPI_Barrier(world); } - thermo_data += "]\n"; - MPI_Barrier(world); } if (comm->me == 0) { diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 6fecf7f41b..cb6aea16cf 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -223,7 +223,7 @@ void DumpNetCDF::openfile() if (thermo && !singlefile_opened) { delete[] thermovar; - thermovar = new int[output->thermo->nfield]; + thermovar = new int[output->thermo->get_keywords().size()]; } // now the computes and fixes have been initialized, so we can query @@ -320,9 +320,10 @@ void DumpNetCDF::openfile() // perframe variables if (thermo) { - Thermo *th = output->thermo; - for (int i = 0; i < th->nfield; i++) { - NCERRX( nc_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() ); + auto keywords = output->thermo->get_keywords(); + int nfield = keywords.size(); + for (int i = 0; i < nfield; i++) { + NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); } } @@ -432,22 +433,16 @@ void DumpNetCDF::openfile() // perframe variables if (thermo) { - Thermo *th = output->thermo; - for (int i = 0; i < th->nfield; i++) { - if (th->vtype[i] == Thermo::FLOAT) { - NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), type_nc_real, 1, dims, - &thermovar[i]), th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::INT) { - NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims, - &thermovar[i]), th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::BIGINT) { -#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG) - NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims, - &thermovar[i]), th->keyword[i].c_str() ); -#else - NCERRX( nc_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims, - &thermovar[i]), th->keyword[i].c_str() ); -#endif + auto fields = output->thermo->get_fields(); + auto keywords = output->thermo->get_keywords(); + int nfield = fields.size(); + for (int i = 0; i < nfield; i++) { + if (fields[i].type == multitype::DOUBLE) { + NCERRX( nc_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() ); + } else if (fields[i].type == multitype::INT) { + NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() ); + } else if (fields[i].type == multitype::BIGINT) { + NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() ); } } } @@ -605,20 +600,17 @@ void DumpNetCDF::write() start[1] = 0; if (thermo) { - Thermo *th = output->thermo; - for (int i = 0; i < th->nfield; i++) { - th->call_vfunc(i); + auto keywords = output->thermo->get_keywords(); + auto fields = output->thermo->get_fields(); + int nfield = fields.size(); + for (int i = 0; i < nfield; i++) { if (filewriter) { - if (th->vtype[i] == Thermo::FLOAT) { - NCERRX( nc_put_var1_double(ncid, thermovar[i], start, - &th->dvalue), - th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::INT) { - NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &th->ivalue), - th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::BIGINT) { - NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue), - th->keyword[i].c_str() ); + if (fields[i].type == multitype::DOUBLE) { + NCERRX( nc_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() ); + } else if (fields[i].type == multitype::INT) { + NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() ); + } else if (fields[i].type == multitype::BIGINT) { + NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() ); } } } diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index 0282903d77..fdcd03470e 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -220,7 +220,7 @@ void DumpNetCDFMPIIO::openfile() if (thermo && !singlefile_opened) { delete[] thermovar; - thermovar = new int[output->thermo->nfield]; + thermovar = new int[output->thermo->get_keywords().size()]; } // now the computes and fixes have been initialized, so we can query @@ -318,9 +318,10 @@ void DumpNetCDFMPIIO::openfile() // perframe variables if (thermo) { - Thermo *th = output->thermo; - for (int i = 0; i < th->nfield; i++) { - NCERRX( ncmpi_inq_varid(ncid, th->keyword[i].c_str(), &thermovar[i]), th->keyword[i].c_str() ); + auto keywords = output->thermo->get_keywords(); + int nfield = keywords.size(); + for (int i = 0; i < nfield; i++) { + NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); } } @@ -422,18 +423,16 @@ void DumpNetCDFMPIIO::openfile() // perframe variables if (thermo) { - Thermo *th = output->thermo; - for (int i = 0; i < th->nfield; i++) { - if (th->vtype[i] == Thermo::FLOAT) { - NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::INT) { - NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT, 1, dims, &thermovar[i]), th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::BIGINT) { -#if defined(LAMMPS_SMALLBIG) || defined(LAMMPS_BIGBIG) - NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), th->keyword[i].c_str() ); -#else - NCERRX( ncmpi_def_var(ncid, th->keyword[i].c_str(), NC_LONG, 1, dims, &thermovar[i]), th->keyword[i].c_str() ); -#endif + auto fields = output->thermo->get_fields(); + auto keywords = output->thermo->get_keywords(); + int nfield = fields.size(); + for (int i = 0; i < nfield; i++) { + if (fields[i].type == multitype::DOUBLE) { + NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() ); + } else if (fields[i].type == multitype::INT) { + NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() ); + } else if (fields[i].type == multitype::BIGINT) { + NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() ); } } } @@ -594,20 +593,17 @@ void DumpNetCDFMPIIO::write() NCERR( ncmpi_begin_indep_data(ncid) ); if (thermo) { - Thermo *th = output->thermo; - for (int i = 0; i < th->nfield; i++) { - th->call_vfunc(i); + auto keywords = output->thermo->get_keywords(); + auto fields = output->thermo->get_fields(); + int nfield = fields.size(); + for (int i = 0; i < nfield; i++) { if (filewriter) { - if (th->vtype[i] == Thermo::FLOAT) { - NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start, - &th->dvalue), - th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::INT) { - NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &th->ivalue), - th->keyword[i].c_str() ); - } else if (th->vtype[i] == Thermo::BIGINT) { - NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &th->bivalue), - th->keyword[i].c_str() ); + if (fields[i].type == multitype::DOUBLE) { + NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() ); + } else if (fields[i].type == multitype::INT) { + NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() ); + } else if (fields[i].type == multitype::BIGINT) { + NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() ); } } } diff --git a/src/thermo.cpp b/src/thermo.cpp index 0503018a3a..31c19fbdc2 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -361,7 +361,7 @@ void Thermo::compute(int flag) int i; firststep = flag; - bigint ntimestep = update->ntimestep; + ntimestep = update->ntimestep; // check for lost atoms // turn off normflag if natoms = 0 to avoid divide by 0 @@ -405,18 +405,23 @@ void Thermo::compute(int flag) } // add each thermo value to line with its specific format + field_data.clear(); + field_data.resize(nfield); for (ifield = 0; ifield < nfield; ifield++) { (this->*vfunc[ifield])(); if (vtype[ifield] == FLOAT) { snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), dvalue); line += fmtbuf; + field_data[ifield] = dvalue; } else if (vtype[ifield] == INT) { snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), ivalue); line += fmtbuf; + field_data[ifield] = ivalue; } else if (vtype[ifield] == BIGINT) { snprintf(fmtbuf, sizeof(fmtbuf), format[ifield].c_str(), bivalue); line += fmtbuf; + field_data[ifield] = bivalue; } } @@ -433,16 +438,6 @@ void Thermo::compute(int flag) firststep = 1; } -/* ---------------------------------------------------------------------- - call function to compute property -------------------------------------------------------------------------- */ - -void Thermo::call_vfunc(int ifield_in) -{ - ifield = ifield_in; - (this->*vfunc[ifield])(); -} - /* ---------------------------------------------------------------------- check for lost atoms, return current number of atoms also could number of warnings across MPI ranks and update total diff --git a/src/thermo.h b/src/thermo.h index eaec3eb9f8..8a5cba29d7 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -21,9 +21,6 @@ namespace LAMMPS_NS { class Thermo : protected Pointers { friend class MinCG; // accesses compute_pe - friend class DumpNetCDF; // accesses thermo properties - friend class DumpNetCDFMPIIO; // accesses thermo properties - friend class DumpYAML; // accesses thermo properties public: char *style; @@ -45,6 +42,11 @@ class Thermo : protected Pointers { void compute(int); int evaluate_keyword(const std::string &, double *); + // for accessing cached thermo data + bigint get_timestep() const { return ntimestep; } + const std::vector &get_fields() const { return field_data; } + const std::vector &get_keywords() const { return keyword; } + private: int nfield, nfield_initial; int *vtype; @@ -52,6 +54,7 @@ class Thermo : protected Pointers { std::vector keyword, format, format_column_user, keyword_user; std::string format_line_user, format_float_user, format_int_user, format_bigint_user; std::map key2col; + std::vector field_data; int normvalue; // use this for normflag unless natoms = 0 int normuserflag; // 0 if user has not set, 1 if has @@ -66,6 +69,7 @@ class Thermo : protected Pointers { bigint last_step; bigint natoms; + bigint ntimestep; // data used by routines that compute single values int ivalue; // integer value to print @@ -114,7 +118,6 @@ class Thermo : protected Pointers { typedef void (Thermo::*FnPtr)(); void addfield(const char *, FnPtr, int); FnPtr *vfunc; // list of ptrs to functions - void call_vfunc(int ifield); void compute_compute(); // functions that compute a single value void compute_fix(); // via calls to Compute,Fix,Variable classes From bbfd909be64c3d6836f22d07c5049e9600a279ff Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Tue, 6 Jun 2023 23:56:16 -0700 Subject: [PATCH 345/448] Adding redundant call to sync Intel package arrays with native arrays for methods such as MC that do not need pre_reverse. --- src/INTEL/fix_intel.cpp | 22 +++++++++++++--------- src/INTEL/fix_intel.h | 2 +- src/MC/fix_gcmc.cpp | 6 ------ src/MC/fix_widom.cpp | 8 +------- 4 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/INTEL/fix_intel.cpp b/src/INTEL/fix_intel.cpp index 1ce0b41338..89775108cb 100644 --- a/src/INTEL/fix_intel.cpp +++ b/src/INTEL/fix_intel.cpp @@ -275,10 +275,8 @@ int FixIntel::setmask() int mask = 0; mask |= PRE_REVERSE; mask |= MIN_PRE_REVERSE; - #ifdef _LMP_INTEL_OFFLOAD mask |= POST_FORCE; mask |= MIN_POST_FORCE; - #endif mask |= POST_RUN; return mask; } @@ -597,6 +595,19 @@ void FixIntel::pre_reverse(int /*eflag*/, int /*vflag*/) /* ---------------------------------------------------------------------- */ +void FixIntel::post_force(int vflag) +{ + // Redundant call to sync Intel data structs with native for methods that + // call force compute but do not call prereverse + _sync_main_arrays(1); + + #ifdef LMP_INTEL_OFFLOAD + if (_sync_mode == 2) sync_coprocessor(); + #endif +} + +/* ---------------------------------------------------------------------- */ + template void FixIntel::reduce_results(acc_t * _noalias const f_scalar) { @@ -883,13 +894,6 @@ double FixIntel::memory_usage() /* ---------------------------------------------------------------------- */ -void FixIntel::post_force(int vflag) -{ - if (_sync_mode == 2) sync_coprocessor(); -} - -/* ---------------------------------------------------------------------- */ - template void FixIntel::add_off_results(const ft * _noalias const f_in, const acc_t * _noalias const ev_global) { diff --git a/src/INTEL/fix_intel.h b/src/INTEL/fix_intel.h index 9214fe3419..1960a6d802 100644 --- a/src/INTEL/fix_intel.h +++ b/src/INTEL/fix_intel.h @@ -55,6 +55,7 @@ class FixIntel : public Fix { void pre_reverse(int eflag = 0, int vflag = 0) override; inline void min_pre_reverse(int eflag = 0, int vflag = 0) override { pre_reverse(eflag, vflag); } + void post_force(int vflag) override; void post_run() override { _print_pkg_info = 1; } // Get all forces, calculation results from coprocesser @@ -132,7 +133,6 @@ class FixIntel : public Fix { inline void get_buffern(const int offload, int &nlocal, int &nall, int &minlocal); #ifdef _LMP_INTEL_OFFLOAD - void post_force(int vflag); inline int coprocessor_number() { return _cop; } inline int full_host_list() { return _full_host_list; } void set_offload_affinity(); diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index 634b512936..21fb4431e1 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -2352,12 +2352,6 @@ double FixGCMC::energy_full() if (force->kspace) force->kspace->compute(eflag,vflag); - // unlike Verlet, not performing a reverse_comm() or forces here - // b/c GCMC does not care about forces - // don't think it will mess up energy due to any post_force() fixes - // but Modify::pre_reverse() is needed for INTEL - - if (modify->n_pre_reverse) modify->pre_reverse(eflag,vflag); if (modify->n_post_force_any) modify->post_force(vflag); // NOTE: all fixes with energy_global_flag set and which diff --git a/src/MC/fix_widom.cpp b/src/MC/fix_widom.cpp index a98f29da5e..cc2f1bc94d 100644 --- a/src/MC/fix_widom.cpp +++ b/src/MC/fix_widom.cpp @@ -1050,13 +1050,7 @@ double FixWidom::energy_full() if (force->kspace) force->kspace->compute(eflag,vflag); - // unlike Verlet, not performing a reverse_comm() or forces here - // b/c Widom does not care about forces - // don't think it will mess up energy due to any post_force() fixes - // but Modify::pre_reverse() is needed for INTEL - - if (modify->n_pre_reverse) modify->pre_reverse(eflag,vflag); - if (modify->n_pre_force) modify->pre_force(vflag); + if (modify->n_post_force_any) modify->post_force(vflag); // NOTE: all fixes with energy_global_flag set and which // operate at pre_force() or post_force() From 6c7a5d2f1efc77fcdf33ee30214a4faa6e0f9215 Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Tue, 6 Jun 2023 23:56:31 -0700 Subject: [PATCH 346/448] Using bigint for Intel package neighbor overflow detection for large local sizes. --- src/INTEL/npair_full_bin_ghost_intel.cpp | 7 ++++--- src/INTEL/npair_intel.cpp | 9 +++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/INTEL/npair_full_bin_ghost_intel.cpp b/src/INTEL/npair_full_bin_ghost_intel.cpp index b7b9ee4aea..381db62c08 100644 --- a/src/INTEL/npair_full_bin_ghost_intel.cpp +++ b/src/INTEL/npair_full_bin_ghost_intel.cpp @@ -292,12 +292,13 @@ void NPairFullBinGhostIntel::fbi(const int offload, NeighList * list, else ito -= wlocal - nlocal; int e_ito = ito; - const int list_size = (e_ito + tid * 2 + 2) * maxnbors; + const bigint list_size = (bigint)(e_ito + tid * 2 + 2) * + (bigint)maxnbors; int pack_offset = maxnbors; - int ct = (ifrom + tid * 2) * maxnbors; + bigint ct = (bigint)(ifrom + tid * 2) * (bigint)maxnbors; int * _noalias neighptr = intel_list + ct; - const int obound = pack_offset + maxnbors * 2; + const bigint obound = pack_offset + maxnbors * 2; const int toffs = tid * ncache_stride; flt_t * _noalias const tx = ncachex + toffs; diff --git a/src/INTEL/npair_intel.cpp b/src/INTEL/npair_intel.cpp index b85873f677..8b05aa38aa 100644 --- a/src/INTEL/npair_intel.cpp +++ b/src/INTEL/npair_intel.cpp @@ -287,16 +287,17 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, if (imod) e_ito += pack_width - imod; } #endif - const int list_size = (e_ito + tid * 2 + 2) * maxnbors; + const bigint list_size = (bigint)(e_ito + tid * 2 + 2) * + (bigint)maxnbors; #ifdef LMP_INTEL_3BODY_FAST const int pack_offset = maxnbors * pack_width; - const int obound = pack_offset + maxnbors * 2; + const bigint obound = pack_offset + maxnbors * 2; #else const int pack_offset = 0; - const int obound = maxnbors * 3; + const bigint obound = maxnbors * 3; #endif - int ct = (ifrom + tid * 2) * maxnbors; + bigint ct = (bigint)(ifrom + tid * 2) * (bigint)maxnbors; int * _noalias neighptr = intel_list + ct; int * _noalias neighptr2; if (THREE) neighptr2 = neighptr; From 0f925f7a39ea4fccd20e5bd35cf81dc56dd00296 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 04:33:08 -0400 Subject: [PATCH 347/448] reformat, add versionadded marker --- doc/src/compute_stress_mop.rst | 123 ++++++++++++++++++--------------- 1 file changed, 69 insertions(+), 54 deletions(-) diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index 7ab8c58a76..5662fc76d4 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -45,92 +45,107 @@ Examples Description """"""""""" -Compute *stress/mop* and compute *stress/mop/profile* define computations that -calculate components of the local stress tensor using the method of -planes :ref:`(Todd) `. Specifically in compute *stress/mop* calculates 3 -components are computed in directions *dir*,\ *x*\ ; *dir*,\ *y*\ ; and -*dir*,\ *z*\ ; where *dir* is the direction normal to the plane, while -in compute *stress/mop/profile* the profile of the stress is computed. +Compute *stress/mop* and compute *stress/mop/profile* define +computations that calculate components of the local stress tensor using +the method of planes :ref:`(Todd) `. Specifically in compute +*stress/mop* calculates 3 components are computed in directions *dir*,\ +*x*\ ; *dir*,\ *y*\ ; and *dir*,\ *z*\ ; where *dir* is the direction +normal to the plane, while in compute *stress/mop/profile* the profile +of the stress is computed. Contrary to methods based on histograms of atomic stress (i.e., using -:doc:`compute stress/atom `), the method of planes is -compatible with mechanical balance in heterogeneous systems and at +:doc:`compute stress/atom `), the method of planes +is compatible with mechanical balance in heterogeneous systems and at interfaces :ref:`(Todd) `. The stress tensor is the sum of a kinetic term and a configurational term, which are given respectively by Eq. (21) and Eq. (16) in -:ref:`(Todd) `. For the kinetic part, the algorithm considers that -atoms have crossed the plane if their positions at times :math:`t-\Delta t` -and :math:`t` are one on either side of the plane, and uses the velocity at -time :math:`t-\Delta t/2` given by the velocity Verlet algorithm. +:ref:`(Todd) `. For the kinetic part, the algorithm considers +that atoms have crossed the plane if their positions at times +:math:`t-\Delta t` and :math:`t` are one on either side of the plane, +and uses the velocity at time :math:`t-\Delta t/2` given by the velocity +Verlet algorithm. -Between one and six keywords can be used to indicate which -contributions to the stress must be computed: total stress (total), kinetic stress (kin), -configurational stress (conf), stress due to bond stretching (bond), -stress due to angle bending (angle) and/or due to pairwise non-bonded interactions (pair). -The angle keyword is currently available only for the stress/mop command and not the stress/mop/profile. +.. versionadded:: TBD -NOTE 1: The configurational stress is computed considering all pairs of atoms where at least one atom belongs to group group-ID. + contributions from bond and angle potentials + +Between one and six keywords can be used to indicate which contributions +to the stress must be computed: total stress (total), kinetic stress +(kin), configurational stress (conf), stress due to bond stretching +(bond), stress due to angle bending (angle) and/or due to pairwise +non-bonded interactions (pair). The angle keyword is currently +available only for the *stress/mop* command and **not** the +*stress/mop/profile* command. + +NOTE 1: The configurational stress is computed considering all pairs of +atoms where at least one atom belongs to group group-ID. NOTE 2: The local stress does not include any Lennard-Jones tail -corrections to the stress added by the :doc:`pair_modify tail yes ` -command, since those are contributions to the global system pressure. +corrections to the stress added by the :doc:`pair_modify tail yes +` command, since those are contributions to the global +system pressure. -NOTE 3: The local stress profile generated by compute *stress/mop/profile* -is similar to that obtained by compute -:doc:`stress/cartesian `. -A key difference is that compute *stress/mop/profile* considers particles -crossing a set of planes, while compute *stress/cartesian* computes averages -for a set of small volumes. More information -on the similarities and differences can be found in -:ref:`(Ikeshoji)`. +NOTE 3: The local stress profile generated by compute +*stress/mop/profile* is similar to that obtained by compute +:doc:`stress/cartesian `. A key difference is +that compute *stress/mop/profile* considers particles crossing a set of +planes, while compute *stress/cartesian* computes averages for a set of +small volumes. More information on the similarities and differences can +be found in :ref:`(Ikeshoji)`. Output info """"""""""" -Compute *stress/mop* calculates a global vector (indices starting at 1), with 3 -values for each declared keyword (in the order the keywords have been -declared). For each keyword, the stress tensor components are ordered as -follows: stress_dir,x, stress_dir,y, and stress_dir,z. +Compute *stress/mop* calculates a global vector (indices starting at 1), +with 3 values for each declared keyword (in the order the keywords have +been declared). For each keyword, the stress tensor components are +ordered as follows: stress_dir,x, stress_dir,y, and stress_dir,z. -Compute *stress/mop/profile* instead calculates a global array, with 1 column -giving the position of the planes where the stress tensor was computed, -and with 3 columns of values for each declared keyword (in the order the -keywords have been declared). For each keyword, the profiles of stress -tensor components are ordered as follows: stress_dir,x; stress_dir,y; -and stress_dir,z. +Compute *stress/mop/profile* instead calculates a global array, with 1 +column giving the position of the planes where the stress tensor was +computed, and with 3 columns of values for each declared keyword (in the +order the keywords have been declared). For each keyword, the profiles +of stress tensor components are ordered as follows: stress_dir,x; +stress_dir,y; and stress_dir,z. The values are in pressure :doc:`units `. -The values produced by this compute can be accessed by various :doc:`output commands `. -For instance, the results can be written to a file using the -:doc:`fix ave/time ` command. Please see the example -in the examples/PACKAGES/mop folder. +The values produced by this compute can be accessed by various +:doc:`output commands `. For instance, the results can be +written to a file using the :doc:`fix ave/time ` +command. Please see the example in the examples/PACKAGES/mop folder. Restrictions """""""""""" -These styles are part of the EXTRA-COMPUTE package. They are only enabled if -LAMMPS is built with that package. See the :doc:`Build package ` -doc page on for more info. +These styles are part of the EXTRA-COMPUTE package. They are only +enabled if LAMMPS is built with that package. See the :doc:`Build +package ` doc page on for more info. The method is only implemented for 3d orthogonal simulation boxes whose size does not change in time, and axis-aligned planes. The method only works with two-body pair interactions, because it -requires the class method pair->single() to be implemented. In -particular, compute *stress/mop/profile* does not work with more than -two-body pair interactions, long range (kspace) interactions and angle/dihedral/improper -intramolecular interactions. Similarly, compute *stress/mop* does not work with more than -two-body pair interactions, long range (kspace) interactions and dihedral/improper -intramolecular interactions but works with all bond interactions with the class method -single() implemented and all angle interactions with the class method born_matrix() -implemented. +requires the class method ``Pair::single()`` to be implemented, which is +not possible for manybody potentials. In particular, compute +*stress/mop/profile* does not work with more than two-body pair +interactions, long range (kspace) interactions and +angle/dihedral/improper intramolecular interactions. Similarly, compute +*stress/mop* does not work with more than two-body pair interactions, +long range (kspace) interactions and dihedral/improper intramolecular +interactions but works with all bond interactions with the class method +single() implemented and all angle interactions with the class method +born_matrix() implemented. Related commands """""""""""""""" -:doc:`compute stress/atom `, :doc:`compute pressure `, :doc:`compute stress/cartesian `, :doc:`compute stress/cylinder `, :doc:`compute stress/spherical ` +:doc:`compute stress/atom `, +:doc:`compute pressure `, +:doc:`compute stress/cartesian `, +:doc:`compute stress/cylinder `, +:doc:`compute stress/spherical ` Default """"""" From 045b230587c3fcf1eb4ea7a0fcf00f0f08b1d19c Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Wed, 7 Jun 2023 10:43:57 +0200 Subject: [PATCH 348/448] Fix shifted coordinates: Add `boxlo` to the bin centers --- src/EXTRA-COMPUTE/compute_stress_cartesian.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index 106ffef8fb..0aae797111 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -399,8 +399,8 @@ void ComputeStressCartesian::compute_array() // populate array to output. for (int bin = 0; bin < nbins1 * nbins2; bin++) { - array[bin][0] = (bin % nbins1 + 0.5) * bin_width1; - if (dims == 2) array[bin][1] = ((int) (bin / nbins1) + 0.5) * bin_width2; + array[bin][0] = (bin % nbins1 + 0.5) * bin_width1 + boxlo[dir1]; + if (dims == 2) array[bin][1] = ((int) (bin / nbins1) + 0.5) * bin_width2 + boxlo[dir2]; array[bin][0 + dims] = dens[bin]; array[bin][1 + dims] = pkxx[bin]; array[bin][2 + dims] = pkyy[bin]; From 53b1af7720c9246eec9cbadf6ef0cb39bcc30fad Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 05:11:53 -0400 Subject: [PATCH 349/448] LAMMPS programming style/conventions updates --- src/EXTRA-COMPUTE/compute_stress_mop.cpp | 171 ++++++++---------- src/EXTRA-COMPUTE/compute_stress_mop.h | 2 +- .../compute_stress_mop_profile.cpp | 96 +++++----- .../compute_stress_mop_profile.h | 2 +- 4 files changed, 126 insertions(+), 145 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_mop.cpp b/src/EXTRA-COMPUTE/compute_stress_mop.cpp index e5d0e2ed13..98e3bf7043 100644 --- a/src/EXTRA-COMPUTE/compute_stress_mop.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_mop.cpp @@ -1,4 +1,3 @@ -// clang-format off /* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator https://www.lammps.org/, Sandia National Laboratories @@ -14,6 +13,7 @@ /*------------------------------------------------------------------------ Contributing Authors : Romain Vermorel (LFCR), Laurent Joly (ULyon) + Support for bonds and angles added by : Evangelos Voyiatzis (NovaMechanics) --------------------------------------------------------------------------*/ #include "compute_stress_mop.h" @@ -22,6 +22,7 @@ #include "atom.h" #include "atom_vec.h" #include "bond.h" +#include "comm.h" #include "domain.h" #include "error.h" #include "force.h" @@ -37,50 +38,49 @@ using namespace LAMMPS_NS; -enum{X,Y,Z}; -enum{TOTAL,CONF,KIN,PAIR,BOND,ANGLE}; +enum { X, Y, Z }; +enum { TOTAL, CONF, KIN, PAIR, BOND, ANGLE }; +// clang-format off /* ---------------------------------------------------------------------- */ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 6) error->all(FLERR,"Illegal compute stress/mop command"); - - MPI_Comm_rank(world,&me); + if (narg < 6) utils::missing_cmd_args(FLERR, "compute stress/mop", error); bondflag = 0; angleflag = 0; // set compute mode and direction of plane(s) for pressure calculation - if (strcmp(arg[3],"x")==0) { + if (strcmp(arg[3],"x") == 0) { dir = X; - } else if (strcmp(arg[3],"y")==0) { + } else if (strcmp(arg[3],"y") == 0) { dir = Y; - } else if (strcmp(arg[3],"z")==0) { + } else if (strcmp(arg[3],"z") == 0) { dir = Z; } else error->all(FLERR,"Illegal compute stress/mop command"); // Position of the plane - if (strcmp(arg[4],"lower")==0) { + if (strcmp(arg[4],"lower") == 0) { pos = domain->boxlo[dir]; - } else if (strcmp(arg[4],"upper")==0) { + } else if (strcmp(arg[4],"upper") == 0) { pos = domain->boxhi[dir]; - } else if (strcmp(arg[4],"center")==0) { + } else if (strcmp(arg[4],"center") == 0) { pos = 0.5*(domain->boxlo[dir]+domain->boxhi[dir]); } else pos = utils::numeric(FLERR,arg[4],false,lmp); // plane inside the box - if (pos >domain->boxhi[dir] || pos boxlo[dir]) { - error->warning(FLERR,"The specified initial plane lies outside of the simulation box"); - double dx[3] {0}; + if ((pos > domain->boxhi[dir]) || (pos < domain->boxlo[dir])) { + error->warning(FLERR, "The specified initial plane lies outside of the simulation box"); + double dx[3] = {0.0, 0.0, 0.0}; dx[dir] = pos - 0.5*(domain->boxhi[dir] + domain->boxlo[dir]); domain->minimum_image(dx[0], dx[1], dx[2]); pos = 0.5*(domain->boxhi[dir] + domain->boxlo[dir]) + dx[dir]; - if (pos >domain->boxhi[dir] || pos boxlo[dir]) + if ((pos > domain->boxhi[dir]) || (pos < domain->boxlo[dir])) error->all(FLERR, "Plane for compute stress/mop is out of bounds"); } @@ -133,15 +133,15 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : iarg++; } - // Error check + // Error checks // 3D only - if (domain->dimension < 3) - error->all(FLERR, "Compute stress/mop incompatible with simulation dimension"); + if (domain->dimension != 3) + error->all(FLERR, "Compute stress/mop requires a 3d system"); // orthogonal simulation box if (domain->triclinic != 0) - error->all(FLERR, "Compute stress/mop incompatible with triclinic simulation box"); + error->all(FLERR, "Compute stress/mop is incompatible with triclinic simulation box"); // Initialize some variables @@ -154,12 +154,12 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : // this fix produces a global vector memory->create(vector,nvalues,"stress/mop:vector"); - memory->create(values_local,nvalues,"stress/mop/spatial:values_local"); - memory->create(values_global,nvalues,"stress/mop/spatial:values_global"); - memory->create(bond_local,nvalues,"stress/mop/spatial:bond_local"); - memory->create(bond_global,nvalues,"stress/mop/spatial:bond_global"); - memory->create(angle_local,nvalues,"stress/mop/spatial:angle_local"); - memory->create(angle_global,nvalues,"stress/mop/spatial:angle_global"); + memory->create(values_local,nvalues,"stress/mop:values_local"); + memory->create(values_global,nvalues,"stress/mop:values_global"); + memory->create(bond_local,nvalues,"stress/mop:bond_local"); + memory->create(bond_global,nvalues,"stress/mop:bond_global"); + memory->create(angle_local,nvalues,"stress/mop:angle_local"); + memory->create(angle_global,nvalues,"stress/mop:angle_global"); size_vector = nvalues; vector_flag = 1; @@ -171,8 +171,7 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : ComputeStressMop::~ComputeStressMop() { - - delete [] which; + delete[] which; memory->destroy(values_local); memory->destroy(values_global); @@ -209,36 +208,39 @@ void ComputeStressMop::init() // Compute stress/mop requires fixed simulation box if (domain->box_change_size || domain->box_change_shape || domain->deform_flag) - error->all(FLERR, "Compute stress/mop requires a fixed simulation box"); + error->all(FLERR, "Compute stress/mop requires a fixed size simulation box"); // This compute requires a pair style with pair_single method implemented - if (force->pair == nullptr) + if (!force->pair) error->all(FLERR,"No pair style is defined for compute stress/mop"); if (force->pair->single_enable == 0) error->all(FLERR,"Pair style does not support compute stress/mop"); // Errors - if (me==0) { + if (comm->me == 0) { // issue an error for unimplemented intramolecular potentials or Kspace. - if (force->bond!=nullptr) bondflag = 1; - if (force->angle!=nullptr) + if (force->bond) bondflag = 1; + if (force->angle) { if (force->angle->born_matrix_enable == 0) { if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0)) error->all(FLERR,"compute stress/mop does not account for angle potentials"); } else { angleflag = 1; } - if (force->dihedral!=nullptr) + } + if (force->dihedral) { if ((strcmp(force->dihedral_style, "zero") != 0) && (strcmp(force->dihedral_style, "none") != 0)) error->all(FLERR,"compute stress/mop does not account for dihedral potentials"); - if (force->improper!=nullptr) + } + if (force->improper) { if ((strcmp(force->improper_style, "zero") != 0) && (strcmp(force->improper_style, "none") != 0)) error->all(FLERR,"compute stress/mop does not account for improper potentials"); - if (force->kspace!=nullptr) + } + if (force->kspace) error->warning(FLERR,"compute stress/mop does not account for kspace contributions"); } @@ -266,8 +268,7 @@ void ComputeStressMop::compute_vector() compute_pairs(); // sum pressure contributions over all procs - MPI_Allreduce(values_local,values_global,nvalues, - MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(values_local,values_global,nvalues,MPI_DOUBLE,MPI_SUM,world); if (bondflag) { //Compute bond contribution on separate procs @@ -292,7 +293,6 @@ void ComputeStressMop::compute_vector() for (int m=0; mpos) && (xj[dir]pos1) && (xj[dir] pos) && (xj[dir] < pos)) || ((xi[dir] > pos1) && (xj[dir] < pos1))) { pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair); - values_local[m] += fpair*(xi[0]-xj[0])/area*nktv2p; values_local[m+1] += fpair*(xi[1]-xj[1])/area*nktv2p; values_local[m+2] += fpair*(xi[2]-xj[2])/area*nktv2p; - } - else if (((xi[dir]pos)) || ((xi[dir]pos1))) { - + } else if (((xi[dir] < pos) && (xj[dir] > pos)) || ((xi[dir] < pos1) && (xj[dir] > pos1))) { pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair); - values_local[m] -= fpair*(xi[0]-xj[0])/area*nktv2p; values_local[m+1] -= fpair*(xi[1]-xj[1])/area*nktv2p; values_local[m+2] -= fpair*(xi[2]-xj[2])/area*nktv2p; } - } else { - - if (((xi[dir]>pos) && (xj[dir]pos1) && (xj[dir] pos) && (xj[dir] < pos)) || ((xi[dir] > pos1) && (xj[dir] < pos1))) { pair->single(i,j,itype,jtype,rsq,factor_coul,factor_lj,fpair); - values_local[m] += fpair*(xi[0]-xj[0])/area*nktv2p; values_local[m+1] += fpair*(xi[1]-xj[1])/area*nktv2p; values_local[m+2] += fpair*(xi[2]-xj[2])/area*nktv2p; } - } - } - } - } // Compute kinetic contribution to pressure // counts local particles transfers across the plane - if (which[m] == KIN || which[m] == TOTAL) { + if ((which[m] == KIN) || (which[m] == TOTAL)) { double sgn; for (int i = 0; i < nlocal; i++) { @@ -447,13 +434,13 @@ void ComputeStressMop::compute_pairs() //coordinates at t-dt (based on Velocity-Verlet alg.) if (rmass) { - xj[0] = xi[0]-vi[0]*dt+fi[0]/2/rmass[i]*dt*dt*ftm2v; - xj[1] = xi[1]-vi[1]*dt+fi[1]/2/rmass[i]*dt*dt*ftm2v; - xj[2] = xi[2]-vi[2]*dt+fi[2]/2/rmass[i]*dt*dt*ftm2v; + xj[0] = xi[0]-vi[0]*dt+fi[0]/2.0/rmass[i]*dt*dt*ftm2v; + xj[1] = xi[1]-vi[1]*dt+fi[1]/2.0/rmass[i]*dt*dt*ftm2v; + xj[2] = xi[2]-vi[2]*dt+fi[2]/2.0/rmass[i]*dt*dt*ftm2v; } else { - xj[0] = xi[0]-vi[0]*dt+fi[0]/2/mass[itype]*dt*dt*ftm2v; - xj[1] = xi[1]-vi[1]*dt+fi[1]/2/mass[itype]*dt*dt*ftm2v; - xj[2] = xi[2]-vi[2]*dt+fi[2]/2/mass[itype]*dt*dt*ftm2v; + xj[0] = xi[0]-vi[0]*dt+fi[0]/2.0/mass[itype]*dt*dt*ftm2v; + xj[1] = xi[1]-vi[1]*dt+fi[1]/2.0/mass[itype]*dt*dt*ftm2v; + xj[2] = xi[2]-vi[2]*dt+fi[2]/2.0/mass[itype]*dt*dt*ftm2v; } // because LAMMPS does not put atoms back in the box @@ -463,21 +450,21 @@ void ComputeStressMop::compute_pairs() double pos_temp = pos+copysign(1.0,domain->prd_half[dir]-pos)*domain->prd[dir]; if (fabs(xi[dir]-pos)bond; - double dx[3] {0}; - double x_bond_1[3] {0}; - double x_bond_2[3] {0}; - double local_contribution[3] {0}; + double dx[3] = {0.0, 0.0, 0.0}; + double x_bond_1[3] = {0.0, 0.0, 0.0}; + double x_bond_2[3] = {0.0, 0.0, 0.0}; + double local_contribution[3] = {0.0, 0.0, 0.0}; // initialization - for (int i {0}; i < nvalues; i++) bond_local[i] = 0.0; + for (int i = 0; i < nvalues; i++) bond_local[i] = 0.0; // loop over all bonded atoms in the current proc for (atom1 = 0; atom1 < nlocal; atom1++) { @@ -591,7 +578,7 @@ void ComputeStressMop::compute_bonds() } // loop over the keywords and if necessary add the bond contribution - int m {0}; + int m = 0; while (mangle; double duang, du2ang; - double dx[3] {0}; - double dx_left[3] {0}; - double dx_right[3] {0}; - double x_angle_left[3] {0}; - double x_angle_middle[3] {0}; - double x_angle_right[3] {0}; - double dcos_theta[3] {0}; - double local_contribution[3] {0}; + double dx[3] = {0.0, 0.0, 0.0}; + double dx_left[3] = {0.0, 0.0, 0.0}; + double dx_right[3] = {0.0, 0.0, 0.0}; + double x_angle_left[3] = {0.0, 0.0, 0.0}; + double x_angle_middle[3] = {0.0, 0.0, 0.0}; + double x_angle_right[3] = {0.0, 0.0, 0.0}; + double dcos_theta[3] = {0.0, 0.0, 0.0}; + double local_contribution[3] = {0.0, 0.0, 0.0}; // initialization - for (int i {0}; i < nvalues; i++) angle_local[i] = 0.0; + for (int i = 0; i < nvalues; i++) angle_local[i] = 0.0; for (atom2 = 0; atom2 < nlocal; atom2++) { if (!(mask[atom2] & groupbit)) continue; @@ -762,8 +749,8 @@ void ComputeStressMop::compute_angles() } } // loop over the keywords and if necessary add the angle contribution - int m {0}; - while (m #include using namespace LAMMPS_NS; -enum{X,Y,Z}; -enum{LOWER,CENTER,UPPER,COORD}; -enum{TOTAL,CONF,KIN,PAIR,BOND}; +enum { X, Y, Z }; +enum { LOWER, CENTER, UPPER, COORD }; +enum { TOTAL, CONF, KIN, PAIR, BOND }; +// clang-format off /* ---------------------------------------------------------------------- */ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **arg) : Compute(lmp, narg, arg) { - if (narg < 7) error->all(FLERR,"Illegal compute stress/mop/profile command"); - - MPI_Comm_rank(world,&me); + if (narg < 7) utils::missing_cmd_args(FLERR, "compute stress/mop/profile", error); bondflag = 0; // set compute mode and direction of plane(s) for pressure calculation - if (strcmp(arg[3],"x")==0) { + if (strcmp(arg[3],"x") == 0) { dir = X; - } else if (strcmp(arg[3],"y")==0) { + } else if (strcmp(arg[3],"y") == 0) { dir = Y; - } else if (strcmp(arg[3],"z")==0) { + } else if (strcmp(arg[3],"z") == 0) { dir = Z; } else error->all(FLERR,"Illegal compute stress/mop/profile command"); @@ -67,8 +67,7 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a else if (strcmp(arg[4],"center") == 0) originflag = CENTER; else if (strcmp(arg[4],"upper") == 0) originflag = UPPER; else originflag = COORD; - if (originflag == COORD) - origin = utils::numeric(FLERR,arg[4],false,lmp); + if (originflag == COORD) origin = utils::numeric(FLERR,arg[4],false,lmp); delta = utils::numeric(FLERR,arg[5],false,lmp); invdelta = 1.0/delta; @@ -149,8 +148,7 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a ComputeStressMopProfile::~ComputeStressMopProfile() { - - delete [] which; + delete[] which; memory->destroy(coord); memory->destroy(coordp); @@ -166,7 +164,6 @@ ComputeStressMopProfile::~ComputeStressMopProfile() void ComputeStressMopProfile::init() { - // conversion constants nktv2p = force->nktv2p; @@ -192,30 +189,30 @@ void ComputeStressMopProfile::init() //This compute requires a pair style with pair_single method implemented - if (force->pair == nullptr) + if (!force->pair) error->all(FLERR,"No pair style is defined for compute stress/mop/profile"); if (force->pair->single_enable == 0) error->all(FLERR,"Pair style does not support compute stress/mop/profile"); // Errors - if (me==0) { + if (comm->me == 0) { //Compute stress/mop/profile only accounts for pair interactions. // issue an error if any intramolecular potential or Kspace is defined. - if (force->bond!=nullptr) bondflag = 1; + if (force->bond) bondflag = 1; - if (force->angle!=nullptr) + if (force->angle) if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0)) error->all(FLERR,"compute stress/mop/profile does not account for angle potentials"); - if (force->dihedral!=nullptr) + if (force->dihedral) if ((strcmp(force->dihedral_style, "zero") != 0) && (strcmp(force->dihedral_style, "none") != 0)) error->all(FLERR,"compute stress/mop/profile does not account for dihedral potentials"); - if (force->improper!=nullptr) + if (force->improper) if ((strcmp(force->improper_style, "zero") != 0) && (strcmp(force->improper_style, "none") != 0)) error->all(FLERR,"compute stress/mop/profile does not account for improper potentials"); - if (force->kspace!=nullptr) + if (force->kspace) error->warning(FLERR,"compute stress/mop/profile does not account for kspace contributions"); } @@ -244,8 +241,7 @@ void ComputeStressMopProfile::compute_array() compute_pairs(); // sum pressure contributions over all procs - MPI_Allreduce(&values_local[0][0],&values_global[0][0],nbins*nvalues, - MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&values_local[0][0],&values_global[0][0],nbins*nvalues,MPI_DOUBLE,MPI_SUM,world); if (bondflag) { //Compute bond contribution on separate procs @@ -259,16 +255,14 @@ void ComputeStressMopProfile::compute_array() } // sum bond contribution over all procs - MPI_Allreduce(&bond_local[0][0],&bond_global[0][0],nbins*nvalues, - MPI_DOUBLE,MPI_SUM,world); + MPI_Allreduce(&bond_local[0][0],&bond_global[0][0],nbins*nvalues,MPI_DOUBLE,MPI_SUM,world); - int ibin,m,mo; - for (ibin=0; ibinbond; - double dx[3] {0}; - double x_bond_1[3] {0}; - double x_bond_2[3] {0}; + double dx[3] = {0.0, 0.0, 0.0}; + double x_bond_1[3] = {0.0, 0.0, 0.0}; + double x_bond_2[3] = {0.0, 0.0, 0.0}; // initialization - for (int m {0}; m < nbins; m++) { - for (int i {0}; i < nvalues; i++) { + for (int m = 0; m < nbins; m++) { + for (int i = 0; i < nvalues; i++) { bond_local[m][i] = 0.0; } local_contribution[m][0] = 0.0; @@ -557,7 +551,7 @@ void ComputeStressMopProfile::compute_bonds() if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; if (btype <= 0) continue; - for (int ibin {0}; ibin Date: Wed, 7 Jun 2023 06:20:24 -0400 Subject: [PATCH 350/448] remove unused include and related statements --- src/INTERLAYER/pair_aip_water_2dm.cpp | 7 ------- src/INTERLAYER/pair_ilp_tmd.cpp | 4 ---- src/OPT/pair_aip_water_2dm_opt.cpp | 10 ---------- 3 files changed, 21 deletions(-) diff --git a/src/INTERLAYER/pair_aip_water_2dm.cpp b/src/INTERLAYER/pair_aip_water_2dm.cpp index f2d68f448b..6e2bf7228d 100644 --- a/src/INTERLAYER/pair_aip_water_2dm.cpp +++ b/src/INTERLAYER/pair_aip_water_2dm.cpp @@ -20,21 +20,14 @@ #include "pair_aip_water_2dm.h" -#include "atom.h" #include "citeme.h" #include "error.h" #include "force.h" -#include "interlayer_taper.h" -#include "memory.h" -#include "my_page.h" -#include "neigh_list.h" -#include "neigh_request.h" #include #include using namespace LAMMPS_NS; -using namespace InterLayer; #define MAXLINE 1024 #define DELTA 4 diff --git a/src/INTERLAYER/pair_ilp_tmd.cpp b/src/INTERLAYER/pair_ilp_tmd.cpp index f29ee34180..fd3a2f8c6f 100644 --- a/src/INTERLAYER/pair_ilp_tmd.cpp +++ b/src/INTERLAYER/pair_ilp_tmd.cpp @@ -35,10 +35,6 @@ using namespace LAMMPS_NS; using namespace InterLayer; -#define MAXLINE 1024 -#define DELTA 4 -#define PGDELTA 1 - static const char cite_ilp_tmd[] = "ilp/tmd potential doi:10.1021/acs.jctc.1c00782\n" "@Article{Ouyang2021\n" diff --git a/src/OPT/pair_aip_water_2dm_opt.cpp b/src/OPT/pair_aip_water_2dm_opt.cpp index 3aba5b9dbd..47c8c395db 100644 --- a/src/OPT/pair_aip_water_2dm_opt.cpp +++ b/src/OPT/pair_aip_water_2dm_opt.cpp @@ -33,21 +33,11 @@ #include "pair_aip_water_2dm_opt.h" #include "atom.h" -#include "citeme.h" -#include "comm.h" -#include "error.h" -#include "force.h" -#include "interlayer_taper.h" #include "memory.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "neighbor.h" -#include #include using namespace LAMMPS_NS; -using namespace InterLayer; PairAIPWATER2DMOpt::PairAIPWATER2DMOpt(LAMMPS *lmp) : PairILPGrapheneHBN(lmp), PairILPTMD(lmp), PairAIPWATER2DM(lmp), PairILPGrapheneHBNOpt(lmp) From 37d894db51074724b20ff1e6befe8c4f7099320f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 06:30:07 -0400 Subject: [PATCH 351/448] update/clarify docs --- doc/src/pair_aip_water_2dm.rst | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/doc/src/pair_aip_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst index 5218db9c37..f57e4b33fb 100644 --- a/doc/src/pair_aip_water_2dm.rst +++ b/doc/src/pair_aip_water_2dm.rst @@ -59,22 +59,20 @@ a continuous cutoff (up to third derivative) for interatomic separations larger than :math:`r_c` :doc:`pair_style ilp_graphene_hbn `. -It is important to include all the pairs to build the neighbor list for -calculating the normals. - .. note:: - Since each water molecule contains one oxygen atom and two hydrogen - atoms, a new definition is proposed (see In :ref:`(Feng) `),the - atomic normal vectors of hydrogen atoms are assumed to lie along the - corresponding oxygen-hydrogen bonds and the normal vector of the - central oxygen atom is defined as their average. + This pair style uses the atomic normal vector definition from + :ref:`(Feng) `), where the atomic normal vectors of the + hydrogen atoms are assumed to lie along the corresponding + oxygen-hydrogen bonds and the normal vector of the central oxygen + atom is defined as their average. The provided parameter file, ``COH.aip.water.2dm``, is intended for use with *metal* :doc:`units `, with energies in meV. Two additional parameters, *S*, and *rcut* are included in the parameter file. *S* is -designed to facilitate scaling of energies; *rcut* is designed to build -the neighbor list for calculating the normals for each atom pair. +designed to facilitate scaling of energies; *rcut* is the cutoff for an +internal, short distance neighbor list that is generated for speeding up +the calculation of the normals for all atom pairs. .. note:: @@ -83,9 +81,9 @@ the neighbor list for calculating the normals for each atom pair. setting the cutoff equal to 16.0 Angstrom. Using a different cutoff or taper function setting should be carefully checked as they can lead to significant errors. These parameters provide a good - description in both short- and long-range interaction regimes. This - feature is essential for simulations in high pressure regime (i.e., - the interlayer distance is smaller than the equilibrium distance). + description in both short- and long-range interaction regimes. This + is essential for simulations in high pressure regime (i.e., the + interlayer distance is smaller than the equilibrium distance). This potential must be used in combination with hybrid/overlay. Other interactions can be set to zero using :doc:`pair_coeff settings From 57f166670f08fe7a683306172ca4d5527e6564cb Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 06:38:52 -0400 Subject: [PATCH 352/448] fix versionadded macro so it is detected when actual version is added --- doc/src/pair_aip_water_2dm.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/pair_aip_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst index f57e4b33fb..532ee8f8f6 100644 --- a/doc/src/pair_aip_water_2dm.rst +++ b/doc/src/pair_aip_water_2dm.rst @@ -33,7 +33,7 @@ Examples Description """"""""""" -.. versionadded:: xxxx2023 +.. versionadded:: TBD The *aip/water/2dm* style computes the anisotropic interfacial potential (AIP) potential for interfaces of water with two-dimensional (2D) From f2f8e139d8c23e750ce603ef4cd2a95b245bdb5a Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Wed, 7 Jun 2023 16:03:32 +0200 Subject: [PATCH 353/448] Add optional keywords to arguments for ke/pair/bond forces --- .../compute_stress_cartesian.cpp | 232 ++++++++++-------- src/EXTRA-COMPUTE/compute_stress_cartesian.h | 3 + 2 files changed, 130 insertions(+), 105 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index 0aae797111..3835b8bea9 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -62,14 +62,12 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg { if (lmp->citeme) lmp->citeme->add(cite_compute_stress_cartesian); - // narg == 5 for one-dimensional and narg == 7 for two-dimensional - if (narg == 5) - dims = 1; - else if (narg == 7) - dims = 2; - else - error->all(FLERR, "Illegal compute stress/cartesian command. Illegal number of arguments."); + if (narg < 7) error->all(FLERR, "Illegal compute stress/cartesian command: illegal number of arguments."); + // no triclinic boxes + if (domain->triclinic) error->all(FLERR, "Compute stress/cartesian requires an orthogonal box"); + + // Direction of first dimension if (strcmp(arg[3], "x") == 0) dir1 = 0; else if (strcmp(arg[3], "y") == 0) @@ -79,14 +77,8 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg else error->all(FLERR, "Illegal compute stress/cartesian direction: {}", arg[3]); - dir2 = 0; bin_width1 = utils::numeric(FLERR, arg[4], false, lmp); - bin_width2 = domain->boxhi[dir2] - domain->boxlo[dir2]; nbins1 = (int) ((domain->boxhi[dir1] - domain->boxlo[dir1]) / bin_width1); - nbins2 = 1; - - // no triclinic boxes - if (domain->triclinic) error->all(FLERR, "Compute stress/cartesian requires an orthogonal box"); // adjust bin width if not a perfect match double tmp_binwidth = (domain->boxhi[dir1] - domain->boxlo[dir1]) / nbins1; @@ -94,14 +86,23 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg utils::logmesg(lmp, "Adjusting first bin width for compute {} from {:.6f} to {:.6f}\n", style, bin_width1, tmp_binwidth); bin_width1 = tmp_binwidth; + invV = bin_width1; if (bin_width1 <= 0.0) error->all(FLERR, "Illegal compute stress/cartesian command. First bin width must be > 0"); else if (bin_width1 > domain->boxhi[dir1] - domain->boxlo[dir1]) error->all(FLERR, "Illegal compute stress/cartesian command. First bin width > box."); - invV = bin_width1; - if (dims == 2) { + // Direction of second dimension + if (strcmp(arg[5], "NULL") == 0) { + dims = 1; + dir2 = 0; + bin_width2 = domain->boxhi[dir2] - domain->boxlo[dir2]; + nbins2 = 1; + } else { + dims = 2; + + // Direction of first dimension if (strcmp(arg[5], "x") == 0) dir2 = 0; else if (strcmp(arg[5], "y") == 0) @@ -150,6 +151,21 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg if (box_incompatible) error->all(FLERR, "Must not use compute stress/cartesian on variable box dimension"); + // process optional args + if (narg > 7) { + compute_ke = false; + compute_pair = false; + compute_bond = false; + int iarg = 7; + while (iarg < narg) { + if (strcmp(arg[iarg], "ke") == 0) compute_ke = true; + else if (strcmp(arg[iarg], "pair") == 0) compute_pair = true; + else if (strcmp(arg[iarg], "bond") == 0) compute_bond = true; + else error->all(FLERR, "Illegal compute stress/atom command"); + iarg++; + } + } + for (int i = 0; i < 3; i++) if ((dims == 1 && i != dir1) || (dims == 2 && (i != dir1 && i != dir2))) invV *= domain->boxhi[i] - domain->boxlo[i]; @@ -262,119 +278,125 @@ void ComputeStressCartesian::compute_array() } // calculate number density and kinetic contribution to pressure - for (int i = 0; i < nlocal; i++) { - int bin1 = (int) ((x[i][dir1] - boxlo[dir1]) / bin_width1) % nbins1; - int bin2 = 0; - if (dims == 2) bin2 = (int) ((x[i][dir2] - boxlo[dir2]) / bin_width2) % nbins2; + if (compute_ke) { + for (int i = 0; i < nlocal; i++) { + int bin1 = (int) ((x[i][dir1] - boxlo[dir1]) / bin_width1) % nbins1; + int bin2 = 0; + if (dims == 2) bin2 = (int) ((x[i][dir2] - boxlo[dir2]) / bin_width2) % nbins2; - // Apply periodic boundary conditions and avoid out of range access - if (domain->periodicity[dir1] == 1) { - if (bin1 < 0) - bin1 = (bin1 + nbins1) % nbins1; + // Apply periodic boundary conditions and avoid out of range access + if (domain->periodicity[dir1] == 1) { + if (bin1 < 0) + bin1 = (bin1 + nbins1) % nbins1; + else if (bin1 >= nbins1) + bin1 = (bin1 - nbins1) % nbins1; + } else if (bin1 < 0) + bin1 = 0; else if (bin1 >= nbins1) - bin1 = (bin1 - nbins1) % nbins1; - } else if (bin1 < 0) - bin1 = 0; - else if (bin1 >= nbins1) - bin1 = nbins1 - 1; + bin1 = nbins1 - 1; - if (domain->periodicity[dir2] == 1) { - if (bin2 < 0) - bin2 = (bin2 + nbins2) % nbins2; + if (domain->periodicity[dir2] == 1) { + if (bin2 < 0) + bin2 = (bin2 + nbins2) % nbins2; + else if (bin2 >= nbins2) + bin2 = (bin2 - nbins2) % nbins2; + } else if (bin2 < 0) + bin2 = 0; else if (bin2 >= nbins2) - bin2 = (bin2 - nbins2) % nbins2; - } else if (bin2 < 0) - bin2 = 0; - else if (bin2 >= nbins2) - bin2 = nbins2 - 1; + bin2 = nbins2 - 1; - int j = bin1 + bin2 * nbins1; - tdens[j] += 1; - tpkxx[j] += mass[type[i]] * v[i][0] * v[i][0]; - tpkyy[j] += mass[type[i]] * v[i][1] * v[i][1]; - tpkzz[j] += mass[type[i]] * v[i][2] * v[i][2]; + int j = bin1 + bin2 * nbins1; + tdens[j] += 1; + tpkxx[j] += mass[type[i]] * v[i][0] * v[i][0]; + tpkyy[j] += mass[type[i]] * v[i][1] * v[i][1]; + tpkzz[j] += mass[type[i]] * v[i][2] * v[i][2]; + } } // loop over neighbors of my atoms - for (int ii = 0; ii < inum; ii++) { - int i = ilist[ii]; + if (compute_pair && force->pair) { + for (int ii = 0; ii < inum; ii++) { + int i = ilist[ii]; - // skip if I or J are not in group - if (!(mask[i] & groupbit)) continue; + // skip if I or J are not in group + if (!(mask[i] & groupbit)) continue; - double xi1 = x[i][dir1] - boxlo[dir1]; - double xi2 = x[i][dir2] - boxlo[dir2]; + double xi1 = x[i][dir1] - boxlo[dir1]; + double xi2 = x[i][dir2] - boxlo[dir2]; - for (int jj = 0; jj < numneigh[i]; jj++) { - int j = firstneigh[i][jj]; - double factor_lj = special_lj[sbmask(j)]; - double factor_coul = special_coul[sbmask(j)]; - j &= NEIGHMASK; - if (!(mask[j] & groupbit)) continue; + for (int jj = 0; jj < numneigh[i]; jj++) { + int j = firstneigh[i][jj]; + double factor_lj = special_lj[sbmask(j)]; + double factor_coul = special_coul[sbmask(j)]; + j &= NEIGHMASK; + if (!(mask[j] & groupbit)) continue; - // for newton = 0 and J = ghost atom, need to ensure I,J pair is only output by one proc - // use same tag[i],tag[j] logic as in Neighbor::neigh_half_nsq() - if (newton_pair == 0 && j >= nlocal) { - if (tag[i] > tag[j]) { - if ((tag[i] + tag[j]) % 2 == 0) continue; - } else if (tag[i] < tag[j]) { - if ((tag[i] + tag[j]) % 2 == 1) continue; - } else { - // tag[i] = tag[j] is possible for long cutoffs that include images of self - if (x[j][2] < x[i][2]) continue; - if (x[j][2] == x[i][2]) { - if (x[j][1] < x[i][1]) continue; - if (x[j][1] == x[i][1] && x[j][0] < x[i][0]) continue; + // for newton = 0 and J = ghost atom, need to ensure I,J pair is only output by one proc + // use same tag[i],tag[j] logic as in Neighbor::neigh_half_nsq() + if (newton_pair == 0 && j >= nlocal) { + if (tag[i] > tag[j]) { + if ((tag[i] + tag[j]) % 2 == 0) continue; + } else if (tag[i] < tag[j]) { + if ((tag[i] + tag[j]) % 2 == 1) continue; + } else { + // tag[i] = tag[j] is possible for long cutoffs that include images of self + if (x[j][2] < x[i][2]) continue; + if (x[j][2] == x[i][2]) { + if (x[j][1] < x[i][1]) continue; + if (x[j][1] == x[i][1] && x[j][0] < x[i][0]) continue; + } } } + + double delx = x[j][0] - x[i][0]; + double dely = x[j][1] - x[i][1]; + double delz = x[j][2] - x[i][2]; + double rsq = delx * delx + dely * dely + delz * delz; + + // Check if inside cut-off + int itype = type[i]; + int jtype = type[j]; + if (rsq >= force->pair->cutsq[itype][jtype]) continue; + + double fpair; + force->pair->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fpair); + compute_pressure(fpair, xi1, xi2, delx, dely, delz); } - - double delx = x[j][0] - x[i][0]; - double dely = x[j][1] - x[i][1]; - double delz = x[j][2] - x[i][2]; - double rsq = delx * delx + dely * dely + delz * delz; - - // Check if inside cut-off - int itype = type[i]; - int jtype = type[j]; - if (rsq >= force->pair->cutsq[itype][jtype]) continue; - - double fpair; - force->pair->single(i, j, itype, jtype, rsq, factor_coul, factor_lj, fpair); - compute_pressure(fpair, xi1, xi2, delx, dely, delz); } } // Loop over all bonds - for (int i_bond = 0; i_bond < neighbor->nbondlist; i_bond++) { - // i == atom1, j == atom2 - int i = neighbor->bondlist[i_bond][0]; - int j = neighbor->bondlist[i_bond][1]; - int btype = neighbor->bondlist[i_bond][2]; + if (compute_bond && force->bond) { + for (int i_bond = 0; i_bond < neighbor->nbondlist; i_bond++) { + // i == atom1, j == atom2 + int i = neighbor->bondlist[i_bond][0]; + int j = neighbor->bondlist[i_bond][1]; + int btype = neighbor->bondlist[i_bond][2]; - // Skip if one of both atoms is not in group - if (!(mask[i] & groupbit)) continue; - if (!(mask[j] & groupbit)) continue; + // Skip if one of both atoms is not in group + if (!(mask[i] & groupbit)) continue; + if (!(mask[j] & groupbit)) continue; - // if newton_bond is off and atom2 is a ghost atom, only compute this on one processor - if (!force->newton_bond && j >= nlocal) { - if (tag[i] > tag[j]) { - if ((tag[i] + tag[j]) % 2 == 0) continue; - } else if (tag[i] < tag[j]) { - if ((tag[i] < tag[j]) % 2 == 1) continue; + // if newton_bond is off and atom2 is a ghost atom, only compute this on one processor + if (!force->newton_bond && j >= nlocal) { + if (tag[i] > tag[j]) { + if ((tag[i] + tag[j]) % 2 == 0) continue; + } else if (tag[i] < tag[j]) { + if ((tag[i] < tag[j]) % 2 == 1) continue; + } } + + double dx = x[j][0] - x[i][0]; + double dy = x[j][1] - x[i][1]; + double dz = x[j][2] - x[i][2]; + double rsq = dx*dx + dy*dy + dz*dz; + double xi = x[i][dir1] - boxlo[dir1]; + double yi = x[i][dir2] - boxlo[dir2]; + + double fbond; + force->bond->single(btype, rsq, i, j, fbond); + compute_pressure(fbond, xi, yi, dx, dy, dz); } - - double dx = x[j][0] - x[i][0]; - double dy = x[j][1] - x[i][1]; - double dz = x[j][2] - x[i][2]; - double rsq = dx*dx + dy*dy + dz*dz; - double xi = x[i][dir1] - boxlo[dir1]; - double yi = x[i][dir2] - boxlo[dir2]; - - double fbond; - force->bond->single(btype, rsq, i, j, fbond); - compute_pressure(fbond, xi, yi, dx, dy, dz); } // normalize pressure diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.h b/src/EXTRA-COMPUTE/compute_stress_cartesian.h index 0954d9ca71..40f2e9d4af 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.h +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.h @@ -36,6 +36,9 @@ class ComputeStressCartesian : public Compute { private: int nbins1, nbins2, dir1, dir2, dims; double bin_width1, bin_width2, invV; + bool compute_ke = true; + bool compute_pair = true; + bool compute_bond = true; // Number density, kinetic and configurational contribution to the pressure. double *dens, *pkxx, *pkyy, *pkzz, *pcxx, *pcyy, *pczz; From 2f88153f060f8bac8a98108b86cd298403a1c5a6 Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Wed, 7 Jun 2023 10:43:51 -0700 Subject: [PATCH 354/448] Implementing feature request for runtime control of pppm_table in Intel package. --- doc/src/package.rst | 19 +++++++++++-------- src/INTEL/fix_intel.cpp | 8 ++++++-- src/INTEL/fix_intel.h | 4 ++-- src/INTEL/intel_preprocess.h | 2 -- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/doc/src/package.rst b/doc/src/package.rst index 6d425b63dd..ce45a1eb79 100644 --- a/doc/src/package.rst +++ b/doc/src/package.rst @@ -68,6 +68,9 @@ Syntax Ntpc = max number of co-processor threads per co-processor core (default = 4) *tptask* value = Ntptask Ntptask = max number of co-processor threads per MPI task (default = 240) + *pppm_table* value = *yes* or *no* + *yes* = Precompute pppm values in table (doesn't change accuracy) + *no* = Compute pppm values on the fly *no_affinity* values = none *kokkos* args = keyword value ... zero or more keyword/value pairs may be appended @@ -708,14 +711,14 @@ in your input script or via the "-pk gpu" :doc:`command-line switch ` is used. If it is -not used, you must invoke the package intel command in your input -script or via the "-pk intel" :doc:`command-line switch `. +tptask = 240, pppm_table = yes. The default ghost option is determined +by the pair style being used. This value is output to the screen in +the offload report at the end of each run. Note that all of these +settings, except "omp" and "mode", are ignored if LAMMPS was not built +with Xeon Phi co-processor support. These settings are made +automatically if the "-sf intel" :doc:`command-line switch ` +is used. If it is not used, you must invoke the package intel command +in your input script or via the "-pk intel" :doc:`command-line switch `. For the KOKKOS package, the option defaults for GPUs are neigh = full, neigh/qeq = full, newton = off, binsize for GPUs = 2x LAMMPS default diff --git a/src/INTEL/fix_intel.cpp b/src/INTEL/fix_intel.cpp index 89775108cb..2b786b6eed 100644 --- a/src/INTEL/fix_intel.cpp +++ b/src/INTEL/fix_intel.cpp @@ -95,6 +95,7 @@ FixIntel::FixIntel(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) _allow_separate_buffers = 1; _offload_ghost = -1; _lrt = 0; + _p3m_table = 1; int iarg = 4; while (iarg < narg) { @@ -135,11 +136,14 @@ FixIntel::FixIntel(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) if (iarg+2 > narg) error->all(FLERR,"Illegal package intel command"); _lrt = utils::logical(FLERR,arg[iarg+1],false,lmp); iarg += 2; - } + } else if (strcmp(arg[iarg], "pppm_table") == 0) { + if (iarg+2 > narg) error->all(FLERR,"Illegal package intel command"); + _p3m_table = utils::logical(FLERR,arg[iarg+1],false,lmp); + iarg += 2; // undocumented options - else if (strcmp(arg[iarg],"offload_affinity_balanced") == 0) { + } else if (strcmp(arg[iarg],"offload_affinity_balanced") == 0) { _offload_affinity_balanced = 1; iarg++; } else if (strcmp(arg[iarg],"buffers") == 0) { diff --git a/src/INTEL/fix_intel.h b/src/INTEL/fix_intel.h index 1960a6d802..050b27c313 100644 --- a/src/INTEL/fix_intel.h +++ b/src/INTEL/fix_intel.h @@ -103,7 +103,7 @@ class FixIntel : public Fix { inline int pppm_table() { if (force->kspace_match("^pppm/.*intel$", 0)) - return INTEL_P3M_TABLE; + return _p3m_table; else return 0; } @@ -194,7 +194,7 @@ class FixIntel : public Fix { protected: int _overflow_flag[5]; _alignvar(int _off_overflow_flag[5], 64); - int _allow_separate_buffers, _offload_ghost, _lrt; + int _allow_separate_buffers, _offload_ghost, _lrt, _p3m_table; IntelBuffers::vec3_acc_t *_force_array_s; IntelBuffers::vec3_acc_t *_force_array_m; diff --git a/src/INTEL/intel_preprocess.h b/src/INTEL/intel_preprocess.h index a3c961f436..2c4b9a0c1b 100644 --- a/src/INTEL/intel_preprocess.h +++ b/src/INTEL/intel_preprocess.h @@ -86,8 +86,6 @@ enum {TIME_PACK, TIME_HOST_NEIGHBOR, TIME_HOST_PAIR, TIME_OFFLOAD_NEIGHBOR, #define INTEL_MAX_STENCIL_CHECK 4096 #define INTEL_P3M_MAXORDER 8 #define INTEL_P3M_ALIGNED_MAXORDER 8 -// PRECOMPUTE VALUES IN TABLE (DOESN'T AFFECT ACCURACY) -#define INTEL_P3M_TABLE 1 #ifdef __INTEL_COMPILER #ifdef __AVX__ From 6360c02daaa882c73770aaebd3a11f1239b398f6 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 14:04:41 -0400 Subject: [PATCH 355/448] use explicit const references --- src/EXTRA-DUMP/dump_yaml.cpp | 6 +++--- src/NETCDF/dump_netcdf.cpp | 10 +++++----- src/NETCDF/dump_netcdf_mpiio.cpp | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/EXTRA-DUMP/dump_yaml.cpp b/src/EXTRA-DUMP/dump_yaml.cpp index 029415164f..ec7d26af31 100644 --- a/src/EXTRA-DUMP/dump_yaml.cpp +++ b/src/EXTRA-DUMP/dump_yaml.cpp @@ -64,10 +64,10 @@ void DumpYAML::write_header(bigint ndump) if (update->ntimestep == th->get_timestep()) { thermo_data += "thermo:\n - keywords: [ "; - for (auto key : th->get_keywords()) thermo_data += fmt::format("{}, ", key); + for (const auto &key : th->get_keywords()) thermo_data += fmt::format("{}, ", key); thermo_data += "]\n - data: [ "; - for (auto val : th->get_fields()) { + for (const auto &val : th->get_fields()) { if (val.type == multitype::DOUBLE) thermo_data += fmt::format("{}, ", val.data.d); else if (val.type == multitype::INT) @@ -90,7 +90,7 @@ void DumpYAML::write_header(bigint ndump) fmt::print(fp, "natoms: {}\n", ndump); fputs("boundary: [ ", fp); - for (const auto bflag : boundary) { + for (const auto &bflag : boundary) { if (bflag == ' ') continue; fmt::print(fp, "{}, ", bflag); } diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index cb6aea16cf..8c99ff1f70 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -320,7 +320,7 @@ void DumpNetCDF::openfile() // perframe variables if (thermo) { - auto keywords = output->thermo->get_keywords(); + const auto &keywords = output->thermo->get_keywords(); int nfield = keywords.size(); for (int i = 0; i < nfield; i++) { NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); @@ -433,8 +433,8 @@ void DumpNetCDF::openfile() // perframe variables if (thermo) { - auto fields = output->thermo->get_fields(); - auto keywords = output->thermo->get_keywords(); + const auto &fields = output->thermo->get_fields(); + const auto &keywords = output->thermo->get_keywords(); int nfield = fields.size(); for (int i = 0; i < nfield; i++) { if (fields[i].type == multitype::DOUBLE) { @@ -600,8 +600,8 @@ void DumpNetCDF::write() start[1] = 0; if (thermo) { - auto keywords = output->thermo->get_keywords(); - auto fields = output->thermo->get_fields(); + const auto &keywords = output->thermo->get_keywords(); + const auto &fields = output->thermo->get_fields(); int nfield = fields.size(); for (int i = 0; i < nfield; i++) { if (filewriter) { diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index fdcd03470e..3aec34dd40 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -318,7 +318,7 @@ void DumpNetCDFMPIIO::openfile() // perframe variables if (thermo) { - auto keywords = output->thermo->get_keywords(); + const auto &keywords = output->thermo->get_keywords(); int nfield = keywords.size(); for (int i = 0; i < nfield; i++) { NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); @@ -423,8 +423,8 @@ void DumpNetCDFMPIIO::openfile() // perframe variables if (thermo) { - auto fields = output->thermo->get_fields(); - auto keywords = output->thermo->get_keywords(); + const auto &fields = output->thermo->get_fields(); + const auto &keywords = output->thermo->get_keywords(); int nfield = fields.size(); for (int i = 0; i < nfield; i++) { if (fields[i].type == multitype::DOUBLE) { @@ -593,8 +593,8 @@ void DumpNetCDFMPIIO::write() NCERR( ncmpi_begin_indep_data(ncid) ); if (thermo) { - auto keywords = output->thermo->get_keywords(); - auto fields = output->thermo->get_fields(); + const auto &keywords = output->thermo->get_keywords(); + const auto &fields = output->thermo->get_fields(); int nfield = fields.size(); for (int i = 0; i < nfield; i++) { if (filewriter) { From b7afe412dc939876b0165eaa7325c8bed9e0e56c Mon Sep 17 00:00:00 2001 From: jtclemm Date: Wed, 7 Jun 2023 13:08:46 -0600 Subject: [PATCH 356/448] Updating SDPD examples --- .../2d-diffusion-in-shear-flow/in.lammps | 6 +- ...g.24Oct18.2d-diffusion-in-shear-flow.g++.1 | 247 ----------------- ...g.24Oct18.2d-diffusion-in-shear-flow.g++.4 | 247 ----------------- ...g.28Mar23.2d-diffusion-in-shear-flow.g++.1 | 253 ++++++++++++++++++ ...g.28Mar23.2d-diffusion-in-shear-flow.g++.4 | 253 ++++++++++++++++++ .../dpd-smooth/2d-diffusion/in.lammps | 6 +- .../log.24Oct18.2d-diffusion.g++.1 | 226 ---------------- .../log.24Oct18.2d-diffusion.g++.4 | 226 ---------------- .../log.28Mar23.2d-diffusion.g++.1 | 230 ++++++++++++++++ .../log.28Mar23.2d-diffusion.g++.4 | 230 ++++++++++++++++ .../equipartition-verification/in.lammps | 6 +- ....g++.1 => log.28Mar23.equipartition.g++.1} | 91 ++++--- ....g++.4 => log.28Mar23.equipartition.g++.4} | 91 ++++--- 13 files changed, 1069 insertions(+), 1043 deletions(-) delete mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.1 delete mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.4 create mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.1 create mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.4 delete mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.1 delete mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.4 create mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.1 create mode 100644 examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.4 rename examples/PACKAGES/dpd-smooth/equipartition-verification/{log.24Oct18.equipartition.g++.1 => log.28Mar23.equipartition.g++.1} (58%) rename examples/PACKAGES/dpd-smooth/equipartition-verification/{log.24Oct18.equipartition.g++.4 => log.28Mar23.equipartition.g++.4} (58%) diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/in.lammps b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/in.lammps index 138f7b5338..dd50a5e69f 100644 --- a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/in.lammps +++ b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/in.lammps @@ -1,6 +1,6 @@ dimension 2 units micro -atom_style meso +atom_style sph variable R equal 0.5 # radius of sphere micrometers variable a equal $R/5 # lattice spacing micrometers @@ -37,12 +37,12 @@ group upper_wall type 3 group lower_wall type 4 mass * ${mass} -set group all meso/rho ${rho_0} +set group all sph/rho ${rho_0} pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed pair_coeff * * ${rho_0} ${c_0} ${h} -fix 1 fluid meso +fix 1 fluid sph fix 2 sphere rigid/meso single fix 3 upper_wall meso/move linear +${wall_velocity} 0 0 units box fix 4 lower_wall meso/move linear -${wall_velocity} 0 0 units box diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.1 b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.1 deleted file mode 100644 index cd01601292..0000000000 --- a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.1 +++ /dev/null @@ -1,247 +0,0 @@ -LAMMPS (24 Oct 2018) -dimension 2 -units micro -atom_style meso - -variable R equal 0.5 # radius of sphere micrometers -variable a equal $R/5 # lattice spacing micrometers -variable a equal 0.5/5 -variable Lf equal $R*3 -variable Lf equal 0.5*3 -variable Lb equal $R*4 -variable Lb equal 0.5*4 -variable wall_velocity equal 0.01 # micrometers/microsecond -variable T equal 300. -variable rho_0 equal 1. # density picograms/micrometer^3 -variable c_0 equal 100. # speed of sound micrometers/microsecond -variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) -variable h equal $a*4.5 # kernel function cutoff micrometers -variable h equal 0.1*4.5 -variable mass equal $a*$a*$a*${rho_0} -variable mass equal 0.1*$a*$a*${rho_0} -variable mass equal 0.1*0.1*$a*${rho_0} -variable mass equal 0.1*0.1*0.1*${rho_0} -variable mass equal 0.1*0.1*0.1*1 -variable dt equal 1e-3 # timestep microseconds -variable skin equal 0.2*$h -variable skin equal 0.2*0.45 - -region box block -${Lb} ${Lb} -${Lb} ${Lb} 0 ${a} units box -region box block -2 ${Lb} -${Lb} ${Lb} 0 ${a} units box -region box block -2 2 -${Lb} ${Lb} 0 ${a} units box -region box block -2 2 -2 ${Lb} 0 ${a} units box -region box block -2 2 -2 2 0 ${a} units box -region box block -2 2 -2 2 0 0.1 units box -create_box 4 box -Created orthogonal box = (-2 -2 0) to (2 2 0.1) - 1 by 1 by 1 MPI processor grid -lattice sq $a -lattice sq 0.1 -Lattice spacing in x,y,z = 0.1 0.1 0.1 - -create_atoms 1 box -Created 1600 atoms - Time spent = 0.00169706 secs - -region sphere sphere 0 0 0 $R units box -region sphere sphere 0 0 0 0.5 units box -set region sphere type 2 - 81 settings made for type - -region upper_wall block INF INF +${Lf} INF INF INF units box -region upper_wall block INF INF +1.5 INF INF INF units box -set region upper_wall type 3 - 200 settings made for type - -region lower_wall block INF INF INF -${Lf} INF INF units box -region lower_wall block INF INF INF -1.5 INF INF units box -set region lower_wall type 4 - 240 settings made for type - -group fluid type 1 -1079 atoms in group fluid -group sphere type 2 -81 atoms in group sphere -group upper_wall type 3 -200 atoms in group upper_wall -group lower_wall type 4 -240 atoms in group lower_wall - -mass * ${mass} -mass * 0.001 -set group all meso/rho ${rho_0} -set group all meso/rho 1 - 1600 settings made for meso/rho - -pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed -pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 -pair_style sdpd/taitwater/isothermal 300 1 76787 -pair_coeff * * ${rho_0} ${c_0} ${h} -pair_coeff * * 1 ${c_0} ${h} -pair_coeff * * 1 100 ${h} -pair_coeff * * 1 100 0.45 - -fix 1 fluid meso -fix 2 sphere rigid/meso single -1 rigid bodies with 81 atoms -fix 3 upper_wall meso/move linear +${wall_velocity} 0 0 units box -fix 3 upper_wall meso/move linear +0.01 0 0 units box -fix 4 lower_wall meso/move linear -${wall_velocity} 0 0 units box -fix 4 lower_wall meso/move linear -0.01 0 0 units box - -fix 2d all enforce2d - -neighbor ${skin} bin -neighbor 0.09 bin -neigh_modify delay 0 every 1 check yes -timestep ${dt} -timestep 0.001 - -dump dump_id all atom 100 dump.lammpstrj - -thermo 100 -thermo_style custom step time nbuild ndanger - -run 10000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 0.54 - ghost atom cutoff = 0.54 - binsize = 0.27, bins = 15 15 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair sdpd/taitwater/isothermal, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 6.937 | 6.937 | 6.937 Mbytes -Step Time Nbuild Ndanger - 0 0 0 0 - 100 0.1 0 0 - 200 0.2 0 0 - 300 0.3 0 0 - 400 0.4 0 0 - 500 0.5 1 0 - 600 0.6 1 0 - 700 0.7 2 0 - 800 0.8 2 0 - 900 0.9 2 0 - 1000 1 3 0 - 1100 1.1 3 0 - 1200 1.2 3 0 - 1300 1.3 4 0 - 1400 1.4 4 0 - 1500 1.5 4 0 - 1600 1.6 5 0 - 1700 1.7 5 0 - 1800 1.8 5 0 - 1900 1.9 6 0 - 2000 2 6 0 - 2100 2.1 6 0 - 2200 2.2 7 0 - 2300 2.3 7 0 - 2400 2.4 7 0 - 2500 2.5 8 0 - 2600 2.6 8 0 - 2700 2.7 8 0 - 2800 2.8 9 0 - 2900 2.9 9 0 - 3000 3 9 0 - 3100 3.1 10 0 - 3200 3.2 10 0 - 3300 3.3 10 0 - 3400 3.4 11 0 - 3500 3.5 11 0 - 3600 3.6 11 0 - 3700 3.7 12 0 - 3800 3.8 12 0 - 3900 3.9 12 0 - 4000 4 13 0 - 4100 4.1 13 0 - 4200 4.2 14 0 - 4300 4.3 14 0 - 4400 4.4 14 0 - 4500 4.5 15 0 - 4600 4.6 15 0 - 4700 4.7 15 0 - 4800 4.8 16 0 - 4900 4.9 16 0 - 5000 5 16 0 - 5100 5.1 17 0 - 5200 5.2 17 0 - 5300 5.3 17 0 - 5400 5.4 17 0 - 5500 5.5 18 0 - 5600 5.6 18 0 - 5700 5.7 19 0 - 5800 5.8 19 0 - 5900 5.9 19 0 - 6000 6 20 0 - 6100 6.1 20 0 - 6200 6.2 21 0 - 6300 6.3 21 0 - 6400 6.4 21 0 - 6500 6.5 22 0 - 6600 6.6 22 0 - 6700 6.7 22 0 - 6800 6.8 23 0 - 6900 6.9 23 0 - 7000 7 23 0 - 7100 7.1 24 0 - 7200 7.2 24 0 - 7300 7.3 25 0 - 7400 7.4 25 0 - 7500 7.5 25 0 - 7600 7.6 26 0 - 7700 7.7 26 0 - 7800 7.8 26 0 - 7900 7.9 27 0 - 8000 8 27 0 - 8100 8.1 27 0 - 8200 8.2 28 0 - 8300 8.3 28 0 - 8400 8.4 28 0 - 8500 8.5 29 0 - 8600 8.6 29 0 - 8700 8.7 30 0 - 8800 8.8 30 0 - 8900 8.9 30 0 - 9000 9 31 0 - 9100 9.1 31 0 - 9200 9.2 31 0 - 9300 9.3 32 0 - 9400 9.4 32 0 - 9500 9.5 32 0 - 9600 9.6 33 0 - 9700 9.7 33 0 - 9800 9.8 33 0 - 9900 9.9 34 0 - 10000 10 34 0 -Loop time of 144.208 on 1 procs for 10000 steps with 1600 atoms - -Performance: 5991348.580 ns/day, 0.000 hours/ns, 69.344 timesteps/s -99.7% CPU use with 1 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 143.08 | 143.08 | 143.08 | 0.0 | 99.22 -Neigh | 0.033195 | 0.033195 | 0.033195 | 0.0 | 0.02 -Comm | 0.24139 | 0.24139 | 0.24139 | 0.0 | 0.17 -Output | 0.11687 | 0.11687 | 0.11687 | 0.0 | 0.08 -Modify | 0.61566 | 0.61566 | 0.61566 | 0.0 | 0.43 -Other | | 0.117 | | | 0.08 - -Nlocal: 1600 ave 1600 max 1600 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 993 ave 993 max 993 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 73236 ave 73236 max 73236 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 73236 -Ave neighs/atom = 45.7725 -Neighbor list builds = 34 -Dangerous builds = 0 -Total wall time: 0:02:24 diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.4 b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.4 deleted file mode 100644 index 77823e00fc..0000000000 --- a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.24Oct18.2d-diffusion-in-shear-flow.g++.4 +++ /dev/null @@ -1,247 +0,0 @@ -LAMMPS (24 Oct 2018) -dimension 2 -units micro -atom_style meso - -variable R equal 0.5 # radius of sphere micrometers -variable a equal $R/5 # lattice spacing micrometers -variable a equal 0.5/5 -variable Lf equal $R*3 -variable Lf equal 0.5*3 -variable Lb equal $R*4 -variable Lb equal 0.5*4 -variable wall_velocity equal 0.01 # micrometers/microsecond -variable T equal 300. -variable rho_0 equal 1. # density picograms/micrometer^3 -variable c_0 equal 100. # speed of sound micrometers/microsecond -variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) -variable h equal $a*4.5 # kernel function cutoff micrometers -variable h equal 0.1*4.5 -variable mass equal $a*$a*$a*${rho_0} -variable mass equal 0.1*$a*$a*${rho_0} -variable mass equal 0.1*0.1*$a*${rho_0} -variable mass equal 0.1*0.1*0.1*${rho_0} -variable mass equal 0.1*0.1*0.1*1 -variable dt equal 1e-3 # timestep microseconds -variable skin equal 0.2*$h -variable skin equal 0.2*0.45 - -region box block -${Lb} ${Lb} -${Lb} ${Lb} 0 ${a} units box -region box block -2 ${Lb} -${Lb} ${Lb} 0 ${a} units box -region box block -2 2 -${Lb} ${Lb} 0 ${a} units box -region box block -2 2 -2 ${Lb} 0 ${a} units box -region box block -2 2 -2 2 0 ${a} units box -region box block -2 2 -2 2 0 0.1 units box -create_box 4 box -Created orthogonal box = (-2 -2 0) to (2 2 0.1) - 2 by 2 by 1 MPI processor grid -lattice sq $a -lattice sq 0.1 -Lattice spacing in x,y,z = 0.1 0.1 0.1 - -create_atoms 1 box -Created 1600 atoms - Time spent = 0.000589566 secs - -region sphere sphere 0 0 0 $R units box -region sphere sphere 0 0 0 0.5 units box -set region sphere type 2 - 81 settings made for type - -region upper_wall block INF INF +${Lf} INF INF INF units box -region upper_wall block INF INF +1.5 INF INF INF units box -set region upper_wall type 3 - 200 settings made for type - -region lower_wall block INF INF INF -${Lf} INF INF units box -region lower_wall block INF INF INF -1.5 INF INF units box -set region lower_wall type 4 - 240 settings made for type - -group fluid type 1 -1079 atoms in group fluid -group sphere type 2 -81 atoms in group sphere -group upper_wall type 3 -200 atoms in group upper_wall -group lower_wall type 4 -240 atoms in group lower_wall - -mass * ${mass} -mass * 0.001 -set group all meso/rho ${rho_0} -set group all meso/rho 1 - 1600 settings made for meso/rho - -pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed -pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 -pair_style sdpd/taitwater/isothermal 300 1 76787 -pair_coeff * * ${rho_0} ${c_0} ${h} -pair_coeff * * 1 ${c_0} ${h} -pair_coeff * * 1 100 ${h} -pair_coeff * * 1 100 0.45 - -fix 1 fluid meso -fix 2 sphere rigid/meso single -1 rigid bodies with 81 atoms -fix 3 upper_wall meso/move linear +${wall_velocity} 0 0 units box -fix 3 upper_wall meso/move linear +0.01 0 0 units box -fix 4 lower_wall meso/move linear -${wall_velocity} 0 0 units box -fix 4 lower_wall meso/move linear -0.01 0 0 units box - -fix 2d all enforce2d - -neighbor ${skin} bin -neighbor 0.09 bin -neigh_modify delay 0 every 1 check yes -timestep ${dt} -timestep 0.001 - -dump dump_id all atom 100 dump.lammpstrj - -thermo 100 -thermo_style custom step time nbuild ndanger - -run 10000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 0.54 - ghost atom cutoff = 0.54 - binsize = 0.27, bins = 15 15 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair sdpd/taitwater/isothermal, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 6.854 | 6.854 | 6.854 Mbytes -Step Time Nbuild Ndanger - 0 0 0 0 - 100 0.1 0 0 - 200 0.2 0 0 - 300 0.3 0 0 - 400 0.4 1 0 - 500 0.5 1 0 - 600 0.6 1 0 - 700 0.7 2 0 - 800 0.8 2 0 - 900 0.9 2 0 - 1000 1 3 0 - 1100 1.1 3 0 - 1200 1.2 4 0 - 1300 1.3 4 0 - 1400 1.4 4 0 - 1500 1.5 4 0 - 1600 1.6 5 0 - 1700 1.7 5 0 - 1800 1.8 5 0 - 1900 1.9 6 0 - 2000 2 6 0 - 2100 2.1 6 0 - 2200 2.2 6 0 - 2300 2.3 7 0 - 2400 2.4 7 0 - 2500 2.5 7 0 - 2600 2.6 8 0 - 2700 2.7 8 0 - 2800 2.8 8 0 - 2900 2.9 9 0 - 3000 3 9 0 - 3100 3.1 9 0 - 3200 3.2 10 0 - 3300 3.3 10 0 - 3400 3.4 10 0 - 3500 3.5 11 0 - 3600 3.6 11 0 - 3700 3.7 11 0 - 3800 3.8 12 0 - 3900 3.9 12 0 - 4000 4 12 0 - 4100 4.1 13 0 - 4200 4.2 13 0 - 4300 4.3 13 0 - 4400 4.4 14 0 - 4500 4.5 14 0 - 4600 4.6 15 0 - 4700 4.7 15 0 - 4800 4.8 15 0 - 4900 4.9 16 0 - 5000 5 16 0 - 5100 5.1 17 0 - 5200 5.2 17 0 - 5300 5.3 17 0 - 5400 5.4 17 0 - 5500 5.5 18 0 - 5600 5.6 18 0 - 5700 5.7 18 0 - 5800 5.8 19 0 - 5900 5.9 19 0 - 6000 6 20 0 - 6100 6.1 20 0 - 6200 6.2 20 0 - 6300 6.3 21 0 - 6400 6.4 21 0 - 6500 6.5 21 0 - 6600 6.6 22 0 - 6700 6.7 22 0 - 6800 6.8 22 0 - 6900 6.9 23 0 - 7000 7 23 0 - 7100 7.1 23 0 - 7200 7.2 24 0 - 7300 7.3 24 0 - 7400 7.4 25 0 - 7500 7.5 25 0 - 7600 7.6 25 0 - 7700 7.7 25 0 - 7800 7.8 26 0 - 7900 7.9 26 0 - 8000 8 26 0 - 8100 8.1 27 0 - 8200 8.2 27 0 - 8300 8.3 27 0 - 8400 8.4 28 0 - 8500 8.5 28 0 - 8600 8.6 28 0 - 8700 8.7 29 0 - 8800 8.8 29 0 - 8900 8.9 29 0 - 9000 9 30 0 - 9100 9.1 30 0 - 9200 9.2 31 0 - 9300 9.3 31 0 - 9400 9.4 31 0 - 9500 9.5 32 0 - 9600 9.6 32 0 - 9700 9.7 32 0 - 9800 9.8 32 0 - 9900 9.9 33 0 - 10000 10 33 0 -Loop time of 63.2372 on 4 procs for 10000 steps with 1600 atoms - -Performance: 13662841.706 ns/day, 0.000 hours/ns, 158.135 timesteps/s -94.3% CPU use with 4 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 51.576 | 53.662 | 55.484 | 23.9 | 84.86 -Neigh | 0.011519 | 0.012395 | 0.013405 | 0.7 | 0.02 -Comm | 6.8389 | 8.5423 | 10.517 | 56.1 | 13.51 -Output | 0.12342 | 0.12513 | 0.1302 | 0.8 | 0.20 -Modify | 0.58708 | 0.69128 | 0.78806 | 11.3 | 1.09 -Other | | 0.2038 | | | 0.32 - -Nlocal: 400 ave 411 max 388 min -Histogram: 1 1 0 0 0 0 0 0 0 2 -Nghost: 552.25 ave 567 max 539 min -Histogram: 2 0 0 0 0 0 0 0 1 1 -Neighs: 18298.8 ave 18781 max 17829 min -Histogram: 2 0 0 0 0 0 0 0 0 2 - -Total # of neighbors = 73195 -Ave neighs/atom = 45.7469 -Neighbor list builds = 33 -Dangerous builds = 0 -Total wall time: 0:01:03 diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.1 b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.1 new file mode 100644 index 0000000000..c4c11205e1 --- /dev/null +++ b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.1 @@ -0,0 +1,253 @@ +LAMMPS (28 Mar 2023 - Development) +dimension 2 +units micro +atom_style sph + +variable R equal 0.5 # radius of sphere micrometers +variable a equal $R/5 # lattice spacing micrometers +variable a equal 0.5/5 +variable Lf equal $R*3 +variable Lf equal 0.5*3 +variable Lb equal $R*4 +variable Lb equal 0.5*4 +variable wall_velocity equal 0.01 # micrometers/microsecond +variable T equal 300. +variable rho_0 equal 1. # density picograms/micrometer^3 +variable c_0 equal 100. # speed of sound micrometers/microsecond +variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) +variable h equal $a*4.5 # kernel function cutoff micrometers +variable h equal 0.1*4.5 +variable mass equal $a*$a*$a*${rho_0} +variable mass equal 0.1*$a*$a*${rho_0} +variable mass equal 0.1*0.1*$a*${rho_0} +variable mass equal 0.1*0.1*0.1*${rho_0} +variable mass equal 0.1*0.1*0.1*1 +variable dt equal 1e-3 # timestep microseconds +variable skin equal 0.2*$h +variable skin equal 0.2*0.45 + +region box block -${Lb} ${Lb} -${Lb} ${Lb} 0 ${a} units box +region box block -2 ${Lb} -${Lb} ${Lb} 0 ${a} units box +region box block -2 2 -${Lb} ${Lb} 0 ${a} units box +region box block -2 2 -2 ${Lb} 0 ${a} units box +region box block -2 2 -2 2 0 ${a} units box +region box block -2 2 -2 2 0 0.1 units box +create_box 4 box +Created orthogonal box = (-2 -2 0) to (2 2 0.1) + 1 by 1 by 1 MPI processor grid +lattice sq $a +lattice sq 0.1 +Lattice spacing in x,y,z = 0.1 0.1 0.1 + +create_atoms 1 box +Created 1600 atoms + using lattice units in orthogonal box = (-2 -2 0) to (2 2 0.1) + create_atoms CPU = 0.001 seconds + +region sphere sphere 0 0 0 $R units box +region sphere sphere 0 0 0 0.5 units box +set region sphere type 2 +Setting atom values ... + 81 settings made for type + +region upper_wall block INF INF +${Lf} INF INF INF units box +region upper_wall block INF INF +1.5 INF INF INF units box +set region upper_wall type 3 +Setting atom values ... + 200 settings made for type + +region lower_wall block INF INF INF -${Lf} INF INF units box +region lower_wall block INF INF INF -1.5 INF INF units box +set region lower_wall type 4 +Setting atom values ... + 240 settings made for type + +group fluid type 1 +1079 atoms in group fluid +group sphere type 2 +81 atoms in group sphere +group upper_wall type 3 +200 atoms in group upper_wall +group lower_wall type 4 +240 atoms in group lower_wall + +mass * ${mass} +mass * 0.001 +set group all sph/rho ${rho_0} +set group all sph/rho 1 +Setting atom values ... + 1600 settings made for sph/rho + +pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed +pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 +pair_style sdpd/taitwater/isothermal 300 1 76787 +pair_coeff * * ${rho_0} ${c_0} ${h} +pair_coeff * * 1 ${c_0} ${h} +pair_coeff * * 1 100 ${h} +pair_coeff * * 1 100 0.45 + +fix 1 fluid sph +fix 2 sphere rigid/meso single + 1 rigid bodies with 81 atoms +fix 3 upper_wall meso/move linear +${wall_velocity} 0 0 units box +fix 3 upper_wall meso/move linear +0.01 0 0 units box +fix 4 lower_wall meso/move linear -${wall_velocity} 0 0 units box +fix 4 lower_wall meso/move linear -0.01 0 0 units box + +fix 2d all enforce2d + +neighbor ${skin} bin +neighbor 0.09 bin +neigh_modify delay 0 every 1 check yes +timestep ${dt} +timestep 0.001 + +dump dump_id all atom 100 dump.lammpstrj + +thermo 100 +thermo_style custom step time nbuild ndanger + +run 10000 +Generated 0 of 6 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0.54 + ghost atom cutoff = 0.54 + binsize = 0.27, bins = 15 15 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair sdpd/taitwater/isothermal, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 7.313 | 7.313 | 7.313 Mbytes + Step Time Nbuild Ndanger + 0 0 0 0 + 100 0.1 0 0 + 200 0.2 0 0 + 300 0.3 0 0 + 400 0.4 0 0 + 500 0.5 1 0 + 600 0.6 1 0 + 700 0.7 2 0 + 800 0.8 2 0 + 900 0.9 2 0 + 1000 1 3 0 + 1100 1.1 3 0 + 1200 1.2 3 0 + 1300 1.3 4 0 + 1400 1.4 4 0 + 1500 1.5 4 0 + 1600 1.6 5 0 + 1700 1.7 5 0 + 1800 1.8 5 0 + 1900 1.9 6 0 + 2000 2 6 0 + 2100 2.1 6 0 + 2200 2.2 7 0 + 2300 2.3 7 0 + 2400 2.4 7 0 + 2500 2.5 8 0 + 2600 2.6 8 0 + 2700 2.7 8 0 + 2800 2.8 9 0 + 2900 2.9 9 0 + 3000 3 9 0 + 3100 3.1 10 0 + 3200 3.2 10 0 + 3300 3.3 10 0 + 3400 3.4 11 0 + 3500 3.5 11 0 + 3600 3.6 11 0 + 3700 3.7 12 0 + 3800 3.8 12 0 + 3900 3.9 12 0 + 4000 4 13 0 + 4100 4.1 13 0 + 4200 4.2 14 0 + 4300 4.3 14 0 + 4400 4.4 14 0 + 4500 4.5 15 0 + 4600 4.6 15 0 + 4700 4.7 15 0 + 4800 4.8 16 0 + 4900 4.9 16 0 + 5000 5 16 0 + 5100 5.1 17 0 + 5200 5.2 17 0 + 5300 5.3 17 0 + 5400 5.4 17 0 + 5500 5.5 18 0 + 5600 5.6 18 0 + 5700 5.7 19 0 + 5800 5.8 19 0 + 5900 5.9 19 0 + 6000 6 20 0 + 6100 6.1 20 0 + 6200 6.2 21 0 + 6300 6.3 21 0 + 6400 6.4 21 0 + 6500 6.5 22 0 + 6600 6.6 22 0 + 6700 6.7 22 0 + 6800 6.8 23 0 + 6900 6.9 23 0 + 7000 7 23 0 + 7100 7.1 24 0 + 7200 7.2 24 0 + 7300 7.3 25 0 + 7400 7.4 25 0 + 7500 7.5 25 0 + 7600 7.6 26 0 + 7700 7.7 26 0 + 7800 7.8 26 0 + 7900 7.9 27 0 + 8000 8 27 0 + 8100 8.1 27 0 + 8200 8.2 28 0 + 8300 8.3 28 0 + 8400 8.4 28 0 + 8500 8.5 29 0 + 8600 8.6 29 0 + 8700 8.7 30 0 + 8800 8.8 30 0 + 8900 8.9 30 0 + 9000 9 31 0 + 9100 9.1 31 0 + 9200 9.2 31 0 + 9300 9.3 32 0 + 9400 9.4 32 0 + 9500 9.5 32 0 + 9600 9.6 33 0 + 9700 9.7 33 0 + 9800 9.8 33 0 + 9900 9.9 34 0 + 10000 10 34 0 +Loop time of 131.724 on 1 procs for 10000 steps with 1600 atoms + +Performance: 6559168.339 ns/day, 0.000 hours/ns, 75.916 timesteps/s, 121.466 katom-step/s +99.7% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 130.89 | 130.89 | 130.89 | 0.0 | 99.37 +Neigh | 0.02884 | 0.02884 | 0.02884 | 0.0 | 0.02 +Comm | 0.17863 | 0.17863 | 0.17863 | 0.0 | 0.14 +Output | 0.095497 | 0.095497 | 0.095497 | 0.0 | 0.07 +Modify | 0.42063 | 0.42063 | 0.42063 | 0.0 | 0.32 +Other | | 0.1069 | | | 0.08 + +Nlocal: 1600 ave 1600 max 1600 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 993 ave 993 max 993 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 73236 ave 73236 max 73236 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 73236 +Ave neighs/atom = 45.7725 +Neighbor list builds = 34 +Dangerous builds = 0 +Total wall time: 0:02:11 diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.4 b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.4 new file mode 100644 index 0000000000..6cb58bc233 --- /dev/null +++ b/examples/PACKAGES/dpd-smooth/2d-diffusion-in-shear-flow/log.28Mar23.2d-diffusion-in-shear-flow.g++.4 @@ -0,0 +1,253 @@ +LAMMPS (28 Mar 2023 - Development) +dimension 2 +units micro +atom_style sph + +variable R equal 0.5 # radius of sphere micrometers +variable a equal $R/5 # lattice spacing micrometers +variable a equal 0.5/5 +variable Lf equal $R*3 +variable Lf equal 0.5*3 +variable Lb equal $R*4 +variable Lb equal 0.5*4 +variable wall_velocity equal 0.01 # micrometers/microsecond +variable T equal 300. +variable rho_0 equal 1. # density picograms/micrometer^3 +variable c_0 equal 100. # speed of sound micrometers/microsecond +variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) +variable h equal $a*4.5 # kernel function cutoff micrometers +variable h equal 0.1*4.5 +variable mass equal $a*$a*$a*${rho_0} +variable mass equal 0.1*$a*$a*${rho_0} +variable mass equal 0.1*0.1*$a*${rho_0} +variable mass equal 0.1*0.1*0.1*${rho_0} +variable mass equal 0.1*0.1*0.1*1 +variable dt equal 1e-3 # timestep microseconds +variable skin equal 0.2*$h +variable skin equal 0.2*0.45 + +region box block -${Lb} ${Lb} -${Lb} ${Lb} 0 ${a} units box +region box block -2 ${Lb} -${Lb} ${Lb} 0 ${a} units box +region box block -2 2 -${Lb} ${Lb} 0 ${a} units box +region box block -2 2 -2 ${Lb} 0 ${a} units box +region box block -2 2 -2 2 0 ${a} units box +region box block -2 2 -2 2 0 0.1 units box +create_box 4 box +Created orthogonal box = (-2 -2 0) to (2 2 0.1) + 2 by 2 by 1 MPI processor grid +lattice sq $a +lattice sq 0.1 +Lattice spacing in x,y,z = 0.1 0.1 0.1 + +create_atoms 1 box +Created 1600 atoms + using lattice units in orthogonal box = (-2 -2 0) to (2 2 0.1) + create_atoms CPU = 0.001 seconds + +region sphere sphere 0 0 0 $R units box +region sphere sphere 0 0 0 0.5 units box +set region sphere type 2 +Setting atom values ... + 81 settings made for type + +region upper_wall block INF INF +${Lf} INF INF INF units box +region upper_wall block INF INF +1.5 INF INF INF units box +set region upper_wall type 3 +Setting atom values ... + 200 settings made for type + +region lower_wall block INF INF INF -${Lf} INF INF units box +region lower_wall block INF INF INF -1.5 INF INF units box +set region lower_wall type 4 +Setting atom values ... + 240 settings made for type + +group fluid type 1 +1079 atoms in group fluid +group sphere type 2 +81 atoms in group sphere +group upper_wall type 3 +200 atoms in group upper_wall +group lower_wall type 4 +240 atoms in group lower_wall + +mass * ${mass} +mass * 0.001 +set group all sph/rho ${rho_0} +set group all sph/rho 1 +Setting atom values ... + 1600 settings made for sph/rho + +pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed +pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 +pair_style sdpd/taitwater/isothermal 300 1 76787 +pair_coeff * * ${rho_0} ${c_0} ${h} +pair_coeff * * 1 ${c_0} ${h} +pair_coeff * * 1 100 ${h} +pair_coeff * * 1 100 0.45 + +fix 1 fluid sph +fix 2 sphere rigid/meso single + 1 rigid bodies with 81 atoms +fix 3 upper_wall meso/move linear +${wall_velocity} 0 0 units box +fix 3 upper_wall meso/move linear +0.01 0 0 units box +fix 4 lower_wall meso/move linear -${wall_velocity} 0 0 units box +fix 4 lower_wall meso/move linear -0.01 0 0 units box + +fix 2d all enforce2d + +neighbor ${skin} bin +neighbor 0.09 bin +neigh_modify delay 0 every 1 check yes +timestep ${dt} +timestep 0.001 + +dump dump_id all atom 100 dump.lammpstrj + +thermo 100 +thermo_style custom step time nbuild ndanger + +run 10000 +Generated 0 of 6 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0.54 + ghost atom cutoff = 0.54 + binsize = 0.27, bins = 15 15 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair sdpd/taitwater/isothermal, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 7.23 | 7.23 | 7.23 Mbytes + Step Time Nbuild Ndanger + 0 0 0 0 + 100 0.1 0 0 + 200 0.2 0 0 + 300 0.3 0 0 + 400 0.4 1 0 + 500 0.5 1 0 + 600 0.6 1 0 + 700 0.7 2 0 + 800 0.8 2 0 + 900 0.9 2 0 + 1000 1 3 0 + 1100 1.1 3 0 + 1200 1.2 3 0 + 1300 1.3 4 0 + 1400 1.4 4 0 + 1500 1.5 4 0 + 1600 1.6 5 0 + 1700 1.7 5 0 + 1800 1.8 5 0 + 1900 1.9 6 0 + 2000 2 6 0 + 2100 2.1 6 0 + 2200 2.2 7 0 + 2300 2.3 7 0 + 2400 2.4 7 0 + 2500 2.5 8 0 + 2600 2.6 8 0 + 2700 2.7 8 0 + 2800 2.8 9 0 + 2900 2.9 9 0 + 3000 3 9 0 + 3100 3.1 10 0 + 3200 3.2 10 0 + 3300 3.3 10 0 + 3400 3.4 11 0 + 3500 3.5 11 0 + 3600 3.6 11 0 + 3700 3.7 12 0 + 3800 3.8 12 0 + 3900 3.9 12 0 + 4000 4 13 0 + 4100 4.1 13 0 + 4200 4.2 13 0 + 4300 4.3 14 0 + 4400 4.4 14 0 + 4500 4.5 14 0 + 4600 4.6 14 0 + 4700 4.7 15 0 + 4800 4.8 15 0 + 4900 4.9 16 0 + 5000 5 16 0 + 5100 5.1 16 0 + 5200 5.2 17 0 + 5300 5.3 17 0 + 5400 5.4 17 0 + 5500 5.5 18 0 + 5600 5.6 18 0 + 5700 5.7 18 0 + 5800 5.8 19 0 + 5900 5.9 19 0 + 6000 6 20 0 + 6100 6.1 20 0 + 6200 6.2 20 0 + 6300 6.3 21 0 + 6400 6.4 21 0 + 6500 6.5 21 0 + 6600 6.6 22 0 + 6700 6.7 22 0 + 6800 6.8 22 0 + 6900 6.9 23 0 + 7000 7 23 0 + 7100 7.1 23 0 + 7200 7.2 24 0 + 7300 7.3 24 0 + 7400 7.4 24 0 + 7500 7.5 25 0 + 7600 7.6 25 0 + 7700 7.7 25 0 + 7800 7.8 25 0 + 7900 7.9 26 0 + 8000 8 26 0 + 8100 8.1 26 0 + 8200 8.2 27 0 + 8300 8.3 27 0 + 8400 8.4 28 0 + 8500 8.5 28 0 + 8600 8.6 28 0 + 8700 8.7 29 0 + 8800 8.8 29 0 + 8900 8.9 29 0 + 9000 9 30 0 + 9100 9.1 30 0 + 9200 9.2 30 0 + 9300 9.3 31 0 + 9400 9.4 31 0 + 9500 9.5 31 0 + 9600 9.6 32 0 + 9700 9.7 32 0 + 9800 9.8 32 0 + 9900 9.9 32 0 + 10000 10 33 0 +Loop time of 24.8261 on 4 procs for 10000 steps with 1600 atoms + +Performance: 34802055.618 ns/day, 0.000 hours/ns, 402.802 timesteps/s, 644.483 katom-step/s +99.1% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 21.84 | 22.879 | 23.944 | 21.4 | 92.16 +Neigh | 0.007446 | 0.0079435 | 0.0084435 | 0.6 | 0.03 +Comm | 0.5271 | 1.5894 | 2.6259 | 80.9 | 6.40 +Output | 0.034799 | 0.035302 | 0.036437 | 0.4 | 0.14 +Modify | 0.20079 | 0.21033 | 0.2202 | 1.7 | 0.85 +Other | | 0.1041 | | | 0.42 + +Nlocal: 400 ave 414 max 390 min +Histogram: 2 0 0 0 0 1 0 0 0 1 +Nghost: 555.5 ave 564 max 543 min +Histogram: 1 0 0 0 1 0 0 0 0 2 +Neighs: 18299.2 ave 18820 max 17906 min +Histogram: 1 1 0 0 0 0 1 0 0 1 + +Total # of neighbors = 73197 +Ave neighs/atom = 45.748125 +Neighbor list builds = 33 +Dangerous builds = 0 +Total wall time: 0:00:24 diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion/in.lammps b/examples/PACKAGES/dpd-smooth/2d-diffusion/in.lammps index 6ef36a0cf6..2e0e821480 100644 --- a/examples/PACKAGES/dpd-smooth/2d-diffusion/in.lammps +++ b/examples/PACKAGES/dpd-smooth/2d-diffusion/in.lammps @@ -1,6 +1,6 @@ dimension 2 units micro -atom_style meso +atom_style sph variable R equal 0.5 # radius of sphere micrometers variable a equal $R/5 # lattice spacing micrometers @@ -27,12 +27,12 @@ group fluid type 1 group sphere type 2 mass * ${mass} -set group all meso/rho ${rho_0} +set group all sph/rho ${rho_0} pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed pair_coeff * * ${rho_0} ${c_0} ${h} -fix 1 fluid meso +fix 1 fluid sph fix 2 sphere rigid/meso single fix 2d all enforce2d diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.1 b/examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.1 deleted file mode 100644 index d44c0fd6f4..0000000000 --- a/examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.1 +++ /dev/null @@ -1,226 +0,0 @@ -LAMMPS (24 Oct 2018) -dimension 2 -units micro -atom_style meso - -variable R equal 0.5 # radius of sphere micrometers -variable a equal $R/5 # lattice spacing micrometers -variable a equal 0.5/5 -variable L equal $R*3 -variable L equal 0.5*3 -variable T equal 300. -variable rho_0 equal 1. # density picograms/micrometer^3 -variable c_0 equal 100. # speed of sound micrometers/microsecond -variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) -variable h equal $a*4.5 # kernel function cutoff micrometers -variable h equal 0.1*4.5 -variable mass equal $a*$a*$a*${rho_0} -variable mass equal 0.1*$a*$a*${rho_0} -variable mass equal 0.1*0.1*$a*${rho_0} -variable mass equal 0.1*0.1*0.1*${rho_0} -variable mass equal 0.1*0.1*0.1*1 -variable dt equal 1e-3 # timestep microseconds -variable skin equal 0.2*$h -variable skin equal 0.2*0.45 - -region box block -$L $L -$L $L 0 $a units box -region box block -1.5 $L -$L $L 0 $a units box -region box block -1.5 1.5 -$L $L 0 $a units box -region box block -1.5 1.5 -1.5 $L 0 $a units box -region box block -1.5 1.5 -1.5 1.5 0 $a units box -region box block -1.5 1.5 -1.5 1.5 0 0.1 units box -create_box 2 box -Created orthogonal box = (-1.5 -1.5 0) to (1.5 1.5 0.1) - 1 by 1 by 1 MPI processor grid -lattice sq $a -lattice sq 0.1 -Lattice spacing in x,y,z = 0.1 0.1 0.1 - -create_atoms 1 box -Created 900 atoms - Time spent = 0.0015769 secs - -region sphere sphere 0 0 0 $R units box -region sphere sphere 0 0 0 0.5 units box -set region sphere type 2 - 81 settings made for type - -group fluid type 1 -819 atoms in group fluid -group sphere type 2 -81 atoms in group sphere - -mass * ${mass} -mass * 0.001 -set group all meso/rho ${rho_0} -set group all meso/rho 1 - 900 settings made for meso/rho - -pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed -pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 -pair_style sdpd/taitwater/isothermal 300 1 76787 -pair_coeff * * ${rho_0} ${c_0} ${h} -pair_coeff * * 1 ${c_0} ${h} -pair_coeff * * 1 100 ${h} -pair_coeff * * 1 100 0.45 - -fix 1 fluid meso -fix 2 sphere rigid/meso single -1 rigid bodies with 81 atoms - -fix 2d all enforce2d - -neighbor ${skin} bin -neighbor 0.09 bin -neigh_modify delay 0 every 1 check yes -timestep ${dt} -timestep 0.001 - -dump dump_id all atom 100 dump.lammpstrj - -thermo 100 -thermo_style custom step time nbuild ndanger - -run 10000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 0.54 - ghost atom cutoff = 0.54 - binsize = 0.27, bins = 12 12 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair sdpd/taitwater/isothermal, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 6.137 | 6.137 | 6.137 Mbytes -Step Time Nbuild Ndanger - 0 0 0 0 - 100 0.1 0 0 - 200 0.2 0 0 - 300 0.3 0 0 - 400 0.4 1 0 - 500 0.5 1 0 - 600 0.6 1 0 - 700 0.7 2 0 - 800 0.8 2 0 - 900 0.9 2 0 - 1000 1 3 0 - 1100 1.1 3 0 - 1200 1.2 3 0 - 1300 1.3 4 0 - 1400 1.4 4 0 - 1500 1.5 4 0 - 1600 1.6 5 0 - 1700 1.7 5 0 - 1800 1.8 6 0 - 1900 1.9 6 0 - 2000 2 6 0 - 2100 2.1 7 0 - 2200 2.2 7 0 - 2300 2.3 7 0 - 2400 2.4 7 0 - 2500 2.5 8 0 - 2600 2.6 8 0 - 2700 2.7 8 0 - 2800 2.8 9 0 - 2900 2.9 9 0 - 3000 3 10 0 - 3100 3.1 10 0 - 3200 3.2 10 0 - 3300 3.3 11 0 - 3400 3.4 11 0 - 3500 3.5 11 0 - 3600 3.6 12 0 - 3700 3.7 12 0 - 3800 3.8 12 0 - 3900 3.9 13 0 - 4000 4 13 0 - 4100 4.1 13 0 - 4200 4.2 14 0 - 4300 4.3 14 0 - 4400 4.4 14 0 - 4500 4.5 15 0 - 4600 4.6 15 0 - 4700 4.7 15 0 - 4800 4.8 16 0 - 4900 4.9 16 0 - 5000 5 17 0 - 5100 5.1 17 0 - 5200 5.2 17 0 - 5300 5.3 17 0 - 5400 5.4 18 0 - 5500 5.5 18 0 - 5600 5.6 18 0 - 5700 5.7 19 0 - 5800 5.8 19 0 - 5900 5.9 19 0 - 6000 6 19 0 - 6100 6.1 20 0 - 6200 6.2 20 0 - 6300 6.3 20 0 - 6400 6.4 21 0 - 6500 6.5 21 0 - 6600 6.6 21 0 - 6700 6.7 21 0 - 6800 6.8 22 0 - 6900 6.9 22 0 - 7000 7 22 0 - 7100 7.1 23 0 - 7200 7.2 23 0 - 7300 7.3 23 0 - 7400 7.4 24 0 - 7500 7.5 24 0 - 7600 7.6 24 0 - 7700 7.7 25 0 - 7800 7.8 25 0 - 7900 7.9 26 0 - 8000 8 26 0 - 8100 8.1 26 0 - 8200 8.2 26 0 - 8300 8.3 27 0 - 8400 8.4 27 0 - 8500 8.5 27 0 - 8600 8.6 28 0 - 8700 8.7 28 0 - 8800 8.8 28 0 - 8900 8.9 29 0 - 9000 9 29 0 - 9100 9.1 29 0 - 9200 9.2 30 0 - 9300 9.3 30 0 - 9400 9.4 30 0 - 9500 9.5 30 0 - 9600 9.6 31 0 - 9700 9.7 31 0 - 9800 9.8 32 0 - 9900 9.9 32 0 - 10000 10 32 0 -Loop time of 80.9456 on 1 procs for 10000 steps with 900 atoms - -Performance: 10673829.855 ns/day, 0.000 hours/ns, 123.540 timesteps/s -99.8% CPU use with 1 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 80.306 | 80.306 | 80.306 | 0.0 | 99.21 -Neigh | 0.017418 | 0.017418 | 0.017418 | 0.0 | 0.02 -Comm | 0.16939 | 0.16939 | 0.16939 | 0.0 | 0.21 -Output | 0.070281 | 0.070281 | 0.070281 | 0.0 | 0.09 -Modify | 0.3154 | 0.3154 | 0.3154 | 0.0 | 0.39 -Other | | 0.067 | | | 0.08 - -Nlocal: 900 ave 900 max 900 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 762 ave 762 max 762 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 40697 ave 40697 max 40697 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 40697 -Ave neighs/atom = 45.2189 -Neighbor list builds = 32 -Dangerous builds = 0 -Total wall time: 0:01:20 diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.4 b/examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.4 deleted file mode 100644 index f904b78ab4..0000000000 --- a/examples/PACKAGES/dpd-smooth/2d-diffusion/log.24Oct18.2d-diffusion.g++.4 +++ /dev/null @@ -1,226 +0,0 @@ -LAMMPS (24 Oct 2018) -dimension 2 -units micro -atom_style meso - -variable R equal 0.5 # radius of sphere micrometers -variable a equal $R/5 # lattice spacing micrometers -variable a equal 0.5/5 -variable L equal $R*3 -variable L equal 0.5*3 -variable T equal 300. -variable rho_0 equal 1. # density picograms/micrometer^3 -variable c_0 equal 100. # speed of sound micrometers/microsecond -variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) -variable h equal $a*4.5 # kernel function cutoff micrometers -variable h equal 0.1*4.5 -variable mass equal $a*$a*$a*${rho_0} -variable mass equal 0.1*$a*$a*${rho_0} -variable mass equal 0.1*0.1*$a*${rho_0} -variable mass equal 0.1*0.1*0.1*${rho_0} -variable mass equal 0.1*0.1*0.1*1 -variable dt equal 1e-3 # timestep microseconds -variable skin equal 0.2*$h -variable skin equal 0.2*0.45 - -region box block -$L $L -$L $L 0 $a units box -region box block -1.5 $L -$L $L 0 $a units box -region box block -1.5 1.5 -$L $L 0 $a units box -region box block -1.5 1.5 -1.5 $L 0 $a units box -region box block -1.5 1.5 -1.5 1.5 0 $a units box -region box block -1.5 1.5 -1.5 1.5 0 0.1 units box -create_box 2 box -Created orthogonal box = (-1.5 -1.5 0) to (1.5 1.5 0.1) - 2 by 2 by 1 MPI processor grid -lattice sq $a -lattice sq 0.1 -Lattice spacing in x,y,z = 0.1 0.1 0.1 - -create_atoms 1 box -Created 900 atoms - Time spent = 0.0010246 secs - -region sphere sphere 0 0 0 $R units box -region sphere sphere 0 0 0 0.5 units box -set region sphere type 2 - 81 settings made for type - -group fluid type 1 -819 atoms in group fluid -group sphere type 2 -81 atoms in group sphere - -mass * ${mass} -mass * 0.001 -set group all meso/rho ${rho_0} -set group all meso/rho 1 - 900 settings made for meso/rho - -pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed -pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 -pair_style sdpd/taitwater/isothermal 300 1 76787 -pair_coeff * * ${rho_0} ${c_0} ${h} -pair_coeff * * 1 ${c_0} ${h} -pair_coeff * * 1 100 ${h} -pair_coeff * * 1 100 0.45 - -fix 1 fluid meso -fix 2 sphere rigid/meso single -1 rigid bodies with 81 atoms - -fix 2d all enforce2d - -neighbor ${skin} bin -neighbor 0.09 bin -neigh_modify delay 0 every 1 check yes -timestep ${dt} -timestep 0.001 - -dump dump_id all atom 100 dump.lammpstrj - -thermo 100 -thermo_style custom step time nbuild ndanger - -run 10000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 0.54 - ghost atom cutoff = 0.54 - binsize = 0.27, bins = 12 12 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair sdpd/taitwater/isothermal, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 6.087 | 6.087 | 6.087 Mbytes -Step Time Nbuild Ndanger - 0 0 0 0 - 100 0.1 0 0 - 200 0.2 0 0 - 300 0.3 0 0 - 400 0.4 1 0 - 500 0.5 1 0 - 600 0.6 1 0 - 700 0.7 2 0 - 800 0.8 2 0 - 900 0.9 2 0 - 1000 1 3 0 - 1100 1.1 3 0 - 1200 1.2 3 0 - 1300 1.3 4 0 - 1400 1.4 4 0 - 1500 1.5 5 0 - 1600 1.6 5 0 - 1700 1.7 5 0 - 1800 1.8 6 0 - 1900 1.9 6 0 - 2000 2 6 0 - 2100 2.1 7 0 - 2200 2.2 7 0 - 2300 2.3 7 0 - 2400 2.4 8 0 - 2500 2.5 8 0 - 2600 2.6 8 0 - 2700 2.7 9 0 - 2800 2.8 9 0 - 2900 2.9 9 0 - 3000 3 9 0 - 3100 3.1 10 0 - 3200 3.2 10 0 - 3300 3.3 10 0 - 3400 3.4 11 0 - 3500 3.5 11 0 - 3600 3.6 11 0 - 3700 3.7 12 0 - 3800 3.8 12 0 - 3900 3.9 12 0 - 4000 4 13 0 - 4100 4.1 13 0 - 4200 4.2 13 0 - 4300 4.3 14 0 - 4400 4.4 14 0 - 4500 4.5 15 0 - 4600 4.6 15 0 - 4700 4.7 15 0 - 4800 4.8 16 0 - 4900 4.9 16 0 - 5000 5 16 0 - 5100 5.1 16 0 - 5200 5.2 17 0 - 5300 5.3 17 0 - 5400 5.4 18 0 - 5500 5.5 18 0 - 5600 5.6 19 0 - 5700 5.7 19 0 - 5800 5.8 19 0 - 5900 5.9 20 0 - 6000 6 20 0 - 6100 6.1 20 0 - 6200 6.2 21 0 - 6300 6.3 21 0 - 6400 6.4 21 0 - 6500 6.5 22 0 - 6600 6.6 22 0 - 6700 6.7 22 0 - 6800 6.8 23 0 - 6900 6.9 23 0 - 7000 7 23 0 - 7100 7.1 24 0 - 7200 7.2 24 0 - 7300 7.3 24 0 - 7400 7.4 25 0 - 7500 7.5 25 0 - 7600 7.6 25 0 - 7700 7.7 26 0 - 7800 7.8 26 0 - 7900 7.9 26 0 - 8000 8 27 0 - 8100 8.1 27 0 - 8200 8.2 27 0 - 8300 8.3 28 0 - 8400 8.4 28 0 - 8500 8.5 28 0 - 8600 8.6 28 0 - 8700 8.7 29 0 - 8800 8.8 29 0 - 8900 8.9 29 0 - 9000 9 30 0 - 9100 9.1 30 0 - 9200 9.2 31 0 - 9300 9.3 31 0 - 9400 9.4 31 0 - 9500 9.5 31 0 - 9600 9.6 32 0 - 9700 9.7 32 0 - 9800 9.8 32 0 - 9900 9.9 33 0 - 10000 10 33 0 -Loop time of 69.01 on 4 procs for 10000 steps with 900 atoms - -Performance: 12519931.275 ns/day, 0.000 hours/ns, 144.907 timesteps/s -48.7% CPU use with 4 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 56.528 | 57.936 | 58.729 | 11.0 | 83.95 -Neigh | 0.013157 | 0.013382 | 0.013551 | 0.1 | 0.02 -Comm | 8.9594 | 9.7555 | 11.113 | 26.7 | 14.14 -Output | 0.14644 | 0.15009 | 0.15809 | 1.2 | 0.22 -Modify | 0.72913 | 0.91574 | 1.0524 | 12.4 | 1.33 -Other | | 0.2389 | | | 0.35 - -Nlocal: 225 ave 229 max 223 min -Histogram: 1 2 0 0 0 0 0 0 0 1 -Nghost: 442 ave 444 max 439 min -Histogram: 1 0 0 0 1 0 0 0 0 2 -Neighs: 10188.8 ave 10437 max 9932 min -Histogram: 1 0 0 1 0 0 0 1 0 1 - -Total # of neighbors = 40755 -Ave neighs/atom = 45.2833 -Neighbor list builds = 33 -Dangerous builds = 0 -Total wall time: 0:01:09 diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.1 b/examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.1 new file mode 100644 index 0000000000..30bf43dcf6 --- /dev/null +++ b/examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.1 @@ -0,0 +1,230 @@ +LAMMPS (28 Mar 2023 - Development) +dimension 2 +units micro +atom_style sph + +variable R equal 0.5 # radius of sphere micrometers +variable a equal $R/5 # lattice spacing micrometers +variable a equal 0.5/5 +variable L equal $R*3 +variable L equal 0.5*3 +variable T equal 300. +variable rho_0 equal 1. # density picograms/micrometer^3 +variable c_0 equal 100. # speed of sound micrometers/microsecond +variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) +variable h equal $a*4.5 # kernel function cutoff micrometers +variable h equal 0.1*4.5 +variable mass equal $a*$a*$a*${rho_0} +variable mass equal 0.1*$a*$a*${rho_0} +variable mass equal 0.1*0.1*$a*${rho_0} +variable mass equal 0.1*0.1*0.1*${rho_0} +variable mass equal 0.1*0.1*0.1*1 +variable dt equal 1e-3 # timestep microseconds +variable skin equal 0.2*$h +variable skin equal 0.2*0.45 + +region box block -$L $L -$L $L 0 $a units box +region box block -1.5 $L -$L $L 0 $a units box +region box block -1.5 1.5 -$L $L 0 $a units box +region box block -1.5 1.5 -1.5 $L 0 $a units box +region box block -1.5 1.5 -1.5 1.5 0 $a units box +region box block -1.5 1.5 -1.5 1.5 0 0.1 units box +create_box 2 box +Created orthogonal box = (-1.5 -1.5 0) to (1.5 1.5 0.1) + 1 by 1 by 1 MPI processor grid +lattice sq $a +lattice sq 0.1 +Lattice spacing in x,y,z = 0.1 0.1 0.1 + +create_atoms 1 box +Created 900 atoms + using lattice units in orthogonal box = (-1.5 -1.5 0) to (1.5 1.5 0.1) + create_atoms CPU = 0.001 seconds + +region sphere sphere 0 0 0 $R units box +region sphere sphere 0 0 0 0.5 units box +set region sphere type 2 +Setting atom values ... + 81 settings made for type + +group fluid type 1 +819 atoms in group fluid +group sphere type 2 +81 atoms in group sphere + +mass * ${mass} +mass * 0.001 +set group all sph/rho ${rho_0} +set group all sph/rho 1 +Setting atom values ... + 900 settings made for sph/rho + +pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed +pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 +pair_style sdpd/taitwater/isothermal 300 1 76787 +pair_coeff * * ${rho_0} ${c_0} ${h} +pair_coeff * * 1 ${c_0} ${h} +pair_coeff * * 1 100 ${h} +pair_coeff * * 1 100 0.45 + +fix 1 fluid sph +fix 2 sphere rigid/meso single + 1 rigid bodies with 81 atoms + +fix 2d all enforce2d + +neighbor ${skin} bin +neighbor 0.09 bin +neigh_modify delay 0 every 1 check yes +timestep ${dt} +timestep 0.001 + +dump dump_id all atom 100 dump.lammpstrj + +thermo 100 +thermo_style custom step time nbuild ndanger + +run 10000 +Generated 0 of 1 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0.54 + ghost atom cutoff = 0.54 + binsize = 0.27, bins = 12 12 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair sdpd/taitwater/isothermal, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 6.512 | 6.512 | 6.512 Mbytes + Step Time Nbuild Ndanger + 0 0 0 0 + 100 0.1 0 0 + 200 0.2 0 0 + 300 0.3 0 0 + 400 0.4 1 0 + 500 0.5 1 0 + 600 0.6 1 0 + 700 0.7 2 0 + 800 0.8 2 0 + 900 0.9 2 0 + 1000 1 3 0 + 1100 1.1 3 0 + 1200 1.2 3 0 + 1300 1.3 4 0 + 1400 1.4 4 0 + 1500 1.5 4 0 + 1600 1.6 5 0 + 1700 1.7 5 0 + 1800 1.8 6 0 + 1900 1.9 6 0 + 2000 2 6 0 + 2100 2.1 7 0 + 2200 2.2 7 0 + 2300 2.3 7 0 + 2400 2.4 7 0 + 2500 2.5 8 0 + 2600 2.6 8 0 + 2700 2.7 8 0 + 2800 2.8 9 0 + 2900 2.9 9 0 + 3000 3 10 0 + 3100 3.1 10 0 + 3200 3.2 10 0 + 3300 3.3 11 0 + 3400 3.4 11 0 + 3500 3.5 11 0 + 3600 3.6 12 0 + 3700 3.7 12 0 + 3800 3.8 12 0 + 3900 3.9 13 0 + 4000 4 13 0 + 4100 4.1 13 0 + 4200 4.2 14 0 + 4300 4.3 14 0 + 4400 4.4 14 0 + 4500 4.5 15 0 + 4600 4.6 15 0 + 4700 4.7 15 0 + 4800 4.8 16 0 + 4900 4.9 16 0 + 5000 5 17 0 + 5100 5.1 17 0 + 5200 5.2 17 0 + 5300 5.3 17 0 + 5400 5.4 18 0 + 5500 5.5 18 0 + 5600 5.6 18 0 + 5700 5.7 19 0 + 5800 5.8 19 0 + 5900 5.9 19 0 + 6000 6 19 0 + 6100 6.1 20 0 + 6200 6.2 20 0 + 6300 6.3 20 0 + 6400 6.4 21 0 + 6500 6.5 21 0 + 6600 6.6 21 0 + 6700 6.7 21 0 + 6800 6.8 22 0 + 6900 6.9 22 0 + 7000 7 22 0 + 7100 7.1 23 0 + 7200 7.2 23 0 + 7300 7.3 23 0 + 7400 7.4 24 0 + 7500 7.5 24 0 + 7600 7.6 24 0 + 7700 7.7 25 0 + 7800 7.8 25 0 + 7900 7.9 26 0 + 8000 8 26 0 + 8100 8.1 26 0 + 8200 8.2 26 0 + 8300 8.3 27 0 + 8400 8.4 27 0 + 8500 8.5 27 0 + 8600 8.6 28 0 + 8700 8.7 28 0 + 8800 8.8 28 0 + 8900 8.9 29 0 + 9000 9 29 0 + 9100 9.1 29 0 + 9200 9.2 30 0 + 9300 9.3 30 0 + 9400 9.4 30 0 + 9500 9.5 30 0 + 9600 9.6 31 0 + 9700 9.7 31 0 + 9800 9.8 32 0 + 9900 9.9 32 0 + 10000 10 32 0 +Loop time of 78.0094 on 1 procs for 10000 steps with 900 atoms + +Performance: 11075589.479 ns/day, 0.000 hours/ns, 128.190 timesteps/s, 115.371 katom-step/s +99.5% CPU use with 1 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 77.441 | 77.441 | 77.441 | 0.0 | 99.27 +Neigh | 0.016471 | 0.016471 | 0.016471 | 0.0 | 0.02 +Comm | 0.14821 | 0.14821 | 0.14821 | 0.0 | 0.19 +Output | 0.062415 | 0.062415 | 0.062415 | 0.0 | 0.08 +Modify | 0.25323 | 0.25323 | 0.25323 | 0.0 | 0.32 +Other | | 0.0877 | | | 0.11 + +Nlocal: 900 ave 900 max 900 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 762 ave 762 max 762 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 40697 ave 40697 max 40697 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 40697 +Ave neighs/atom = 45.218889 +Neighbor list builds = 32 +Dangerous builds = 0 +Total wall time: 0:01:18 diff --git a/examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.4 b/examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.4 new file mode 100644 index 0000000000..03f5ed01bb --- /dev/null +++ b/examples/PACKAGES/dpd-smooth/2d-diffusion/log.28Mar23.2d-diffusion.g++.4 @@ -0,0 +1,230 @@ +LAMMPS (28 Mar 2023 - Development) +dimension 2 +units micro +atom_style sph + +variable R equal 0.5 # radius of sphere micrometers +variable a equal $R/5 # lattice spacing micrometers +variable a equal 0.5/5 +variable L equal $R*3 +variable L equal 0.5*3 +variable T equal 300. +variable rho_0 equal 1. # density picograms/micrometer^3 +variable c_0 equal 100. # speed of sound micrometers/microsecond +variable mu equal 1. # dynamic viscosity picogram/(micrometer-microsecond) +variable h equal $a*4.5 # kernel function cutoff micrometers +variable h equal 0.1*4.5 +variable mass equal $a*$a*$a*${rho_0} +variable mass equal 0.1*$a*$a*${rho_0} +variable mass equal 0.1*0.1*$a*${rho_0} +variable mass equal 0.1*0.1*0.1*${rho_0} +variable mass equal 0.1*0.1*0.1*1 +variable dt equal 1e-3 # timestep microseconds +variable skin equal 0.2*$h +variable skin equal 0.2*0.45 + +region box block -$L $L -$L $L 0 $a units box +region box block -1.5 $L -$L $L 0 $a units box +region box block -1.5 1.5 -$L $L 0 $a units box +region box block -1.5 1.5 -1.5 $L 0 $a units box +region box block -1.5 1.5 -1.5 1.5 0 $a units box +region box block -1.5 1.5 -1.5 1.5 0 0.1 units box +create_box 2 box +Created orthogonal box = (-1.5 -1.5 0) to (1.5 1.5 0.1) + 2 by 2 by 1 MPI processor grid +lattice sq $a +lattice sq 0.1 +Lattice spacing in x,y,z = 0.1 0.1 0.1 + +create_atoms 1 box +Created 900 atoms + using lattice units in orthogonal box = (-1.5 -1.5 0) to (1.5 1.5 0.1) + create_atoms CPU = 0.001 seconds + +region sphere sphere 0 0 0 $R units box +region sphere sphere 0 0 0 0.5 units box +set region sphere type 2 +Setting atom values ... + 81 settings made for type + +group fluid type 1 +819 atoms in group fluid +group sphere type 2 +81 atoms in group sphere + +mass * ${mass} +mass * 0.001 +set group all sph/rho ${rho_0} +set group all sph/rho 1 +Setting atom values ... + 900 settings made for sph/rho + +pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed +pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 +pair_style sdpd/taitwater/isothermal 300 1 76787 +pair_coeff * * ${rho_0} ${c_0} ${h} +pair_coeff * * 1 ${c_0} ${h} +pair_coeff * * 1 100 ${h} +pair_coeff * * 1 100 0.45 + +fix 1 fluid sph +fix 2 sphere rigid/meso single + 1 rigid bodies with 81 atoms + +fix 2d all enforce2d + +neighbor ${skin} bin +neighbor 0.09 bin +neigh_modify delay 0 every 1 check yes +timestep ${dt} +timestep 0.001 + +dump dump_id all atom 100 dump.lammpstrj + +thermo 100 +thermo_style custom step time nbuild ndanger + +run 10000 +Generated 0 of 1 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 0.54 + ghost atom cutoff = 0.54 + binsize = 0.27, bins = 12 12 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair sdpd/taitwater/isothermal, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 6.463 | 6.463 | 6.463 Mbytes + Step Time Nbuild Ndanger + 0 0 0 0 + 100 0.1 0 0 + 200 0.2 0 0 + 300 0.3 0 0 + 400 0.4 1 0 + 500 0.5 1 0 + 600 0.6 1 0 + 700 0.7 2 0 + 800 0.8 2 0 + 900 0.9 2 0 + 1000 1 3 0 + 1100 1.1 3 0 + 1200 1.2 3 0 + 1300 1.3 4 0 + 1400 1.4 4 0 + 1500 1.5 4 0 + 1600 1.6 5 0 + 1700 1.7 5 0 + 1800 1.8 5 0 + 1900 1.9 6 0 + 2000 2 6 0 + 2100 2.1 6 0 + 2200 2.2 7 0 + 2300 2.3 7 0 + 2400 2.4 7 0 + 2500 2.5 8 0 + 2600 2.6 8 0 + 2700 2.7 8 0 + 2800 2.8 9 0 + 2900 2.9 9 0 + 3000 3 9 0 + 3100 3.1 10 0 + 3200 3.2 10 0 + 3300 3.3 11 0 + 3400 3.4 11 0 + 3500 3.5 11 0 + 3600 3.6 12 0 + 3700 3.7 12 0 + 3800 3.8 12 0 + 3900 3.9 12 0 + 4000 4 13 0 + 4100 4.1 13 0 + 4200 4.2 14 0 + 4300 4.3 14 0 + 4400 4.4 14 0 + 4500 4.5 15 0 + 4600 4.6 15 0 + 4700 4.7 15 0 + 4800 4.8 16 0 + 4900 4.9 16 0 + 5000 5 16 0 + 5100 5.1 17 0 + 5200 5.2 17 0 + 5300 5.3 17 0 + 5400 5.4 17 0 + 5500 5.5 18 0 + 5600 5.6 18 0 + 5700 5.7 18 0 + 5800 5.8 19 0 + 5900 5.9 19 0 + 6000 6 19 0 + 6100 6.1 20 0 + 6200 6.2 20 0 + 6300 6.3 20 0 + 6400 6.4 21 0 + 6500 6.5 21 0 + 6600 6.6 21 0 + 6700 6.7 22 0 + 6800 6.8 22 0 + 6900 6.9 22 0 + 7000 7 23 0 + 7100 7.1 23 0 + 7200 7.2 23 0 + 7300 7.3 24 0 + 7400 7.4 24 0 + 7500 7.5 24 0 + 7600 7.6 25 0 + 7700 7.7 25 0 + 7800 7.8 26 0 + 7900 7.9 26 0 + 8000 8 26 0 + 8100 8.1 26 0 + 8200 8.2 27 0 + 8300 8.3 27 0 + 8400 8.4 28 0 + 8500 8.5 28 0 + 8600 8.6 28 0 + 8700 8.7 29 0 + 8800 8.8 29 0 + 8900 8.9 29 0 + 9000 9 30 0 + 9100 9.1 30 0 + 9200 9.2 30 0 + 9300 9.3 30 0 + 9400 9.4 31 0 + 9500 9.5 31 0 + 9600 9.6 31 0 + 9700 9.7 32 0 + 9800 9.8 32 0 + 9900 9.9 32 0 + 10000 10 33 0 +Loop time of 13.5306 on 4 procs for 10000 steps with 900 atoms + +Performance: 63855371.888 ns/day, 0.000 hours/ns, 739.067 timesteps/s, 665.160 katom-step/s +98.8% CPU use with 4 MPI tasks x no OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 12.327 | 12.56 | 12.738 | 4.3 | 92.83 +Neigh | 0.0043391 | 0.0044297 | 0.0045381 | 0.1 | 0.03 +Comm | 0.53746 | 0.71463 | 0.94685 | 18.1 | 5.28 +Output | 0.021884 | 0.02228 | 0.023428 | 0.4 | 0.16 +Modify | 0.14457 | 0.14548 | 0.14643 | 0.2 | 1.08 +Other | | 0.08351 | | | 0.62 + +Nlocal: 225 ave 228 max 222 min +Histogram: 1 0 0 1 0 0 1 0 0 1 +Nghost: 438.25 ave 442 max 434 min +Histogram: 1 0 0 0 0 1 1 0 0 1 +Neighs: 10152.2 ave 10328 max 9853 min +Histogram: 1 0 0 0 0 0 0 1 1 1 + +Total # of neighbors = 40609 +Ave neighs/atom = 45.121111 +Neighbor list builds = 33 +Dangerous builds = 0 +Total wall time: 0:00:13 diff --git a/examples/PACKAGES/dpd-smooth/equipartition-verification/in.lammps b/examples/PACKAGES/dpd-smooth/equipartition-verification/in.lammps index 0d06723f59..59359d4b38 100644 --- a/examples/PACKAGES/dpd-smooth/equipartition-verification/in.lammps +++ b/examples/PACKAGES/dpd-smooth/equipartition-verification/in.lammps @@ -1,6 +1,6 @@ dimension 3 units micro -atom_style meso +atom_style sph variable a equal 0.1 # lattice spacing micrometers variable L equal $a*10 @@ -21,7 +21,7 @@ lattice sc $a create_atoms 1 box mass * ${mass} -set group all meso/rho ${rho_0} +set group all sph/rho ${rho_0} pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed pair_coeff * * ${rho_0} ${c_0} ${h} @@ -34,7 +34,7 @@ variable vx_sq_check equal c_v_sq[1]*${mass}/${kB}/$T variable vy_sq_check equal c_v_sq[2]*${mass}/${kB}/$T variable vz_sq_check equal c_v_sq[3]*${mass}/${kB}/$T -fix 1 all meso +fix 1 all sph neighbor ${skin} bin timestep ${dt} diff --git a/examples/PACKAGES/dpd-smooth/equipartition-verification/log.24Oct18.equipartition.g++.1 b/examples/PACKAGES/dpd-smooth/equipartition-verification/log.28Mar23.equipartition.g++.1 similarity index 58% rename from examples/PACKAGES/dpd-smooth/equipartition-verification/log.24Oct18.equipartition.g++.1 rename to examples/PACKAGES/dpd-smooth/equipartition-verification/log.28Mar23.equipartition.g++.1 index 06ffd699bc..2fa4771a74 100644 --- a/examples/PACKAGES/dpd-smooth/equipartition-verification/log.24Oct18.equipartition.g++.1 +++ b/examples/PACKAGES/dpd-smooth/equipartition-verification/log.28Mar23.equipartition.g++.1 @@ -1,7 +1,7 @@ -LAMMPS (24 Oct 2018) +LAMMPS (28 Mar 2023 - Development) dimension 3 units micro -atom_style meso +atom_style sph variable a equal 0.1 # lattice spacing micrometers variable L equal $a*10 @@ -38,13 +38,15 @@ Lattice spacing in x,y,z = 0.1 0.1 0.1 create_atoms 1 box Created 8000 atoms - Time spent = 0.00285411 secs + using lattice units in orthogonal box = (-1 -1 -1) to (1 1 1) + create_atoms CPU = 0.002 seconds mass * ${mass} mass * 0.001 -set group all meso/rho ${rho_0} -set group all meso/rho 1 - 8000 settings made for meso/rho +set group all sph/rho ${rho_0} +set group all sph/rho 1 +Setting atom values ... + 8000 settings made for sph/rho pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 @@ -71,7 +73,7 @@ variable vz_sq_check equal c_v_sq[3]*0.001/${kB}/$T variable vz_sq_check equal c_v_sq[3]*0.001/1.3806504e-08/$T variable vz_sq_check equal c_v_sq[3]*0.001/1.3806504e-08/300 -fix 1 all meso +fix 1 all sph neighbor ${skin} bin neighbor 0.04 bin @@ -82,8 +84,9 @@ thermo 10 thermo_style custom step time v_vx_sq_check v_vy_sq_check v_vz_sq_check run 200 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule Neighbor list info ... - update every 1 steps, delay 10 steps, check yes + update: every = 1 steps, delay = 0 steps, check = yes max neighbors/atom: 2000, page size: 100000 master list distance cutoff = 0.44 ghost atom cutoff = 0.44 @@ -92,55 +95,55 @@ Neighbor list info ... (1) pair sdpd/taitwater/isothermal, perpetual attributes: half, newton on pair build: half/bin/atomonly/newton - stencil: half/bin/3d/newton + stencil: half/bin/3d bin: standard -Per MPI rank memory allocation (min/avg/max) = 13.54 | 13.54 | 13.54 Mbytes -Step Time v_vx_sq_check v_vy_sq_check v_vz_sq_check - 0 0 0 0 0 - 10 0.005 0.70973271 0.71495693 0.71910087 - 20 0.01 0.90418096 0.88845437 0.89659567 - 30 0.015 0.9590736 0.97880338 0.9619016 - 40 0.02 0.98533774 0.96057682 0.95600448 - 50 0.025 0.96433662 0.96650071 0.95509683 - 60 0.03 0.96598029 0.96373656 0.96734888 - 70 0.035 0.95433045 0.98004764 0.96255924 - 80 0.04 0.97872906 0.95987289 0.96623598 - 90 0.045 0.99913888 0.99255731 0.95616142 - 100 0.05 0.98872675 0.97141018 0.95338841 - 110 0.055 0.97794592 0.97389258 0.98473719 - 120 0.06 0.98389266 0.96716284 0.95504862 - 130 0.065 0.98572886 0.96680923 0.95599065 - 140 0.07 0.97602684 0.97580081 0.9886878 - 150 0.075 0.99172003 0.95027467 0.96028033 - 160 0.08 0.96793247 0.94590928 0.95644301 - 170 0.085 0.94167619 0.98048861 0.93439426 - 180 0.09 0.97277934 0.97383622 0.96900866 - 190 0.095 0.96647288 1.0027643 0.96230782 - 200 0.1 0.94864291 0.95902585 0.96398175 -Loop time of 60.1095 on 1 procs for 200 steps with 8000 atoms +Per MPI rank memory allocation (min/avg/max) = 14.29 | 14.29 | 14.29 Mbytes + Step Time v_vx_sq_check v_vy_sq_check v_vz_sq_check + 0 0 0 0 0 + 10 0.005 0.70973271 0.71495693 0.71910087 + 20 0.01 0.90418096 0.88845437 0.89659567 + 30 0.015 0.9590736 0.97880338 0.9619016 + 40 0.02 0.98533774 0.96057682 0.95600448 + 50 0.025 0.96433662 0.96650071 0.95509683 + 60 0.03 0.96598029 0.96373656 0.96734888 + 70 0.035 0.95433045 0.98004764 0.96255924 + 80 0.04 0.97872906 0.95987289 0.96623598 + 90 0.045 0.99913888 0.99255731 0.95616142 + 100 0.05 0.98872675 0.97141018 0.95338841 + 110 0.055 0.97794592 0.97389258 0.98473719 + 120 0.06 0.98389266 0.96716284 0.95504862 + 130 0.065 0.98572886 0.96680923 0.95599065 + 140 0.07 0.97602684 0.97580081 0.9886878 + 150 0.075 0.99172003 0.95027467 0.96028033 + 160 0.08 0.96793247 0.94590928 0.95644301 + 170 0.085 0.94167619 0.98048861 0.93439426 + 180 0.09 0.97277934 0.97383622 0.96900866 + 190 0.095 0.96647288 1.0027643 0.96230782 + 200 0.1 0.94864291 0.95902585 0.96398175 +Loop time of 55.7542 on 1 procs for 200 steps with 8000 atoms -Performance: 143737.595 ns/day, 0.000 hours/ns, 3.327 timesteps/s -99.7% CPU use with 1 MPI tasks x no OpenMP threads +Performance: 154965.922 ns/day, 0.000 hours/ns, 3.587 timesteps/s, 28.697 katom-step/s +99.6% CPU use with 1 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 59.92 | 59.92 | 59.92 | 0.0 | 99.68 +Pair | 55.642 | 55.642 | 55.642 | 0.0 | 99.80 Neigh | 0 | 0 | 0 | 0.0 | 0.00 -Comm | 0.11154 | 0.11154 | 0.11154 | 0.0 | 0.19 -Output | 0.0063498 | 0.0063498 | 0.0063498 | 0.0 | 0.01 -Modify | 0.043546 | 0.043546 | 0.043546 | 0.0 | 0.07 -Other | | 0.02811 | | | 0.05 +Comm | 0.060977 | 0.060977 | 0.060977 | 0.0 | 0.11 +Output | 0.0066393 | 0.0066393 | 0.0066393 | 0.0 | 0.01 +Modify | 0.028354 | 0.028354 | 0.028354 | 0.0 | 0.05 +Other | | 0.01623 | | | 0.03 -Nlocal: 8000 ave 8000 max 8000 min +Nlocal: 8000 ave 8000 max 8000 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 16389 ave 16389 max 16389 min +Nghost: 16389 ave 16389 max 16389 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 1.456e+06 ave 1.456e+06 max 1.456e+06 min +Neighs: 1.456e+06 ave 1.456e+06 max 1.456e+06 min Histogram: 1 0 0 0 0 0 0 0 0 0 Total # of neighbors = 1456000 Ave neighs/atom = 182 Neighbor list builds = 0 Dangerous builds = 0 -Total wall time: 0:01:00 +Total wall time: 0:00:56 diff --git a/examples/PACKAGES/dpd-smooth/equipartition-verification/log.24Oct18.equipartition.g++.4 b/examples/PACKAGES/dpd-smooth/equipartition-verification/log.28Mar23.equipartition.g++.4 similarity index 58% rename from examples/PACKAGES/dpd-smooth/equipartition-verification/log.24Oct18.equipartition.g++.4 rename to examples/PACKAGES/dpd-smooth/equipartition-verification/log.28Mar23.equipartition.g++.4 index 88509f0fd1..e4f11d305e 100644 --- a/examples/PACKAGES/dpd-smooth/equipartition-verification/log.24Oct18.equipartition.g++.4 +++ b/examples/PACKAGES/dpd-smooth/equipartition-verification/log.28Mar23.equipartition.g++.4 @@ -1,7 +1,7 @@ -LAMMPS (24 Oct 2018) +LAMMPS (28 Mar 2023 - Development) dimension 3 units micro -atom_style meso +atom_style sph variable a equal 0.1 # lattice spacing micrometers variable L equal $a*10 @@ -38,13 +38,15 @@ Lattice spacing in x,y,z = 0.1 0.1 0.1 create_atoms 1 box Created 8000 atoms - Time spent = 0.00252754 secs + using lattice units in orthogonal box = (-1 -1 -1) to (1 1 1) + create_atoms CPU = 0.001 seconds mass * ${mass} mass * 0.001 -set group all meso/rho ${rho_0} -set group all meso/rho 1 - 8000 settings made for meso/rho +set group all sph/rho ${rho_0} +set group all sph/rho 1 +Setting atom values ... + 8000 settings made for sph/rho pair_style sdpd/taitwater/isothermal $T ${mu} 76787 # temperature viscosity random_seed pair_style sdpd/taitwater/isothermal 300 ${mu} 76787 @@ -71,7 +73,7 @@ variable vz_sq_check equal c_v_sq[3]*0.001/${kB}/$T variable vz_sq_check equal c_v_sq[3]*0.001/1.3806504e-08/$T variable vz_sq_check equal c_v_sq[3]*0.001/1.3806504e-08/300 -fix 1 all meso +fix 1 all sph neighbor ${skin} bin neighbor 0.04 bin @@ -82,8 +84,9 @@ thermo 10 thermo_style custom step time v_vx_sq_check v_vy_sq_check v_vz_sq_check run 200 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule Neighbor list info ... - update every 1 steps, delay 10 steps, check yes + update: every = 1 steps, delay = 0 steps, check = yes max neighbors/atom: 2000, page size: 100000 master list distance cutoff = 0.44 ghost atom cutoff = 0.44 @@ -92,55 +95,55 @@ Neighbor list info ... (1) pair sdpd/taitwater/isothermal, perpetual attributes: half, newton on pair build: half/bin/atomonly/newton - stencil: half/bin/3d/newton + stencil: half/bin/3d bin: standard -Per MPI rank memory allocation (min/avg/max) = 5.795 | 5.795 | 5.795 Mbytes -Step Time v_vx_sq_check v_vy_sq_check v_vz_sq_check - 0 0 0 0 0 - 10 0.005 0.71224819 0.71470372 0.7008956 - 20 0.01 0.90627589 0.90683966 0.90116506 - 30 0.015 0.938505 0.95884272 0.93337542 - 40 0.02 0.94394649 0.93668038 0.96468004 - 50 0.025 0.97152309 0.97546161 0.95107762 - 60 0.03 0.94710871 0.95678322 0.97285504 - 70 0.035 0.96253148 0.95838642 0.95450883 - 80 0.04 0.97581495 0.95278681 0.95099478 - 90 0.045 0.96251614 0.9740684 0.96081505 - 100 0.05 0.94191275 0.97137523 0.94084858 - 110 0.055 0.953406 0.95739684 0.98574522 - 120 0.06 0.99001614 0.99608287 0.9839996 - 130 0.065 0.96575225 0.94309655 0.92847798 - 140 0.07 0.97642687 0.97458638 0.94696406 - 150 0.075 0.99316381 0.96876814 0.95440106 - 160 0.08 0.94589744 0.95264791 0.95495169 - 170 0.085 0.97599092 0.95336014 0.97687718 - 180 0.09 0.97214242 0.9726305 0.9726035 - 190 0.095 0.97577583 0.96523645 0.9756968 - 200 0.1 0.96386053 0.97268854 0.94582436 -Loop time of 32.5247 on 4 procs for 200 steps with 8000 atoms +Per MPI rank memory allocation (min/avg/max) = 6.172 | 6.172 | 6.172 Mbytes + Step Time v_vx_sq_check v_vy_sq_check v_vz_sq_check + 0 0 0 0 0 + 10 0.005 0.71224819 0.71470372 0.7008956 + 20 0.01 0.90627589 0.90683966 0.90116506 + 30 0.015 0.938505 0.95884272 0.93337542 + 40 0.02 0.94394649 0.93668038 0.96468004 + 50 0.025 0.97152309 0.97546161 0.95107762 + 60 0.03 0.94710871 0.95678322 0.97285504 + 70 0.035 0.96253148 0.95838642 0.95450883 + 80 0.04 0.97581495 0.95278681 0.95099478 + 90 0.045 0.96251614 0.9740684 0.96081505 + 100 0.05 0.94191275 0.97137523 0.94084858 + 110 0.055 0.953406 0.95739684 0.98574522 + 120 0.06 0.99001614 0.99608287 0.9839996 + 130 0.065 0.96575225 0.94309655 0.92847798 + 140 0.07 0.97642687 0.97458638 0.94696406 + 150 0.075 0.99316381 0.96876814 0.95440106 + 160 0.08 0.94589744 0.95264791 0.95495169 + 170 0.085 0.97599092 0.95336014 0.97687718 + 180 0.09 0.97214242 0.9726305 0.9726035 + 190 0.095 0.97577583 0.96523645 0.9756968 + 200 0.1 0.96386053 0.97268854 0.94582436 +Loop time of 9.59181 on 4 procs for 200 steps with 8000 atoms -Performance: 265644.515 ns/day, 0.000 hours/ns, 6.149 timesteps/s -73.9% CPU use with 4 MPI tasks x no OpenMP threads +Performance: 900768.333 ns/day, 0.000 hours/ns, 20.851 timesteps/s, 166.809 katom-step/s +98.1% CPU use with 4 MPI tasks x no OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 27.385 | 28.409 | 28.761 | 11.1 | 87.34 +Pair | 8.9729 | 9.2147 | 9.4383 | 5.5 | 96.07 Neigh | 0 | 0 | 0 | 0.0 | 0.00 -Comm | 3.582 | 3.9343 | 4.9531 | 29.7 | 12.10 -Output | 0.022267 | 0.026073 | 0.033141 | 2.7 | 0.08 -Modify | 0.031714 | 0.033134 | 0.034367 | 0.6 | 0.10 -Other | | 0.1226 | | | 0.38 +Comm | 0.13739 | 0.36068 | 0.60216 | 27.6 | 3.76 +Output | 0.0022724 | 0.002394 | 0.0026506 | 0.3 | 0.02 +Modify | 0.0068559 | 0.0069926 | 0.0070974 | 0.1 | 0.07 +Other | | 0.007004 | | | 0.07 -Nlocal: 2000 ave 2000 max 2000 min +Nlocal: 2000 ave 2000 max 2000 min Histogram: 4 0 0 0 0 0 0 0 0 0 -Nghost: 8469 ave 8469 max 8469 min +Nghost: 8469 ave 8469 max 8469 min Histogram: 4 0 0 0 0 0 0 0 0 0 -Neighs: 364000 ave 376628 max 351184 min +Neighs: 364000 ave 376628 max 351184 min Histogram: 1 0 1 0 0 0 0 1 0 1 Total # of neighbors = 1456000 Ave neighs/atom = 182 Neighbor list builds = 0 Dangerous builds = 0 -Total wall time: 0:00:32 +Total wall time: 0:00:09 From 620cca34d4f840722fefaeca35c3548200dadce0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 15:19:13 -0400 Subject: [PATCH 357/448] add accessor to nfield, make certain field types are initialized early --- src/thermo.cpp | 10 ++++++++++ src/thermo.h | 1 + 2 files changed, 11 insertions(+) diff --git a/src/thermo.cpp b/src/thermo.cpp index 31c19fbdc2..1c07da695f 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -201,6 +201,8 @@ void Thermo::init() ValueTokenizer *format_line = nullptr; if (format_line_user.size()) format_line = new ValueTokenizer(format_line_user); + field_data.clear(); + field_data.resize(nfield); std::string format_this, format_line_user_def; for (int i = 0; i < nfield; i++) { @@ -208,6 +210,14 @@ void Thermo::init() format_this.clear(); format_line_user_def.clear(); + if (vtype[i] == FLOAT) { + field_data[i] = (double) 0.0; + } else if (vtype[i] == INT) { + field_data[i] = (int) 0; + } else if (vtype[i] == BIGINT) { + field_data[i] = (bigint) 0; + } + if ((lineflag == MULTILINE) && ((i % 3) == 0)) format[i] += "\n"; if ((lineflag == YAMLLINE) && (i == 0)) format[i] += " - ["; if (format_line) format_line_user_def = format_line->next_string(); diff --git a/src/thermo.h b/src/thermo.h index 8a5cba29d7..f22f3103b0 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -43,6 +43,7 @@ class Thermo : protected Pointers { int evaluate_keyword(const std::string &, double *); // for accessing cached thermo data + int get_nfield() const { return nfield; } bigint get_timestep() const { return ntimestep; } const std::vector &get_fields() const { return field_data; } const std::vector &get_keywords() const { return keyword; } From 30e6b8b9b6405cd979b87d4abb951ae5ca4e0a46 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 15:19:58 -0400 Subject: [PATCH 358/448] make more reliable with explicit loops using exported nfield value --- src/EXTRA-DUMP/dump_yaml.cpp | 19 +++++++++------- src/NETCDF/dump_netcdf.cpp | 37 ++++++++++++++++++++++-------- src/NETCDF/dump_netcdf.h | 1 + src/NETCDF/dump_netcdf_mpiio.cpp | 39 ++++++++++++++++++++++++-------- src/NETCDF/dump_netcdf_mpiio.h | 1 + 5 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/EXTRA-DUMP/dump_yaml.cpp b/src/EXTRA-DUMP/dump_yaml.cpp index ec7d26af31..f8d2fb2264 100644 --- a/src/EXTRA-DUMP/dump_yaml.cpp +++ b/src/EXTRA-DUMP/dump_yaml.cpp @@ -62,18 +62,21 @@ void DumpYAML::write_header(bigint ndump) Thermo *th = output->thermo; // output thermo data only on timesteps where it was computed if (update->ntimestep == th->get_timestep()) { + int nfield = th->get_nfield(); + const auto &keywords = th->get_keywords(); + const auto &fields = th->get_fields(); thermo_data += "thermo:\n - keywords: [ "; - for (const auto &key : th->get_keywords()) thermo_data += fmt::format("{}, ", key); + for (int i = 0; i < nfield; ++i) thermo_data += fmt::format("{}, ", keywords[i]); thermo_data += "]\n - data: [ "; - for (const auto &val : th->get_fields()) { - if (val.type == multitype::DOUBLE) - thermo_data += fmt::format("{}, ", val.data.d); - else if (val.type == multitype::INT) - thermo_data += fmt::format("{}, ", val.data.i); - else if (val.type == multitype::BIGINT) - thermo_data += fmt::format("{}, ", val.data.b); + for (int i = 0; i < nfield; ++i) { + if (fields[i].type == multitype::DOUBLE) + thermo_data += fmt::format("{}, ", fields[i].data.d); + else if (fields[i].type == multitype::INT) + thermo_data += fmt::format("{}, ", fields[i].data.i); + else if (fields[i].type == multitype::BIGINT) + thermo_data += fmt::format("{}, ", fields[i].data.b); else thermo_data += ", "; } diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 8c99ff1f70..2b064edeae 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -195,6 +195,7 @@ DumpNetCDF::DumpNetCDF(LAMMPS *lmp, int narg, char **arg) : type_nc_real = NC_FLOAT; thermo = false; + thermo_warn = true; thermovar = nullptr; framei = 0; @@ -223,7 +224,7 @@ void DumpNetCDF::openfile() if (thermo && !singlefile_opened) { delete[] thermovar; - thermovar = new int[output->thermo->get_keywords().size()]; + thermovar = new int[output->thermo->get_nfield()]; } // now the computes and fixes have been initialized, so we can query @@ -320,8 +321,10 @@ void DumpNetCDF::openfile() // perframe variables if (thermo) { - const auto &keywords = output->thermo->get_keywords(); - int nfield = keywords.size(); + Thermo *th = output->thermo; + const auto &keywords = th->get_keywords(); + const int nfield = th->get_nfield(); + for (int i = 0; i < nfield; i++) { NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); } @@ -433,9 +436,11 @@ void DumpNetCDF::openfile() // perframe variables if (thermo) { - const auto &fields = output->thermo->get_fields(); - const auto &keywords = output->thermo->get_keywords(); - int nfield = fields.size(); + Thermo *th = output->thermo; + const auto &fields = th->get_fields(); + const auto &keywords = th->get_keywords(); + const int nfield = th->get_nfield(); + for (int i = 0; i < nfield; i++) { if (fields[i].type == multitype::DOUBLE) { NCERRX( nc_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() ); @@ -600,9 +605,23 @@ void DumpNetCDF::write() start[1] = 0; if (thermo) { - const auto &keywords = output->thermo->get_keywords(); - const auto &fields = output->thermo->get_fields(); - int nfield = fields.size(); + Thermo *th = output->thermo; + + // will output current thermo data only on timesteps where it was computed. + // warn (once) about using cached copy from old timestep. + + if (thermo_warn && (update->ntimestep != th->get_timestep())) { + thermo_warn = false; + if (comm->me == 0) { + error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n" + " Dump netcdf always stores thermo data from last thermo output", + id, th->get_timestep(), update->ntimestep); + } + } + + const auto &keywords = th->get_keywords(); + const auto &fields = th->get_fields(); + int nfield = th->get_nfield(); for (int i = 0; i < nfield; i++) { if (filewriter) { if (fields[i].type == multitype::DOUBLE) { diff --git a/src/NETCDF/dump_netcdf.h b/src/NETCDF/dump_netcdf.h index 20c60ef104..982cd99fb5 100644 --- a/src/NETCDF/dump_netcdf.h +++ b/src/NETCDF/dump_netcdf.h @@ -65,6 +65,7 @@ class DumpNetCDF : public DumpCustom { int type_nc_real; // netcdf type to use for real variables: float or double bool thermo; // write thermo output to netcdf file + bool thermo_warn; // warn (once) that thermo output is on incompatible step bigint n_buffer; // size of buffer bigint *int_buffer; // buffer for passing data to netcdf diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index 3aec34dd40..4a34f11ab4 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -192,6 +192,7 @@ DumpNetCDFMPIIO::DumpNetCDFMPIIO(LAMMPS *lmp, int narg, char **arg) : type_nc_real = NC_FLOAT; thermo = false; + thermo_warn = true; thermovar = nullptr; framei = 0; @@ -220,7 +221,7 @@ void DumpNetCDFMPIIO::openfile() if (thermo && !singlefile_opened) { delete[] thermovar; - thermovar = new int[output->thermo->get_keywords().size()]; + thermovar = new int[output->thermo->get_nfield()]; } // now the computes and fixes have been initialized, so we can query @@ -318,8 +319,10 @@ void DumpNetCDFMPIIO::openfile() // perframe variables if (thermo) { - const auto &keywords = output->thermo->get_keywords(); - int nfield = keywords.size(); + Thermo *th = output->thermo; + const auto &keywords = th->get_keywords(); + const int nfield = th->get_nfield(); + for (int i = 0; i < nfield; i++) { NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); } @@ -423,9 +426,11 @@ void DumpNetCDFMPIIO::openfile() // perframe variables if (thermo) { - const auto &fields = output->thermo->get_fields(); - const auto &keywords = output->thermo->get_keywords(); - int nfield = fields.size(); + Thermo *th = output->thermo; + const auto &fields = th->get_fields(); + const auto &keywords = th->get_keywords(); + const int nfield = th->get_nfield(); + for (int i = 0; i < nfield; i++) { if (fields[i].type == multitype::DOUBLE) { NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() ); @@ -593,9 +598,23 @@ void DumpNetCDFMPIIO::write() NCERR( ncmpi_begin_indep_data(ncid) ); if (thermo) { - const auto &keywords = output->thermo->get_keywords(); - const auto &fields = output->thermo->get_fields(); - int nfield = fields.size(); + Thermo *th = output->thermo; + + // will output current thermo data only on timesteps where it was computed. + // warn (once) about using cached copy from old timestep. + + if (thermo_warn && (update->ntimestep != th->get_timestep())) { + thermo_warn = false; + if (comm->me == 0) { + error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n" + " Dump netcdf/mpiio always stores thermo data from last thermo output", + id, th->get_timestep(), update->ntimestep); + } + } + + const auto &keywords = th->get_keywords(); + const auto &fields = th->get_fields(); + int nfield = th->get_nfield(); for (int i = 0; i < nfield; i++) { if (filewriter) { if (fields[i].type == multitype::DOUBLE) { @@ -609,7 +628,7 @@ void DumpNetCDFMPIIO::write() } } - // write timestep header + // write timestep header write_time_and_cell(); diff --git a/src/NETCDF/dump_netcdf_mpiio.h b/src/NETCDF/dump_netcdf_mpiio.h index 5948dc272b..14ee930e26 100644 --- a/src/NETCDF/dump_netcdf_mpiio.h +++ b/src/NETCDF/dump_netcdf_mpiio.h @@ -62,6 +62,7 @@ class DumpNetCDFMPIIO : public DumpCustom { int type_nc_real; // netcdf type to use for real variables: float or double bool thermo; // write thermo output to netcdf file + bool thermo_warn; // warn (once) that thermo output is on incompatible step bigint n_buffer; // size of buffer bigint *int_buffer; // buffer for passing data to netcdf From de561737a3be4a0c3554b544273110c7be46e16e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 15:28:35 -0400 Subject: [PATCH 359/448] update docs --- doc/src/dump_modify.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/src/dump_modify.rst b/doc/src/dump_modify.rst index 89b3766083..0ac2afbeee 100644 --- a/doc/src/dump_modify.rst +++ b/doc/src/dump_modify.rst @@ -758,7 +758,8 @@ file alongside per-atom data. The values included in the dump file are cached values from the last thermo output and include the exact same the values as specified by the :doc:`thermo_style ` command. Because these are cached values, they are only up-to-date when dump -output is on a timestep that also has thermo output. +output is on a timestep that also has thermo output. Dump style *yaml* +will skip thermo output on incompatible steps. ---------- From 491e152289e3abf267f4ebee6cddda7ba797591f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 16:21:01 -0400 Subject: [PATCH 360/448] add API to library interface to access last thermo data --- src/EXTRA-DUMP/dump_yaml.cpp | 4 +- src/NETCDF/dump_netcdf.cpp | 12 ++-- src/NETCDF/dump_netcdf_mpiio.cpp | 12 ++-- src/library.cpp | 99 +++++++++++++++++++++++++++++++- src/library.h | 1 + src/thermo.cpp | 1 + src/thermo.h | 4 +- 7 files changed, 116 insertions(+), 17 deletions(-) diff --git a/src/EXTRA-DUMP/dump_yaml.cpp b/src/EXTRA-DUMP/dump_yaml.cpp index f8d2fb2264..47cab1ee02 100644 --- a/src/EXTRA-DUMP/dump_yaml.cpp +++ b/src/EXTRA-DUMP/dump_yaml.cpp @@ -61,8 +61,8 @@ void DumpYAML::write_header(bigint ndump) if (thermo) { Thermo *th = output->thermo; // output thermo data only on timesteps where it was computed - if (update->ntimestep == th->get_timestep()) { - int nfield = th->get_nfield(); + if (update->ntimestep == *th->get_timestep()) { + int nfield = *th->get_nfield(); const auto &keywords = th->get_keywords(); const auto &fields = th->get_fields(); diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 2b064edeae..0115c0bbe9 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -224,7 +224,7 @@ void DumpNetCDF::openfile() if (thermo && !singlefile_opened) { delete[] thermovar; - thermovar = new int[output->thermo->get_nfield()]; + thermovar = new int[*output->thermo->get_nfield()]; } // now the computes and fixes have been initialized, so we can query @@ -323,7 +323,7 @@ void DumpNetCDF::openfile() if (thermo) { Thermo *th = output->thermo; const auto &keywords = th->get_keywords(); - const int nfield = th->get_nfield(); + const int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { NCERRX( nc_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); @@ -439,7 +439,7 @@ void DumpNetCDF::openfile() Thermo *th = output->thermo; const auto &fields = th->get_fields(); const auto &keywords = th->get_keywords(); - const int nfield = th->get_nfield(); + const int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { if (fields[i].type == multitype::DOUBLE) { @@ -610,18 +610,18 @@ void DumpNetCDF::write() // will output current thermo data only on timesteps where it was computed. // warn (once) about using cached copy from old timestep. - if (thermo_warn && (update->ntimestep != th->get_timestep())) { + if (thermo_warn && (update->ntimestep != *th->get_timestep())) { thermo_warn = false; if (comm->me == 0) { error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n" " Dump netcdf always stores thermo data from last thermo output", - id, th->get_timestep(), update->ntimestep); + id, *th->get_timestep(), update->ntimestep); } } const auto &keywords = th->get_keywords(); const auto &fields = th->get_fields(); - int nfield = th->get_nfield(); + int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { if (filewriter) { if (fields[i].type == multitype::DOUBLE) { diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index 4a34f11ab4..f9382dacef 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -221,7 +221,7 @@ void DumpNetCDFMPIIO::openfile() if (thermo && !singlefile_opened) { delete[] thermovar; - thermovar = new int[output->thermo->get_nfield()]; + thermovar = new int[*output->thermo->get_nfield()]; } // now the computes and fixes have been initialized, so we can query @@ -321,7 +321,7 @@ void DumpNetCDFMPIIO::openfile() if (thermo) { Thermo *th = output->thermo; const auto &keywords = th->get_keywords(); - const int nfield = th->get_nfield(); + const int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { NCERRX( ncmpi_inq_varid(ncid, keywords[i].c_str(), &thermovar[i]), keywords[i].c_str() ); @@ -429,7 +429,7 @@ void DumpNetCDFMPIIO::openfile() Thermo *th = output->thermo; const auto &fields = th->get_fields(); const auto &keywords = th->get_keywords(); - const int nfield = th->get_nfield(); + const int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { if (fields[i].type == multitype::DOUBLE) { @@ -603,18 +603,18 @@ void DumpNetCDFMPIIO::write() // will output current thermo data only on timesteps where it was computed. // warn (once) about using cached copy from old timestep. - if (thermo_warn && (update->ntimestep != th->get_timestep())) { + if (thermo_warn && (update->ntimestep != *th->get_timestep())) { thermo_warn = false; if (comm->me == 0) { error->warning(FLERR, "Dump {} output on incompatible timestep with thermo output: {} vs {} \n" " Dump netcdf/mpiio always stores thermo data from last thermo output", - id, th->get_timestep(), update->ntimestep); + id, *th->get_timestep(), update->ntimestep); } } const auto &keywords = th->get_keywords(); const auto &fields = th->get_fields(); - int nfield = th->get_nfield(); + int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { if (filewriter) { if (fields[i].type == multitype::DOUBLE) { diff --git a/src/library.cpp b/src/library.cpp index 33f49a4e53..6b079b4a93 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -719,7 +719,7 @@ double lammps_get_natoms(void *handle) /* ---------------------------------------------------------------------- */ -/** Get current value of a thermo keyword. +/** Evaluate a thermo keyword. * \verbatim embed:rst @@ -750,6 +750,103 @@ double lammps_get_thermo(void *handle, const char *keyword) /* ---------------------------------------------------------------------- */ +/** Access cached data from last thermo output + * +\verbatim embed:rst + +This function provides access to cached data from the last thermo +output. This differs from :cpp:func:`lammps_get_thermo` in that it does +not trigger an evaluation. It provides direct access to a a read-only +location of the last thermo output data and the corresponding keyword +strings. The output depends on the value of the *what* argument string. + +.. list-table:: + :header-rows: 1 + :widths: auto + + * - Value of *what + - Description of return value + - Data type + - Uses index + * - step + - timestep when the last thermo output was generated or -1 when no data available + - pointer to bigint cast to void pointer + - no + * - num + - number of fields in thermo output + - pointer to int cast to void pointer + - no + * - keyword + - column keyword for thermo output + - const char pointer cast to void pointer + - yes + * - type + - data type of thermo output column. LAMMPS_INT, LAMMPS_DOUBLE, or LAMMPS_INT64 + - const int cast to void pointer + - yes + * - data + - actual field data for column + - pointer to either int, int64_t or double cast to void pointer + - yes + +\endverbatim + * + * \param handle pointer to a previously created LAMMPS instance + * \param what string with the kind of data requested + * \param idx integer with index into data arrays, ignored for scalar data + * \return pointer to location of requested data cast to void or NULL */ + +void *lammps_last_thermo(void *handle, const char *what, int idx) +{ + auto lmp = (LAMMPS *) handle; + void *val = nullptr; + Thermo *th = lmp->output->thermo; + if (!th) return nullptr; + const int nfield = *th->get_nfield(); + + BEGIN_CAPTURE + { + if (strcmp(what, "step") == 0) { + val = (void *) th->get_timestep(); + + } else if (strcmp(what, "num") == 0) { + val = (void *) th->get_nfield(); + + } else if (strcmp(what, "keyword") == 0) { + if ((idx < 0) || (idx >= nfield)) return nullptr; + const auto &keywords = th->get_keywords(); + val = (void *) keywords[idx].c_str(); + + } else if (strcmp(what, "type") == 0) { + if ((idx < 0) || (idx >= nfield)) return nullptr; + const auto &field = th->get_fields()[idx]; + if (field.type == multitype::INT) { + val = (void *) LAMMPS_INT; + } else if (field.type == multitype::BIGINT) { + val = (void *) LAMMPS_INT64; + } else if (field.type == multitype::DOUBLE) { + val = (void *) LAMMPS_DOUBLE; + } + + } else if (strcmp(what, "data") == 0) { + if ((idx < 0) || (idx >= nfield)) return nullptr; + const auto &field = th->get_fields()[idx]; + if (field.type == multitype::INT) { + val = (void *) &field.data.i; + } else if (field.type == multitype::BIGINT) { + val = (void *) &field.data.b; + } else if (field.type == multitype::DOUBLE) { + val = (void *) &field.data.d; + } + + } else val = nullptr; + } + END_CAPTURE + return val; +} + +/* ---------------------------------------------------------------------- */ + /** Extract simulation box parameters. * \verbatim embed:rst diff --git a/src/library.h b/src/library.h index 340b0edb7b..4c2530210c 100644 --- a/src/library.h +++ b/src/library.h @@ -148,6 +148,7 @@ void lammps_commands_string(void *handle, const char *str); double lammps_get_natoms(void *handle); double lammps_get_thermo(void *handle, const char *keyword); +void *lammps_last_thermo(void *handle, const char *what, int idx); void lammps_extract_box(void *handle, double *boxlo, double *boxhi, double *xy, double *yz, double *xz, int *pflags, int *boxflag); diff --git a/src/thermo.cpp b/src/thermo.cpp index 1c07da695f..c6e71354ff 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -111,6 +111,7 @@ Thermo::Thermo(LAMMPS *_lmp, int narg, char **arg) : lostflag = lostbond = Thermo::ERROR; lostbefore = warnbefore = 0; flushflag = 0; + ntimestep = -1; // set style and corresponding lineflag // custom style builds its own line of keywords, including wildcard expansion diff --git a/src/thermo.h b/src/thermo.h index f22f3103b0..333a282ca0 100644 --- a/src/thermo.h +++ b/src/thermo.h @@ -43,8 +43,8 @@ class Thermo : protected Pointers { int evaluate_keyword(const std::string &, double *); // for accessing cached thermo data - int get_nfield() const { return nfield; } - bigint get_timestep() const { return ntimestep; } + const int *get_nfield() const { return &nfield; } + const bigint *get_timestep() const { return &ntimestep; } const std::vector &get_fields() const { return field_data; } const std::vector &get_keywords() const { return keyword; } From 7551219d81c368e9b1879a3224377693beac306f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 20:16:26 -0400 Subject: [PATCH 361/448] correct multitype unittest for -DLAMMPS_SMALLSMALL --- unittest/utils/test_lmptype.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/unittest/utils/test_lmptype.cpp b/unittest/utils/test_lmptype.cpp index 6db340fddf..e5dc871953 100644 --- a/unittest/utils/test_lmptype.cpp +++ b/unittest/utils/test_lmptype.cpp @@ -41,7 +41,7 @@ TEST(Types, ubuf) TEST(Types, multitype) { - multitype m[6]; + multitype m[7]; int64_t b1 = (3L << 48) - 1; int i1 = 20; double d1 = 0.1; @@ -50,27 +50,22 @@ TEST(Types, multitype) m[1] = i1; m[2] = d1; -#if !defined(LAMMPS_SMALLSMALL) - m[3] = -((1L << 40) + (1L << 50)); -#endif + m[3] = (bigint) -((1L << 40) + (1L << 50)); m[4] = -1023; m[5] = -2.225; -#if defined(LAMMPS_SMALLSMALL) - EXPECT_EQ(m[0].type, multitype::INT); -#else EXPECT_EQ(m[0].type, multitype::BIGINT); -#endif EXPECT_EQ(m[1].type, multitype::INT); EXPECT_EQ(m[2].type, multitype::DOUBLE); #if defined(LAMMPS_SMALLSMALL) - EXPECT_EQ(m[3].type, multitype::NONE); + EXPECT_EQ(m[3].type, multitype::INT); #else EXPECT_EQ(m[3].type, multitype::BIGINT); #endif EXPECT_EQ(m[4].type, multitype::INT); EXPECT_EQ(m[5].type, multitype::DOUBLE); + EXPECT_EQ(m[6].type, multitype::NONE); EXPECT_EQ(m[0].data.b, b1); EXPECT_EQ(m[1].data.i, i1); From dd0bba6ac7a62f4e321f62c6105a7f736d3fd3bb Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 7 Jun 2023 20:37:53 -0400 Subject: [PATCH 362/448] whitespace --- src/GRANULAR/gran_sub_mod_normal.h | 6 +++--- src/library.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/GRANULAR/gran_sub_mod_normal.h b/src/GRANULAR/gran_sub_mod_normal.h index c1511fdfa5..6f2f3aabbe 100644 --- a/src/GRANULAR/gran_sub_mod_normal.h +++ b/src/GRANULAR/gran_sub_mod_normal.h @@ -94,7 +94,7 @@ namespace Granular_NS { void coeffs_to_local() override; void mix_coeffs(double *, double *) override; private: - int mixed_coefficients; + int mixed_coefficients; }; /* ---------------------------------------------------------------------- */ @@ -110,7 +110,7 @@ namespace Granular_NS { protected: double k, cohesion; double F_pulloff, Fne; - int mixed_coefficients; + int mixed_coefficients; }; /* ---------------------------------------------------------------------- */ @@ -129,7 +129,7 @@ namespace Granular_NS { protected: double k, cohesion; double Emix, F_pulloff, Fne; - int mixed_coefficients; + int mixed_coefficients; }; } // namespace Granular_NS diff --git a/src/library.cpp b/src/library.cpp index 6b079b4a93..62d029f625 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -788,7 +788,7 @@ strings. The output depends on the value of the *what* argument string. - actual field data for column - pointer to either int, int64_t or double cast to void pointer - yes - + \endverbatim * * \param handle pointer to a previously created LAMMPS instance From c851c7304c02d8b38424c240e3ee84671a402f7a Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Thu, 8 Jun 2023 11:03:21 +0200 Subject: [PATCH 363/448] Update documentation for compute stress/cartesian, and split the doc page compute_stress_profile into compute_stress_cartesian and compute_stress_curvilinear --- doc/src/compute_stress_cartesian.rst | 118 ++++++++++++++++++ ...ile.rst => compute_stress_curvilinear.rst} | 48 ++----- 2 files changed, 125 insertions(+), 41 deletions(-) create mode 100644 doc/src/compute_stress_cartesian.rst rename doc/src/{compute_stress_profile.rst => compute_stress_curvilinear.rst} (69%) diff --git a/doc/src/compute_stress_cartesian.rst b/doc/src/compute_stress_cartesian.rst new file mode 100644 index 0000000000..f52b360aa6 --- /dev/null +++ b/doc/src/compute_stress_cartesian.rst @@ -0,0 +1,118 @@ +.. index:: compute stress/cartesian + +compute stress/cartesian command +================================== + +Syntax +"""""" + +.. code-block:: LAMMPS + + compute ID group-ID stress/cartesian args + +* ID, group-ID are documented in :doc:`compute ` command +* args = argument specific to the compute style + +.. parsed-literal:: + + *stress/cartesian* args = dim1 bin_width1 dim2 bin_width2 keyword + dim1 = *x* or *y* or *z* + bin_width1 = width of the bin + dim2 = *x* or *y* or *z* or *NULL* + bin_width2 = width of the bin + keyword = *ke* or *pair* or *bond* + +Examples +"""""""" + +.. code-block:: LAMMPS + compute 1 all stress/cartesian x 0.1 NULL 0 + compute 1 all stress/cartesian y 0.1 z 0.1 + compute 1 all stress/cartesian x 0.1 NULL 0 ke pair + +Description +""""""""""" + +Compute *stress/cartesian* defines computations that calculate profiles of the +diagonal components of the local stress tensor over one or two Cartesian +dimensions, as described in :ref:`(Ikeshoji)`. The stress tensor is +split into a kinetic contribution :math:`P^k` and a virial contribution +:math:`P^v`. The sum gives the total stress tensor :math:`P = P^k+P^v`. +This compute obeys momentum balance through fluid interfaces. They use the +Irving--Kirkwood contour, which is the straight line between particle pairs. + +This compute only supports pair and bond (no angle, dihedral, improper, +or kspace) forces. By default, if no extra keywords are specified, all +supported contributions to the stress are included (ke, pair, bond). If any +keywords are specified, then only those components are summed. + +Output info +""""""""""" + +The output columns for *stress/cartesian* are the position of the +center of the local volume in the first and second dimensions, number +density, :math:`P^k_{xx}`, :math:`P^k_{yy}`, :math:`P^k_{zz}`, +:math:`P^v_{xx}`, :math:`P^v_{yy}`, and :math:`P^v_{zz}`. There are 8 +columns when one dimension is specified and 9 columns when two +dimensions are specified. The number of bins (rows) is +:math:`(L_1/b_1)(L_2/b_2)`, where :math:`L_1` and :math:`L_2` are the lengths +of the simulation box in the specified dimensions and :math:`b_1` and +:math:`b_2` are the specified bin widths. When only one dimension is +specified, the number of bins (rows) is :math:`L_1/b_1`. + +This array can be output with :doc:`fix ave/time `, + +.. code-block:: LAMMPS + + compute p all stress/cartesian x 0.1 + fix 2 all ave/time 100 1 100 c_p[*] file dump_p.out mode vector + +The values calculated by this compute are "intensive". The stress +values will be in pressure :doc:`units `. The number density +values are in inverse volume :doc:`units `. + +NOTE 1: The local stress does not include any Lennard-Jones tail +corrections to the stress added by the +:doc:`pair_modify tail yes ` +command, since those are contributions to the global system pressure. + +NOTE 2: The local stress profiles generated by these computes are +similar to those obtained by the +:doc:`method-of-planes (MOP) `. +A key difference +is that compute `stress/mop/profile ` +considers particles crossing a set of planes, while +*stress/cartesian* computes averages for a set of small volumes. +Moreover, this compute computes the diagonal components of the stress +tensor :math:`P_{xx}`, :math:`P_{yy}`, and :math:`P_{zz}`, while +`stress/mop/profile ` computes the components +:math:`P_{ix}`, :math:`P_{iy}`, and :math:`P_{iz}`, where :math:`i` is the +direction normal to the plane. + +More information on the similarities and differences can be found in +:ref:`(Ikeshoji)`. + +Restrictions +"""""""""""" + +These computes calculate the stress tensor contributions for pair and bond +forces only (no angle, dihedral, improper, or kspace force). +It requires pairwise force calculations not available for most +many-body pair styles. + +These computes are part of the EXTRA-COMPUTE package. They are only +enabled if LAMMPS was built with that package. See the :doc:`Build +package ` doc page for more info. + +Related commands +"""""""""""""""" + +:doc:`compute stress/atom `, :doc:`compute pressure `, +:doc:`compute stress/mop/profile `, :doc:`compute stress/spherical `, +:doc:`compute stress/cylinder ` + +---------- + +.. _Ikeshoji2: + +**(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). \ No newline at end of file diff --git a/doc/src/compute_stress_profile.rst b/doc/src/compute_stress_curvilinear.rst similarity index 69% rename from doc/src/compute_stress_profile.rst rename to doc/src/compute_stress_curvilinear.rst index 7a4b6a38e6..f7cbf5efbe 100644 --- a/doc/src/compute_stress_profile.rst +++ b/doc/src/compute_stress_curvilinear.rst @@ -1,11 +1,6 @@ -.. index:: compute stress/cartesian .. index:: compute stress/cylinder .. index:: compute stress/spherical - -compute stress/cartesian command -================================== - compute stress/cylinder command ================================= @@ -20,15 +15,11 @@ Syntax compute ID group-ID style args * ID, group-ID are documented in :doc:`compute ` command -* style = stress/cartesian or stress/spherical or stress/cylinder +* style = stress/spherical or stress/cylinder * args = argument specific to the compute style .. parsed-literal:: - *stress/cartesian* args = dim bin_width - dim = *x* or *y* or *z* - bin_width = width of the bin - one or two dim/bin_width pairs may be appended *stress/cylinder* args = zlo zh Rmax bin_width keyword zlo = minimum z-boundary for cylinder zhi = maximum z-boundary for cylinder @@ -45,9 +36,6 @@ Examples """""""" .. code-block:: LAMMPS - - compute 1 all stress/cartesian x 0.1 - compute 1 all stress/cartesian y 0.25 z 0.1 compute 1 all stress/cylinder -10.0 10.0 15.0 0.25 compute 1 all stress/cylinder -10.0 10.0 15.0 0.25 ke no compute 1 all stress/spherical 0 0 0 0.1 10 @@ -55,21 +43,19 @@ Examples Description """"""""""" -Compute *stress/cartesian*, compute *stress/cylinder*, and compute +Compute *stress/cylinder*, and compute *stress/spherical* define computations that calculate profiles of the diagonal components of the local stress tensor in the specified coordinate system. The stress tensor is split into a kinetic contribution :math:`P^k` and a virial contribution :math:`P^v`. The sum gives the total stress tensor :math:`P = P^k+P^v`. These computes can for example be used to calculate the diagonal components of the local -stress tensor of interfaces with flat, cylindrical, or spherical +stress tensor of surfaces with cylindrical or spherical symmetry. These computes obeys momentum balance through fluid interfaces. They use the Irving--Kirkwood contour, which is the straight line between particle pairs. -The *stress/cartesian* computes the stress profile along one or two -Cartesian coordinates, as described in :ref:`(Ikeshoji)`. The -compute *stress/cylinder* computes the stress profile along the +The compute *stress/cylinder* computes the stress profile along the radial direction in cylindrical coordinates, as described in :ref:`(Addington)`. The compute *stress/spherical* computes the stress profile along the radial direction in spherical @@ -79,17 +65,6 @@ coordinates, as described in :ref:`(Ikeshoji)`. Output info """"""""""" -The output columns for *stress/cartesian* are the position of the -center of the local volume in the first and second dimensions, number -density, :math:`P^k_{xx}`, :math:`P^k_{yy}`, :math:`P^k_{zz}`, -:math:`P^v_{xx}`, :math:`P^v_{yy}`, and :math:`P^v_{zz}`. There are 8 -columns when one dimension is specified and 9 columns when two -dimensions are specified. The number of bins (rows) is -:math:`(L_1/b_1)(L_2/b_2)`, where :math:`L_1` and :math:`L_2` are the lengths -of the simulation box in the specified dimensions and :math:`b_1` and -:math:`b_2` are the specified bin widths. When only one dimension is -specified, the number of bins (rows) is :math:`L_1/b_1`. - The default output columns for *stress/cylinder* are the radius to the center of the cylindrical shell, number density, :math:`P^k_{rr}`, :math:`P^k_{\phi\phi}`, :math:`P^k_{zz}`, :math:`P^v_{rr}`, @@ -111,7 +86,7 @@ This array can be output with :doc:`fix ave/time `, .. code-block:: LAMMPS - compute p all stress/cartesian x 0.1 + compute 1 all stress/spherical 0 0 0 0.1 10 fix 2 all ave/time 100 1 100 c_p[*] file dump_p.out mode vector The values calculated by this compute are "intensive". The stress @@ -123,16 +98,6 @@ corrections to the stress added by the :doc:`pair_modify tail yes ` command, since those are contributions to the global system pressure. -NOTE 2: The local stress profiles generated by these computes are -similar to those obtained by the -:doc:`method-of-planes (MOP) `. -A key difference -is that compute `stress/mop/profile ` -considers particles crossing a set of planes, while -*stress/cartesian* computes averages for a set of small volumes. -More information on the similarities and differences can be found in -:ref:`(Ikeshoji)`. - Restrictions """""""""""" @@ -150,7 +115,8 @@ package ` doc page for more info. Related commands """""""""""""""" -:doc:`compute stress/atom `, :doc:`compute pressure `, :doc:`compute stress/mop/profile ` +:doc:`compute stress/atom `, :doc:`compute pressure `, :doc:`compute +stress/mop/profile `, :doc:`compute stress/cartesian ` Default """"""" From 2272d8dd205c99cf91c202e3961723719b7f673d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 09:45:12 -0400 Subject: [PATCH 364/448] add new library interface function to documentation --- doc/src/Library_properties.rst | 6 ++++ src/library.cpp | 53 ++++++++++++++++++---------------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/doc/src/Library_properties.rst b/doc/src/Library_properties.rst index 21e5609fc0..005bfaeea5 100644 --- a/doc/src/Library_properties.rst +++ b/doc/src/Library_properties.rst @@ -5,6 +5,7 @@ This section documents the following functions: - :cpp:func:`lammps_get_natoms` - :cpp:func:`lammps_get_thermo` +- :cpp:func:`lammps_last_thermo` - :cpp:func:`lammps_extract_box` - :cpp:func:`lammps_reset_box` - :cpp:func:`lammps_memory_usage` @@ -81,6 +82,11 @@ subdomains and processors. ----------------------- +.. doxygenfunction:: lammps_last_thermo + :project: progguide + +----------------------- + .. doxygenfunction:: lammps_extract_box :project: progguide diff --git a/src/library.cpp b/src/library.cpp index 62d029f625..36d53c3e6c 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -723,10 +723,12 @@ double lammps_get_natoms(void *handle) * \verbatim embed:rst -This function returns the current value of a :doc:`thermo keyword -`. Unlike :cpp:func:`lammps_extract_global` it does not -give access to the storage of the desired data but returns its value as -a ``double``, so it can also return information that is computed on-the-fly. +This function returns the current value of a :doc:`thermo keyword `. +Unlike :cpp:func:`lammps_extract_global` it does not give access to the +storage of the desired data but returns its value as a ``double``, so it +can also return information that is computed on-the-fly. +Use :cpp:func:`lammps_last_thermo` to get access to the cached data from +the last thermo output. \endverbatim * @@ -754,49 +756,50 @@ double lammps_get_thermo(void *handle, const char *keyword) * \verbatim embed:rst -This function provides access to cached data from the last thermo -output. This differs from :cpp:func:`lammps_get_thermo` in that it does -not trigger an evaluation. It provides direct access to a a read-only -location of the last thermo output data and the corresponding keyword -strings. The output depends on the value of the *what* argument string. +This function provides access to cached data from the last thermo output. +This differs from :cpp:func:`lammps_get_thermo` in that it does not trigger +an evaluation. Instead it provides direct access to a read-only location +of the last thermo output data and the corresponding keyword strings. +The how to handle the return value depends on the value of the *what* +argument string. .. list-table:: :header-rows: 1 :widths: auto - * - Value of *what + * - Value of *what* - Description of return value - Data type - Uses index * - step - - timestep when the last thermo output was generated or -1 when no data available - - pointer to bigint cast to void pointer + - timestep when the last thermo output was generated or -1 + - pointer to bigint - no * - num - number of fields in thermo output - - pointer to int cast to void pointer + - pointer to int - no * - keyword - column keyword for thermo output - - const char pointer cast to void pointer + - const char pointer - yes * - type - - data type of thermo output column. LAMMPS_INT, LAMMPS_DOUBLE, or LAMMPS_INT64 - - const int cast to void pointer + - data type of thermo output column; see :cpp:enum:`_LMP_DATATYPE_CONST` + - const int - yes * - data - actual field data for column - - pointer to either int, int64_t or double cast to void pointer + - pointer to either int, int64_t or double - yes \endverbatim * * \param handle pointer to a previously created LAMMPS instance * \param what string with the kind of data requested - * \param idx integer with index into data arrays, ignored for scalar data + * \param index integer with index into data arrays, ignored for scalar data * \return pointer to location of requested data cast to void or NULL */ -void *lammps_last_thermo(void *handle, const char *what, int idx) +void *lammps_last_thermo(void *handle, const char *what, int index) { auto lmp = (LAMMPS *) handle; void *val = nullptr; @@ -813,13 +816,13 @@ void *lammps_last_thermo(void *handle, const char *what, int idx) val = (void *) th->get_nfield(); } else if (strcmp(what, "keyword") == 0) { - if ((idx < 0) || (idx >= nfield)) return nullptr; + if ((index < 0) || (index >= nfield)) return nullptr; const auto &keywords = th->get_keywords(); - val = (void *) keywords[idx].c_str(); + val = (void *) keywords[index].c_str(); } else if (strcmp(what, "type") == 0) { - if ((idx < 0) || (idx >= nfield)) return nullptr; - const auto &field = th->get_fields()[idx]; + if ((index < 0) || (index >= nfield)) return nullptr; + const auto &field = th->get_fields()[index]; if (field.type == multitype::INT) { val = (void *) LAMMPS_INT; } else if (field.type == multitype::BIGINT) { @@ -829,8 +832,8 @@ void *lammps_last_thermo(void *handle, const char *what, int idx) } } else if (strcmp(what, "data") == 0) { - if ((idx < 0) || (idx >= nfield)) return nullptr; - const auto &field = th->get_fields()[idx]; + if ((index < 0) || (index >= nfield)) return nullptr; + const auto &field = th->get_fields()[index]; if (field.type == multitype::INT) { val = (void *) &field.data.i; } else if (field.type == multitype::BIGINT) { From d6ad52ea6604cbf031076dd583c07d154bfdcca7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 09:46:33 -0400 Subject: [PATCH 365/448] allow wildcards with "cutoff" keyword to fix reaxff/species this also switched to using fmtlib for column aligned output formatting and re-applies clang-format. --- doc/src/fix_reaxff_species.rst | 23 +++++-- src/REAXFF/fix_reaxff_species.cpp | 106 +++++++++++++++--------------- src/REAXFF/fix_reaxff_species.h | 2 - 3 files changed, 71 insertions(+), 60 deletions(-) diff --git a/doc/src/fix_reaxff_species.rst b/doc/src/fix_reaxff_species.rst index f57132f08b..c22c9d7b9f 100644 --- a/doc/src/fix_reaxff_species.rst +++ b/doc/src/fix_reaxff_species.rst @@ -25,7 +25,7 @@ Syntax .. parsed-literal:: *cutoff* value = I J Cutoff - I, J = atom types + I, J = atom types (see asterisk form below) Cutoff = Bond-order cutoff value for this pair of atom types *element* value = Element1, Element2, ... *position* value = posfreq filepos @@ -49,7 +49,7 @@ Examples .. code-block:: LAMMPS fix 1 all reaxff/species 10 10 100 species.out - fix 1 all reaxff/species 1 2 20 species.out cutoff 1 1 0.40 cutoff 1 2 0.55 + fix 1 all reaxff/species 1 2 20 species.out cutoff 1 1 0.40 cutoff 1 2*3 0.55 fix 1 all reaxff/species 1 100 100 species.out element Au O H position 1000 AuOH.pos fix 1 all reaxff/species 1 100 100 species.out delete species.del masslimit 0 50 @@ -88,13 +88,24 @@ If the filename ends with ".gz", the output file is written in gzipped format. A gzipped dump file will be about 3x smaller than the text version, but will also take longer to write. +.. versionadded:: TBD + + Support for wildcards added + Optional keyword *cutoff* can be assigned to change the minimum bond-order values used in identifying chemical bonds between pairs of atoms. Bond-order cutoffs should be carefully chosen, as bond-order -cutoffs that are too small may include too many bonds (which will -result in an error), while cutoffs that are too large will result in -fragmented molecules. The default cutoff of 0.3 usually gives good -results. +cutoffs that are too small may include too many bonds (which will result +in an error), while cutoffs that are too large will result in fragmented +molecules. The default cutoff of 0.3 usually gives good results. A +wildcard asterisk can be used in place of or in conjunction with the I,J +arguments to set the bond-order cutoff for multiple pairs of atom types. +This takes the form "\*" or "\*n" or "n\*" or "m\*n". If :math:`N` is +the number of atom types, then an asterisk with no numeric values means +all types from 1 to :math:`N`. A leading asterisk means all types from +1 to n (inclusive). A trailing asterisk means all types from n to +:math:`N` (inclusive). A middle asterisk means all types from m to n +(inclusive). The optional keyword *element* can be used to specify the chemical symbol printed for each LAMMPS atom type. The number of symbols must diff --git a/src/REAXFF/fix_reaxff_species.cpp b/src/REAXFF/fix_reaxff_species.cpp index 92bca99ae0..8fa06cafb3 100644 --- a/src/REAXFF/fix_reaxff_species.cpp +++ b/src/REAXFF/fix_reaxff_species.cpp @@ -48,15 +48,16 @@ using namespace LAMMPS_NS; using namespace FixConst; static const char cite_reaxff_species_delete[] = - "fix reaxff/species, 'delete' keyword: https://doi.org/10.1016/j.carbon.2022.11.002\n\n" - "@Article{Gissinger23,\n" - " author = {J. R. Gissinger, S. R. Zavada, J. G. Smith, J. Kemppainen, I. Gallegos, G. M. Odegard, E. J. Siochi, K. E. Wise},\n" - " title = {Predicting char yield of high-temperature resins},\n" - " journal = {Carbon},\n" - " year = 2023,\n" - " volume = 202,\n" - " pages = {336-347}\n" - "}\n\n"; + "fix reaxff/species, 'delete' keyword: https://doi.org/10.1016/j.carbon.2022.11.002\n\n" + "@Article{Gissinger23,\n" + " author = {J. R. Gissinger, S. R. Zavada, J. G. Smith, J. Kemppainen, I. Gallegos, G. M. " + "Odegard, E. J. Siochi, K. E. Wise},\n" + " title = {Predicting char yield of high-temperature resins},\n" + " journal = {Carbon},\n" + " year = 2023,\n" + " volume = 202,\n" + " pages = {336-347}\n" + "}\n\n"; /* ---------------------------------------------------------------------- */ @@ -148,13 +149,11 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : setupflag = 0; // set default bond order cutoff - int itype, jtype; - double bo_cut; - bg_cut = 0.30; + double bo_cut = 0.30; int np1 = ntypes + 1; memory->create(BOCut, np1, np1, "reaxff/species:BOCut"); for (int i = 1; i < np1; i++) - for (int j = 1; j < np1; j++) BOCut[i][j] = bg_cut; + for (int j = 1; j < np1; j++) BOCut[i][j] = bo_cut; // optional args eletype = nullptr; @@ -172,16 +171,19 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : // set BO cutoff if (strcmp(arg[iarg], "cutoff") == 0) { if (iarg + 4 > narg) utils::missing_cmd_args(FLERR, "fix reaxff/species cutoff", error); - itype = utils::inumeric(FLERR, arg[iarg + 1], false, lmp); - jtype = utils::inumeric(FLERR, arg[iarg + 2], false, lmp); + int ilo, ihi, jlo, jhi; + utils::bounds(FLERR, arg[iarg + 1], 1, atom->ntypes, ilo, ihi, error); + utils::bounds(FLERR, arg[iarg + 2], 1, atom->ntypes, jlo, jhi, error); bo_cut = utils::numeric(FLERR, arg[iarg + 3], false, lmp); - if ((itype <= 0) || (jtype <= 0) || (itype > ntypes) || (jtype > ntypes)) - error->all(FLERR, "Fix reaxff/species cutoff atom type(s) out of range"); if ((bo_cut > 1.0) || (bo_cut < 0.0)) error->all(FLERR, "Fix reaxff/species invalid cutoff value: {}", bo_cut); - BOCut[itype][jtype] = bo_cut; - BOCut[jtype][itype] = bo_cut; + for (int i = ilo; i <= ihi; ++i) { + for (int j = MAX(jlo, i); j <= jhi; ++j) { + BOCut[i][j] = bo_cut; + BOCut[j][i] = bo_cut; + } + } iarg += 4; // modify element type names @@ -240,17 +242,21 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : error->all(FLERR, "Unknown fix reaxff/species delete option: {}", arg[iarg]); // rate limit when deleting molecules } else if (strcmp(arg[iarg], "delete_rate_limit") == 0) { - if (iarg + 3 > narg) utils::missing_cmd_args(FLERR, "fix reaxff/species delete_rate_limit", error); + if (iarg + 3 > narg) + utils::missing_cmd_args(FLERR, "fix reaxff/species delete_rate_limit", error); delete_Nlimit_varid = -1; - if (strncmp(arg[iarg+1],"v_",2) == 0) { - delete_Nlimit_varname = &arg[iarg+1][2]; + if (strncmp(arg[iarg + 1], "v_", 2) == 0) { + delete_Nlimit_varname = &arg[iarg + 1][2]; delete_Nlimit_varid = input->variable->find(delete_Nlimit_varname.c_str()); if (delete_Nlimit_varid < 0) - error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",delete_Nlimit_varname); + error->all(FLERR, "Fix reaxff/species: Variable name {} does not exist", + delete_Nlimit_varname); if (!input->variable->equalstyle(delete_Nlimit_varid)) - error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",delete_Nlimit_varname); - } else delete_Nlimit = utils::numeric(FLERR, arg[iarg+1], false, lmp); - delete_Nsteps = utils::numeric(FLERR, arg[iarg+2], false, lmp); + error->all(FLERR, "Fix reaxff/species: Variable {} is not equal-style", + delete_Nlimit_varname); + } else + delete_Nlimit = utils::numeric(FLERR, arg[iarg + 1], false, lmp); + delete_Nsteps = utils::numeric(FLERR, arg[iarg + 2], false, lmp); iarg += 3; // position of molecules } else if (strcmp(arg[iarg], "position") == 0) { @@ -292,10 +298,9 @@ FixReaxFFSpecies::FixReaxFFSpecies(LAMMPS *lmp, int narg, char **arg) : if (delete_Nsteps > 0) { if (lmp->citeme) lmp->citeme->add(cite_reaxff_species_delete); - memory->create(delete_Tcount,delete_Nsteps,"reaxff/species:delete_Tcount"); + memory->create(delete_Tcount, delete_Nsteps, "reaxff/species:delete_Tcount"); - for (int i = 0; i < delete_Nsteps; i++) - delete_Tcount[i] = -1; + for (int i = 0; i < delete_Nsteps; i++) delete_Tcount[i] = -1; delete_Tcount[0] = 0; } @@ -393,9 +398,11 @@ void FixReaxFFSpecies::init() if (delete_Nsteps > 0) { delete_Nlimit_varid = input->variable->find(delete_Nlimit_varname.c_str()); if (delete_Nlimit_varid < 0) - error->all(FLERR,"Fix reaxff/species: Variable name {} does not exist",delete_Nlimit_varname); + error->all(FLERR, "Fix reaxff/species: Variable name {} does not exist", + delete_Nlimit_varname); if (!input->variable->equalstyle(delete_Nlimit_varid)) - error->all(FLERR,"Fix reaxff/species: Variable {} is not equal-style",delete_Nlimit_varname); + error->all(FLERR, "Fix reaxff/species: Variable {} is not equal-style", + delete_Nlimit_varname); } } @@ -427,8 +434,7 @@ void FixReaxFFSpecies::Output_ReaxFF_Bonds(bigint ntimestep, FILE * /*fp*/) if (ntimestep != nvalid) { // push back delete_Tcount on every step if (delete_Nsteps > 0) - for (int i = delete_Nsteps-1; i > 0; i--) - delete_Tcount[i] = delete_Tcount[i-1]; + for (int i = delete_Nsteps - 1; i > 0; i--) delete_Tcount[i] = delete_Tcount[i - 1]; return; } @@ -732,31 +738,31 @@ void FixReaxFFSpecies::WriteFormulas(int Nmole, int Nspec) int i, j, itemp; bigint ntimestep = update->ntimestep; - fprintf(fp, "# Timestep No_Moles No_Specs "); + fprintf(fp, "# Timestep No_Moles No_Specs"); Nmoltype = 0; for (i = 0; i < Nspec; i++) nd[i] = CheckExistence(i, ntypes); for (i = 0; i < Nmoltype; i++) { + std::string molname; for (j = 0; j < ntypes; j++) { itemp = MolType[ntypes * i + j]; if (itemp != 0) { if (eletype) - fprintf(fp, "%s", eletype[j]); + molname += eletype[j]; else - fprintf(fp, "%c", ele[j]); - if (itemp != 1) fprintf(fp, "%d", itemp); + molname += ele[j]; + if (itemp != 1) molname += std::to_string(itemp); } } - fputs("\t", fp); + fmt::print(fp, " {:>11}", molname); } fputs("\n", fp); - fmt::print(fp, "{} {:11} {:11}\t", ntimestep, Nmole, Nspec); - - for (i = 0; i < Nmoltype; i++) fprintf(fp, " %d\t", NMol[i]); - fprintf(fp, "\n"); + fmt::print(fp, "{:>11} {:>11} {:>11}", ntimestep, Nmole, Nspec); + for (i = 0; i < Nmoltype; i++) fmt::print(fp, " {:>11}", NMol[i]); + fputs("\n", fp); } /* ---------------------------------------------------------------------- */ @@ -884,8 +890,8 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) int ndeletions; int headroom = -1; if (delete_Nsteps > 0) { - if (delete_Tcount[delete_Nsteps-1] == -1) return; - ndeletions = delete_Tcount[0] - delete_Tcount[delete_Nsteps-1]; + if (delete_Tcount[delete_Nsteps - 1] == -1) return; + ndeletions = delete_Tcount[0] - delete_Tcount[delete_Nsteps - 1]; if (delete_Nlimit_varid > -1) delete_Nlimit = input->variable->compute_equal(delete_Nlimit_varid); headroom = MAX(0, delete_Nlimit - ndeletions); @@ -925,13 +931,11 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) std::random_device rnd; std::minstd_rand park_rng(rnd()); int *molrange; - memory->create(molrange,Nmole,"reaxff/species:molrange"); - for (m = 0; m < Nmole; m++) - molrange[m] = m + 1; + memory->create(molrange, Nmole, "reaxff/species:molrange"); + for (m = 0; m < Nmole; m++) molrange[m] = m + 1; if (delete_Nsteps > 0) { // shuffle index when using rate_limit, in case order is biased - if (comm->me == 0) - std::shuffle(&molrange[0],&molrange[Nmole], park_rng); + if (comm->me == 0) std::shuffle(&molrange[0], &molrange[Nmole], park_rng); MPI_Bcast(&molrange[0], Nmole, MPI_INT, 0, world); } @@ -1060,11 +1064,9 @@ void FixReaxFFSpecies::DeleteSpecies(int Nmole, int Nspec) } } - // push back delete_Tcount on every step if (delete_Nsteps > 0) { - for (i = delete_Nsteps-1; i > 0; i--) - delete_Tcount[i] = delete_Tcount[i-1]; + for (i = delete_Nsteps - 1; i > 0; i--) delete_Tcount[i] = delete_Tcount[i - 1]; delete_Tcount[0] += this_delete_Tcount; } diff --git a/src/REAXFF/fix_reaxff_species.h b/src/REAXFF/fix_reaxff_species.h index 27efa0f915..f711cdeb11 100644 --- a/src/REAXFF/fix_reaxff_species.h +++ b/src/REAXFF/fix_reaxff_species.h @@ -51,8 +51,6 @@ class FixReaxFFSpecies : public Fix { int *Mol2Spec; double *clusterID; AtomCoord *x0; - - double bg_cut; double **BOCut; std::vector del_species; From 36cac1e83deba7aa03f6122128f6fdf5244ff1bc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 12:45:41 -0400 Subject: [PATCH 366/448] make sure the field_data vector size always matches the size of the keywords vector --- src/thermo.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/thermo.cpp b/src/thermo.cpp index c6e71354ff..6122edec83 100644 --- a/src/thermo.cpp +++ b/src/thermo.cpp @@ -1068,6 +1068,8 @@ void Thermo::parse_fields(const std::string &str) } } } + field_data.clear(); + field_data.resize(nfield); } /* ---------------------------------------------------------------------- From a2c968386ed31621e288b63b954243d5ae8a9c4e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 12:46:00 -0400 Subject: [PATCH 367/448] include versionadded tag --- src/library.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/library.cpp b/src/library.cpp index 36d53c3e6c..02758abcda 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -756,6 +756,8 @@ double lammps_get_thermo(void *handle, const char *keyword) * \verbatim embed:rst +.. versionadded:: TBD + This function provides access to cached data from the last thermo output. This differs from :cpp:func:`lammps_get_thermo` in that it does not trigger an evaluation. Instead it provides direct access to a read-only location From 8ddac8cf0229212b046f6eca6b29c4829d319df0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 12:46:41 -0400 Subject: [PATCH 368/448] search through the python folders recursive to detect all pending version tags --- tools/coding_standard/versiontags.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/coding_standard/versiontags.py b/tools/coding_standard/versiontags.py index 0b4597046f..ec512a3fad 100644 --- a/tools/coding_standard/versiontags.py +++ b/tools/coding_standard/versiontags.py @@ -21,7 +21,7 @@ DEFAULT_CONFIG = """ recursive: true include: - doc/src/** - - python + - python/** - src/** exclude: - src/Make.sh From 3f6032e80d05039f538aac19f7916102520e08ee Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 13:03:28 -0400 Subject: [PATCH 369/448] add python module interface to lammps_last_thermo, small consistency fixes --- python/lammps/core.py | 54 +++++++++++++++++++++++++++++++++++++++++++ src/library.cpp | 6 ++--- src/library.h | 2 +- 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index 80961186f3..932d4b863c 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -272,6 +272,9 @@ class lammps(object): self.lib.lammps_get_thermo.argtypes = [c_void_p, c_char_p] self.lib.lammps_get_thermo.restype = c_double + self.lib.lammps_last_thermo.argtypes = [c_void_p, c_char_p, c_int] + self.lib.lammps_last_thermo.restype = c_void_p + self.lib.lammps_encode_image_flags.restype = self.c_imageint self.lib.lammps_config_has_package.argtypes = [c_char_p] @@ -744,6 +747,57 @@ class lammps(object): # ------------------------------------------------------------------------- + def last_thermo(self): + """Get a dictionary of the last thermodynamic output + + This is a wrapper around the :cpp:func:`lammps_last_thermo` + function of the C-library interface. It collects the cached thermo + data from the last timestep into a dictionary. The return value + is None, if there has not been any thermo output yet. + + :return: value of thermo keyword + :rtype: dict or None + """ + + rv = dict() + with ExceptionCheck(self): + ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("step".encode()), 0) + mystep = cast(ptr, POINTER(self.c_bigint)).contents.value + if mystep < 0: + return None + + with ExceptionCheck(self): + ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("num".encode()), 0) + nfield = cast(ptr, POINTER(c_int)).contents.value + + for i in range(nfield): + with ExceptionCheck(self): + ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("keyword".encode()), i) + kw = cast(ptr, c_char_p).value.decode() + + # temporarily switch return type since this stores an int in a pointer + self.lib.lammps_last_thermo.restype = c_int + with ExceptionCheck(self): + typ = self.lib.lammps_last_thermo(self.lmp, c_char_p("type".encode()), i) + self.lib.lammps_last_thermo.restype = c_void_p + with ExceptionCheck(self): + ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("data".encode()), i) + + if typ == LAMMPS_DOUBLE: + val = cast(ptr, POINTER(c_double)).contents.value + elif typ == LAMMPS_INT: + val = cast(ptr, POINTER(c_int)).contents.value + elif typ == LAMMPS_INT64: + val = cast(ptr, POINTER(c_int64)).contents.value + else: + # we should not get here + raise TypeError("Unknown LAMMPS data type " + str(typ)) + rv[kw] = val + + return rv + + # ------------------------------------------------------------------------- + def extract_setting(self, name): """Query LAMMPS about global settings that can be expressed as an integer. diff --git a/src/library.cpp b/src/library.cpp index 02758abcda..cf5d131ba6 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -783,15 +783,15 @@ argument string. - no * - keyword - column keyword for thermo output - - const char pointer + - pointer to 0-terminated const char array - yes * - type - data type of thermo output column; see :cpp:enum:`_LMP_DATATYPE_CONST` - - const int + - const int (**not** a pointer) - yes * - data - actual field data for column - - pointer to either int, int64_t or double + - pointer to int, int64_t or double - yes \endverbatim diff --git a/src/library.h b/src/library.h index 4c2530210c..5f46e36ccf 100644 --- a/src/library.h +++ b/src/library.h @@ -148,7 +148,7 @@ void lammps_commands_string(void *handle, const char *str); double lammps_get_natoms(void *handle); double lammps_get_thermo(void *handle, const char *keyword); -void *lammps_last_thermo(void *handle, const char *what, int idx); +void *lammps_last_thermo(void *handle, const char *what, int index); void lammps_extract_box(void *handle, double *boxlo, double *boxhi, double *xy, double *yz, double *xz, int *pflags, int *boxflag); From b093f1aac19f056e0decfccef23f95d24cd6d44f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 13:11:19 -0400 Subject: [PATCH 370/448] move versionadded tags to the top, replace some missed TBD with version info --- python/lammps/core.py | 71 ++++++++-------- python/lammps/numpy_wrapper.py | 28 +++---- src/library.cpp | 144 +++++++++++++++++---------------- 3 files changed, 125 insertions(+), 118 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index 932d4b863c..b15ddf9302 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -506,9 +506,9 @@ class lammps(object): def error(self, error_type, error_text): """Forward error to the LAMMPS Error class. - This is a wrapper around the :cpp:func:`lammps_error` function of the C-library interface. + .. versionadded:: 3Nov2022 - .. versionadded:: TBD + This is a wrapper around the :cpp:func:`lammps_error` function of the C-library interface. :param error_type: :type error_type: int @@ -1343,6 +1343,8 @@ class lammps(object): def gather_bonds(self): """Retrieve global list of bonds + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_gather_bonds` function of the C-library interface. @@ -1350,8 +1352,6 @@ class lammps(object): flat list of ctypes integer values with the bond type, bond atom1, bond atom2 for each bond. - .. versionadded:: 28Jul2021 - :return: a tuple with the number of bonds and a list of c_int or c_long :rtype: (int, 3*nbonds*c_tagint) """ @@ -1366,6 +1366,8 @@ class lammps(object): def gather_angles(self): """Retrieve global list of angles + .. versionadded:: 8Feb2023 + This is a wrapper around the :cpp:func:`lammps_gather_angles` function of the C-library interface. @@ -1373,8 +1375,6 @@ class lammps(object): flat list of ctypes integer values with the angle type, angle atom1, angle atom2, angle atom3 for each angle. - .. versionadded:: TBD - :return: a tuple with the number of angles and a list of c_int or c_long :rtype: (int, 4*nangles*c_tagint) """ @@ -1389,6 +1389,8 @@ class lammps(object): def gather_dihedrals(self): """Retrieve global list of dihedrals + .. versionadded:: 8Feb2023 + This is a wrapper around the :cpp:func:`lammps_gather_dihedrals` function of the C-library interface. @@ -1396,8 +1398,6 @@ class lammps(object): flat list of ctypes integer values with the dihedral type, dihedral atom1, dihedral atom2, dihedral atom3, dihedral atom4 for each dihedral. - .. versionadded:: TBD - :return: a tuple with the number of dihedrals and a list of c_int or c_long :rtype: (int, 5*ndihedrals*c_tagint) """ @@ -1412,6 +1412,8 @@ class lammps(object): def gather_impropers(self): """Retrieve global list of impropers + .. versionadded:: 8Feb2023 + This is a wrapper around the :cpp:func:`lammps_gather_impropers` function of the C-library interface. @@ -1419,8 +1421,6 @@ class lammps(object): flat list of ctypes integer values with the improper type, improper atom1, improper atom2, improper atom3, improper atom4 for each improper. - .. versionadded:: TBD - :return: a tuple with the number of impropers and a list of c_int or c_long :rtype: (int, 5*nimpropers*c_tagint) """ @@ -1659,13 +1659,13 @@ class lammps(object): def is_running(self): """ Report whether being called from a function during a run or a minimization + .. versionadded:: 9Oct2020 + Various LAMMPS commands must not be called during an ongoing run or minimization. This property allows to check for that. This is a wrapper around the :cpp:func:`lammps_is_running` function of the library interface. - .. versionadded:: 9Oct2020 - :return: True when called during a run otherwise false :rtype: bool """ @@ -1676,12 +1676,13 @@ class lammps(object): def force_timeout(self): """ Trigger an immediate timeout, i.e. a "soft stop" of a run. + .. versionadded:: 9Oct2020 + This function allows to cleanly stop an ongoing run or minimization at the next loop iteration. This is a wrapper around the :cpp:func:`lammps_force_timeout` function of the library interface. - .. versionadded:: 9Oct2020 """ self.lib.lammps_force_timeout(self.lmp) @@ -1764,11 +1765,11 @@ class lammps(object): def has_package(self, name): """ Report if the named package has been enabled in the LAMMPS shared library. + .. versionadded:: 3Nov2022 + This is a wrapper around the :cpp:func:`lammps_config_has_package` function of the library interface. - .. versionadded:: TBD - :param name: name of the package :type name: string @@ -1908,11 +1909,11 @@ class lammps(object): def has_id(self, category, name): """Returns whether a given ID name is available in a given category + .. versionadded:: 9Oct2020 + This is a wrapper around the function :cpp:func:`lammps_has_id` of the library interface. - .. versionadded:: 9Oct2020 - :param category: name of category :type category: string :param name: name of the ID @@ -1928,11 +1929,11 @@ class lammps(object): def available_ids(self, category): """Returns a list of IDs available for a given category + .. versionadded:: 9Oct2020 + This is a wrapper around the functions :cpp:func:`lammps_id_count()` and :cpp:func:`lammps_id_name()` of the library interface. - .. versionadded:: 9Oct2020 - :param category: name of category :type category: string @@ -1955,11 +1956,11 @@ class lammps(object): def available_plugins(self, category): """Returns a list of plugins available for a given category + .. versionadded:: 10Mar2021 + This is a wrapper around the functions :cpp:func:`lammps_plugin_count()` and :cpp:func:`lammps_plugin_name()` of the library interface. - .. versionadded:: 10Mar2021 - :return: list of style/name pairs of loaded plugins :rtype: list """ @@ -2024,11 +2025,11 @@ class lammps(object): def fix_external_get_force(self, fix_id): """Get access to the array with per-atom forces of a fix external instance with a given fix ID. + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_fix_external_get_force` function of the C-library interface. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :return: requested data @@ -2043,11 +2044,11 @@ class lammps(object): def fix_external_set_energy_global(self, fix_id, eng): """Set the global energy contribution for a fix external instance with the given ID. + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_fix_external_set_energy_global` function of the C-library interface. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param eng: potential energy value to be added by fix external @@ -2062,11 +2063,11 @@ class lammps(object): def fix_external_set_virial_global(self, fix_id, virial): """Set the global virial contribution for a fix external instance with the given ID. + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_fix_external_set_virial_global` function of the C-library interface. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param eng: list of 6 floating point numbers with the virial to be added by fix external @@ -2082,11 +2083,11 @@ class lammps(object): def fix_external_set_energy_peratom(self, fix_id, eatom): """Set the per-atom energy contribution for a fix external instance with the given ID. + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_fix_external_set_energy_peratom` function of the C-library interface. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param eatom: list of potential energy values for local atoms to be added by fix external @@ -2105,11 +2106,11 @@ class lammps(object): def fix_external_set_virial_peratom(self, fix_id, vatom): """Set the per-atom virial contribution for a fix external instance with the given ID. + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_fix_external_set_virial_peratom` function of the C-library interface. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param vatom: list of natoms lists with 6 floating point numbers to be added by fix external @@ -2137,11 +2138,11 @@ class lammps(object): def fix_external_set_vector_length(self, fix_id, length): """Set the vector length for a global vector stored with fix external for analysis + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_fix_external_set_vector_length` function of the C-library interface. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param length: length of the global vector @@ -2155,11 +2156,11 @@ class lammps(object): def fix_external_set_vector(self, fix_id, idx, val): """Store a global vector value for a fix external instance with the given ID. + .. versionadded:: 28Jul2021 + This is a wrapper around the :cpp:func:`lammps_fix_external_set_vector` function of the C-library interface. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param idx: 1-based index of the value in the global vector diff --git a/python/lammps/numpy_wrapper.py b/python/lammps/numpy_wrapper.py index 8286fb9a5c..f3ea0fdf8e 100644 --- a/python/lammps/numpy_wrapper.py +++ b/python/lammps/numpy_wrapper.py @@ -262,12 +262,12 @@ class numpy_wrapper: def gather_bonds(self): """Retrieve global list of bonds as NumPy array + .. versionadded:: 28Jul2021 + This is a wrapper around :py:meth:`lammps.gather_bonds() ` It behaves the same as the original method, but returns a NumPy array instead of a ``ctypes`` list. - .. versionadded:: 28Jul2021 - :return: the requested data as a 2d-integer numpy array :rtype: numpy.array(nbonds,3) """ @@ -280,12 +280,12 @@ class numpy_wrapper: def gather_angles(self): """ Retrieve global list of angles as NumPy array + .. versionadded:: 8Feb2023 + This is a wrapper around :py:meth:`lammps.gather_angles() ` It behaves the same as the original method, but returns a NumPy array instead of a ``ctypes`` list. - .. versionadded:: TBD - :return: the requested data as a 2d-integer numpy array :rtype: numpy.array(nangles,4) """ @@ -298,12 +298,12 @@ class numpy_wrapper: def gather_dihedrals(self): """ Retrieve global list of dihedrals as NumPy array + .. versionadded:: 8Feb2023 + This is a wrapper around :py:meth:`lammps.gather_dihedrals() ` It behaves the same as the original method, but returns a NumPy array instead of a ``ctypes`` list. - .. versionadded:: TBD - :return: the requested data as a 2d-integer numpy array :rtype: numpy.array(ndihedrals,5) """ @@ -316,12 +316,12 @@ class numpy_wrapper: def gather_impropers(self): """ Retrieve global list of impropers as NumPy array + .. versionadded:: 8Feb2023 + This is a wrapper around :py:meth:`lammps.gather_impropers() ` It behaves the same as the original method, but returns a NumPy array instead of a ``ctypes`` list. - .. versionadded:: TBD - :return: the requested data as a 2d-integer numpy array :rtype: numpy.array(nimpropers,5) """ @@ -334,13 +334,13 @@ class numpy_wrapper: def fix_external_get_force(self, fix_id): """Get access to the array with per-atom forces of a fix external instance with a given fix ID. + .. versionchanged:: 28Jul2021 + This function is a wrapper around the :py:meth:`lammps.fix_external_get_force() ` method. It behaves the same as the original method, but returns a NumPy array instead of a ``ctypes`` pointer. - .. versionchanged:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :return: requested data @@ -356,13 +356,13 @@ class numpy_wrapper: def fix_external_set_energy_peratom(self, fix_id, eatom): """Set the per-atom energy contribution for a fix external instance with the given ID. + .. versionadded:: 28Jul2021 + This function is an alternative to :py:meth:`lammps.fix_external_set_energy_peratom() ` method. It behaves the same as the original method, but accepts a NumPy array instead of a list as argument. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param eatom: per-atom potential energy @@ -383,13 +383,13 @@ class numpy_wrapper: def fix_external_set_virial_peratom(self, fix_id, vatom): """Set the per-atom virial contribution for a fix external instance with the given ID. + .. versionadded:: 28Jul2021 + This function is an alternative to :py:meth:`lammps.fix_external_set_virial_peratom() ` method. It behaves the same as the original method, but accepts a NumPy array instead of a list as argument. - .. versionadded:: 28Jul2021 - :param fix_id: Fix-ID of a fix external instance :type: string :param eatom: per-atom potential energy diff --git a/src/library.cpp b/src/library.cpp index cf5d131ba6..24a8afa7c7 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -247,6 +247,8 @@ void *lammps_open_no_mpi(int argc, char **argv, void **ptr) * \verbatim embed:rst +.. versionadded:: 18Sep2020 + This function is a version of :cpp:func:`lammps_open`, that uses an integer for the MPI communicator as the MPI Fortran interface does. It is used in the :f:func:`lammps` constructor of the LAMMPS Fortran @@ -257,8 +259,6 @@ communicator with ``MPI_Comm_f2c()`` and then calls If for some reason the creation or initialization of the LAMMPS instance fails a null pointer is returned. -.. versionadded:: 18Sep2020 - *See also* :cpp:func:`lammps_open_fortran`, :cpp:func:`lammps_open_no_mpi` @@ -304,13 +304,13 @@ void lammps_close(void *handle) * \verbatim embed:rst +.. versionadded:: 18Sep2020 + The MPI standard requires that any MPI application must call ``MPI_Init()`` exactly once before performing any other MPI function calls. This function checks, whether MPI is already initialized and calls ``MPI_Init()`` in case it is not. -.. versionadded:: 18Sep2020 - \endverbatim */ void lammps_mpi_init() @@ -333,6 +333,8 @@ void lammps_mpi_init() * \verbatim embed:rst +.. versionadded:: 18Sep2020 + The MPI standard requires that any MPI application calls ``MPI_Finalize()`` before exiting. Even if a calling program does not do any MPI calls, MPI is still initialized internally to avoid errors @@ -341,8 +343,6 @@ before exiting the program to wait until all (parallel) tasks are completed and then MPI is cleanly shut down. After calling this function no more MPI calls may be made. -.. versionadded:: 18Sep2020 - *See also* :cpp:func:`lammps_kokkos_finalize`, :cpp:func:`lammps_python_finalize` \endverbatim */ @@ -366,6 +366,8 @@ void lammps_mpi_finalize() * \verbatim embed:rst +.. versionadded:: 2Jul2021 + The Kokkos library may only be initialized once during the execution of a process. This is done automatically the first time Kokkos functionality is used. This requires that the Kokkos environment @@ -373,8 +375,6 @@ must be explicitly shut down after any LAMMPS instance using it is closed (to release associated resources). After calling this function no Kokkos functionality may be used. -.. versionadded:: 2Jul2021 - *See also* :cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_python_finalize` \endverbatim */ @@ -390,6 +390,8 @@ void lammps_kokkos_finalize() * \verbatim embed:rst +.. versionadded:: 20Sep2021 + This function resets and clears an embedded Python environment by calling the `Py_Finalize() function `_ @@ -409,8 +411,6 @@ after calling Py_Finalize(). This function can be called to explicitly clear the Python environment in case it is safe to do so. -.. versionadded:: 20Sep2021 - *See also* :cpp:func:`lammps_mpi_finalize`, :cpp:func:`lammps_kokkos_finalize` \endverbatim */ @@ -427,6 +427,8 @@ void lammps_python_finalize() * \verbatim embed:rst +.. versionadded:: 3Nov2022 + This function is a wrapper around functions in the ``Error`` to print an error message and then stop LAMMPS. @@ -435,8 +437,6 @@ of constants from :cpp:enum:`_LMP_ERROR_CONST`. If the value does not match any valid combination of constants a warning is printed and the function returns. -.. versionadded:: 3Nov2022 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance @@ -979,6 +979,8 @@ void lammps_reset_box(void *handle, double *boxlo, double *boxhi, * \verbatim embed:rst +.. versionadded:: 18Sep2020 + This function will retrieve memory usage information for the current LAMMPS instance or process. The *meminfo* buffer will be filled with 3 different numbers (if supported by the operating system). The first @@ -991,8 +993,6 @@ third number is the maximum amount of RAM (not swap) used by the process so far. If any of the two latter parameters is not supported by the operating system it will be set to zero. -.. versionadded:: 18Sep2020 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance @@ -1012,6 +1012,8 @@ void lammps_memory_usage(void *handle, double *meminfo) * \verbatim embed:rst +.. versionadded:: 18Sep2020 + This will take the LAMMPS "world" communicator and convert it to an integer using ``MPI_Comm_c2f()``, so it is equivalent to the corresponding MPI communicator in Fortran. This way it can be safely @@ -1020,8 +1022,6 @@ to the C language representation use ``MPI_Comm_f2c()``. If LAMMPS was compiled with MPI_STUBS, this function returns -1. -.. versionadded:: 18Sep2020 - *See also* :cpp:func:`lammps_open_fortran` @@ -1284,13 +1284,13 @@ int lammps_extract_setting(void *handle, const char *keyword) * \verbatim embed:rst +.. versionadded:: 18Sep2020 + This function returns an integer that encodes the data type of the global property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid values. Callers of :cpp:func:`lammps_extract_global` can use this information to then decide how to cast the ``void *`` pointer and access the data. -.. versionadded:: 18Sep2020 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance (unused) @@ -1773,13 +1773,13 @@ void *lammps_extract_global(void *handle, const char *name) * \verbatim embed:rst +.. versionadded:: 18Sep2020 + This function returns an integer that encodes the data type of the per-atom property with the specified name. See :cpp:enum:`_LMP_DATATYPE_CONST` for valid values. Callers of :cpp:func:`lammps_extract_atom` can use this information to then decide how to cast the ``void *`` pointer and access the data. -.. versionadded:: 18Sep2020 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance @@ -2308,13 +2308,13 @@ void *lammps_extract_variable(void *handle, const char *name, const char *group) * \verbatim embed:rst +.. versionadded:: 3Nov2022 + This function returns an integer that encodes the data type of the variable with the specified name. See :cpp:enum:`_LMP_VAR_CONST` for valid values. Callers of :cpp:func:`lammps_extract_variable` can use this information to decide how to cast the ``void *`` pointer and access the data. -.. versionadded:: 3Nov2022 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance @@ -3166,6 +3166,8 @@ void lammps_scatter_atoms_subset(void *handle, const char *name, int type, * \verbatim embed:rst +.. versionadded:: 28Jul2021 + This function copies the list of all bonds into a buffer provided by the calling code. The buffer will be filled with bond type, bond atom 1, bond atom 2 for each bond. Thus the buffer has to be allocated to the @@ -3180,8 +3182,6 @@ When running in parallel, the data buffer must be allocated on **all** MPI ranks and will be filled with the information for **all** bonds in the system. -.. versionadded:: 28Jul2021 - Below is a brief C code demonstrating accessing this collected bond information. .. code-block:: c @@ -3277,6 +3277,8 @@ void lammps_gather_bonds(void *handle, void *data) * \verbatim embed:rst +.. versionadded:: 8Feb2023 + This function copies the list of all angles into a buffer provided by the calling code. The buffer will be filled with angle type, angle atom 1, angle atom 2, angle atom 3 for each angle. Thus the buffer has to be allocated to the @@ -3291,8 +3293,6 @@ When running in parallel, the data buffer must be allocated on **all** MPI ranks and will be filled with the information for **all** angles in the system. -.. versionadded:: 8Feb2023 - Below is a brief C code demonstrating accessing this collected angle information. .. code-block:: c @@ -3388,6 +3388,8 @@ void lammps_gather_angles(void *handle, void *data) * \verbatim embed:rst +.. versionadded:: 8Feb2023 + This function copies the list of all dihedrals into a buffer provided by the calling code. The buffer will be filled with dihedral type, dihedral atom 1, dihedral atom 2, dihedral atom 3, dihedral atom 4 for each dihedral. @@ -3403,8 +3405,6 @@ When running in parallel, the data buffer must be allocated on **all** MPI ranks and will be filled with the information for **all** dihedrals in the system. -.. versionadded:: 8Feb2023 - Below is a brief C code demonstrating accessing this collected dihedral information. .. code-block:: c @@ -3500,6 +3500,8 @@ void lammps_gather_dihedrals(void *handle, void *data) * \verbatim embed:rst +.. versionadded:: 8Feb2023 + This function copies the list of all impropers into a buffer provided by the calling code. The buffer will be filled with improper type, improper atom 1, improper atom 2, improper atom 3, improper atom 4 for each improper. @@ -3515,8 +3517,6 @@ When running in parallel, the data buffer must be allocated on **all** MPI ranks and will be filled with the information for **all** impropers in the system. -.. versionadded:: 8Feb2023 - Below is a brief C code demonstrating accessing this collected improper information. .. code-block:: c @@ -5310,6 +5310,8 @@ int lammps_version(void *handle) * \verbatim embed:rst +.. versionadded:: 9Oct2020 + The :cpp:func:`lammps_get_os_info` function can be used to retrieve detailed information about the hosting operating system and compiler/runtime. @@ -5318,8 +5320,6 @@ A suitable buffer for a C-style string has to be provided and its length. The assembled text will be truncated to not overflow this buffer. The string is typically a few hundred bytes long. -.. versionadded:: 9Oct2020 - \endverbatim * * \param buffer string buffer to copy the information to @@ -5548,6 +5548,8 @@ int lammps_config_accelerator(const char *package, * \verbatim embed:rst +.. versionadded:: 14May2021 + The :cpp:func:`lammps_has_gpu_device` function checks at runtime if an accelerator device is present that can be used with the :doc:`GPU package `. If at least one suitable device is @@ -5557,8 +5559,6 @@ More detailed information about the available device or devices can be obtained by calling the :cpp:func:`lammps_get_gpu_device_info` function. -.. versionadded:: 14May2021 - \endverbatim * * \return 1 if viable device is available, 0 if not. */ @@ -5572,6 +5572,8 @@ int lammps_has_gpu_device() * \verbatim embed:rst +.. versionadded:: 14May2021 + The :cpp:func:`lammps_get_gpu_device_info` function can be used to retrieve detailed information about any accelerator devices that are viable for use with the :doc:`GPU package `. It will produce a string that is @@ -5583,8 +5585,6 @@ A suitable buffer for a C-style string has to be provided and its length. The assembled text will be truncated to not overflow this buffer. This string can be several kilobytes long, if multiple devices are present. -.. versionadded:: 14May2021 - \endverbatim * * \param buffer string buffer to copy the information to @@ -5681,12 +5681,13 @@ int lammps_style_name(void *handle, const char *category, int idx, /** Check if a specific ID exists in the current LAMMPS instance * \verbatim embed:rst + +.. versionadded:: 9Oct2020 + This function checks if the current LAMMPS instance a *category* ID of the given *name* exists. Valid categories are: *compute*\ , *dump*\ , *fix*\ , *group*\ , *molecule*\ , *region*\ , and *variable*\ . -.. versionadded:: 9Oct2020 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -5720,13 +5721,14 @@ int lammps_has_id(void *handle, const char *category, const char *name) { /** Count the number of IDs of a category. * \verbatim embed:rst + +.. versionadded:: 9Oct2020 + This function counts how many IDs in the provided *category* are defined in the current LAMMPS instance. Please see :cpp:func:`lammps_has_id` for a list of valid categories. -.. versionadded:: 9Oct2020 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -5758,6 +5760,9 @@ int lammps_id_count(void *handle, const char *category) { /** Look up the name of an ID by index in the list of IDs of a given category. * \verbatim embed:rst + +.. versionadded:: 9Oct2020 + This function copies the name of the *category* ID with the index *idx* into the provided C-style string buffer. The length of the buffer must be provided as *buf_size* argument. If the name of the style @@ -5765,8 +5770,6 @@ exceeds the length of the buffer, it will be truncated accordingly. If the index is out of range, the function returns 0 and *buffer* is set to an empty string, otherwise 1. -.. versionadded:: 9Oct2020 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -5829,10 +5832,11 @@ int lammps_id_name(void *handle, const char *category, int idx, char *buffer, in /** Count the number of loaded plugins * \verbatim embed:rst -This function counts how many plugins are currently loaded. .. versionadded:: 10Mar2021 +This function counts how many plugins are currently loaded. + \endverbatim * * \return number of loaded plugins @@ -5851,6 +5855,9 @@ int lammps_plugin_count() /** Look up the info of a loaded plugin by its index in the list of plugins * \verbatim embed:rst + +.. versionadded:: 10Mar2021 + This function copies the name of the *style* plugin with the index *idx* into the provided C-style string buffer. The length of the buffer must be provided as *buf_size* argument. If the name of the style @@ -5858,8 +5865,6 @@ exceeds the length of the buffer, it will be truncated accordingly. If the index is out of range, the function returns 0 and *buffer* is set to an empty string, otherwise 1. -.. versionadded:: 10Mar2021 - \endverbatim * * \param idx index of the plugin in the list all or *style* plugins @@ -6018,9 +6023,11 @@ void lammps_set_fix_external_callback(void *handle, const char *id, FixExternalF \verbatim embed:rst -Fix :doc:`external ` allows programs that are running LAMMPS through -its library interface to add or modify certain LAMMPS properties on specific -timesteps, similar to the way other fixes do. +.. versionadded:: 28Jul2021 + +Fix :doc:`external ` allows programs that are running +LAMMPS through its library interface to add or modify certain LAMMPS +properties on specific timesteps, similar to the way other fixes do. This function provides access to the per-atom force storage in a fix external instance with the given fix-ID to be added to the individual @@ -6033,12 +6040,12 @@ data structures can change as well as the order of atom as they migrate between MPI processes because of the domain decomposition parallelization, this function should be always called immediately before the forces are going to be set to get an up-to-date pointer. -You can use, for example, :cpp:func:`lammps_extract_setting` to obtain the -number of local atoms `nlocal` and then assume the dimensions of the returned -force array as ``double force[nlocal][3]``. +You can use, for example, :cpp:func:`lammps_extract_setting` to obtain +the number of local atoms `nlocal` and then assume the dimensions of +the returned force array as ``double force[nlocal][3]``. -This is an alternative to the callback mechanism in fix external set up by -:cpp:func:`lammps_set_fix_external_callback`. The main difference is +This is an alternative to the callback mechanism in fix external set up +by :cpp:func:`lammps_set_fix_external_callback`. The main difference is that this mechanism can be used when forces are be pre-computed and the control alternates between LAMMPS and the external code, while the callback mechanism can call the external code to compute the force when @@ -6048,8 +6055,6 @@ Please see the documentation for :doc:`fix external ` for more information about how to use the fix and how to couple it with an external code. -.. versionadded:: 28Jul2021 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -6080,6 +6085,8 @@ double **lammps_fix_external_get_force(void *handle, const char *id) \verbatim embed:rst +.. versionadded:: 28Jul2021 + This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and :cpp:func:`lammps_fix_external_get_force` to also set the contribution to the global energy from the external code. The value of the *eng* @@ -6096,8 +6103,6 @@ Please see the documentation for :doc:`fix external ` for more information about how to use the fix and how to couple it with an external code. -.. versionadded:: 28Jul2021 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -6126,6 +6131,8 @@ void lammps_fix_external_set_energy_global(void *handle, const char *id, double \verbatim embed:rst +.. versionadded:: 28Jul2021 + This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and :cpp:func:`lammps_fix_external_get_force` to set the contribution to the global virial from the external code. @@ -6144,8 +6151,6 @@ Please see the documentation for :doc:`fix external ` for more information about how to use the fix and how to couple it with an external code. -.. versionadded:: 28Jul2021 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -6174,6 +6179,8 @@ void lammps_fix_external_set_virial_global(void *handle, const char *id, double \verbatim embed:rst +.. versionadded:: 28Jul2021 + This is a companion function to :cpp:func:`lammps_set_fix_external_callback` to set the per-atom energy contribution due to the fix from the external code as part of the callback function. For this to work, the handle to the @@ -6192,8 +6199,6 @@ Please see the documentation for :doc:`fix external ` for more information about how to use the fix and how to couple it with an external code. -.. versionadded:: 28Jul2021 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -6222,6 +6227,8 @@ void lammps_fix_external_set_energy_peratom(void *handle, const char *id, double \verbatim embed:rst +.. versionadded:: 28Jul2021 + This is a companion function to :cpp:func:`lammps_set_fix_external_callback` to set the per-atom virial contribution due to the fix from the external code as part of the callback function. For this to work, the handle to the @@ -6243,8 +6250,6 @@ Please see the documentation for :doc:`fix external ` for more information about how to use the fix and how to couple it with an external code. -.. versionadded:: 28Jul2021 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -6273,6 +6278,8 @@ void lammps_fix_external_set_virial_peratom(void *handle, const char *id, double \verbatim embed:rst +.. versionadded:: 28Jul2021 + This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and :cpp:func:`lammps_fix_external_get_force` to set the length of a global vector of properties that will be stored with the fix via @@ -6287,8 +6294,6 @@ Please see the documentation for :doc:`fix external ` for more information about how to use the fix and how to couple it with an external code. -.. versionadded:: 28Jul2021 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -6317,6 +6322,8 @@ void lammps_fix_external_set_vector_length(void *handle, const char *id, int len \verbatim embed:rst +.. versionadded:: 28Jul2021 + This is a companion function to :cpp:func:`lammps_set_fix_external_callback` and :cpp:func:`lammps_fix_external_get_force` to set the values of a global vector of properties that will be stored with the fix. And can be accessed from @@ -6340,8 +6347,6 @@ Please see the documentation for :doc:`fix external ` for more information about how to use the fix and how to couple it with an external code. -.. versionadded:: 28Jul2021 - \endverbatim * * \param handle pointer to a previously created LAMMPS instance cast to ``void *``. @@ -6513,12 +6518,13 @@ int lammps_get_last_error_message(void *handle, char *buffer, int buf_size) { /** Return API version of embedded Python interpreter \verbatim embed:rst + +.. versionadded:: 3Nov2022 + This function is used by the ML-IAP python code (mliappy) to verify the API version of the embedded python interpreter of the PYTHON package. It returns -1 if the PYTHON package is not enabled. -.. versionadded:: 3Nov2022 - \endverbatim * * \return PYTHON_API_VERSION constant of the python interpreter or -1 */ From 81854cd03e1903e6fc545f1e27028e65d1864385 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 14:55:45 -0400 Subject: [PATCH 371/448] change type keyword to return a pointer to static location for better portability --- python/lammps/core.py | 7 +++---- src/library.cpp | 19 +++++++++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index b15ddf9302..d34d5de4d4 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -775,11 +775,10 @@ class lammps(object): ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("keyword".encode()), i) kw = cast(ptr, c_char_p).value.decode() - # temporarily switch return type since this stores an int in a pointer - self.lib.lammps_last_thermo.restype = c_int with ExceptionCheck(self): - typ = self.lib.lammps_last_thermo(self.lmp, c_char_p("type".encode()), i) - self.lib.lammps_last_thermo.restype = c_void_p + ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("type".encode()), i) + typ = cast(ptr, POINTER(c_int)).contents.value + with ExceptionCheck(self): ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("data".encode()), i) diff --git a/src/library.cpp b/src/library.cpp index 24a8afa7c7..0fcedfc20b 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -765,6 +765,13 @@ of the last thermo output data and the corresponding keyword strings. The how to handle the return value depends on the value of the *what* argument string. +.. note:: + + The *type* property points to a static location that is reassigned + with every call, so the returned pointer should be recast, + dereferenced, and assigned immediately. Otherwise, its value may be + changed with the next invocation of the function. + .. list-table:: :header-rows: 1 :widths: auto @@ -787,7 +794,7 @@ argument string. - yes * - type - data type of thermo output column; see :cpp:enum:`_LMP_DATATYPE_CONST` - - const int (**not** a pointer) + - pointer to static int - yes * - data - actual field data for column @@ -808,6 +815,7 @@ void *lammps_last_thermo(void *handle, const char *what, int index) Thermo *th = lmp->output->thermo; if (!th) return nullptr; const int nfield = *th->get_nfield(); + static int datatype; BEGIN_CAPTURE { @@ -826,11 +834,14 @@ void *lammps_last_thermo(void *handle, const char *what, int index) if ((index < 0) || (index >= nfield)) return nullptr; const auto &field = th->get_fields()[index]; if (field.type == multitype::INT) { - val = (void *) LAMMPS_INT; + datatype = LAMMPS_INT; + val = (void *) &datatype; } else if (field.type == multitype::BIGINT) { - val = (void *) LAMMPS_INT64; + datatype = LAMMPS_INT64; + val = (void *) &datatype; } else if (field.type == multitype::DOUBLE) { - val = (void *) LAMMPS_DOUBLE; + datatype = LAMMPS_DOUBLE; + val = (void *) &datatype; } } else if (strcmp(what, "data") == 0) { From 5d4f9abf5b6604414e8f82537e49b21fbbfb65bc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 15:15:28 -0400 Subject: [PATCH 372/448] add unit tests for c-library interface and plain python module --- .../c-library/test_library_properties.cpp | 61 ++++++++++++++++++- unittest/python/python-commands.py | 27 ++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/unittest/c-library/test_library_properties.cpp b/unittest/c-library/test_library_properties.cpp index d6dd55f75e..14eab06213 100644 --- a/unittest/c-library/test_library_properties.cpp +++ b/unittest/c-library/test_library_properties.cpp @@ -14,6 +14,7 @@ #define STRINGIFY(val) XSTR(val) #define XSTR(val) #val +using ::LAMMPS_NS::bigint; using ::LAMMPS_NS::tagint; using ::LAMMPS_NS::platform::path_join; using ::testing::HasSubstr; @@ -93,6 +94,9 @@ TEST_F(LibraryProperties, natoms) TEST_F(LibraryProperties, thermo) { + bigint bval = *(bigint *)lammps_last_thermo(lmp, "step", 0); + EXPECT_EQ(bval, -1); + if (!lammps_has_style(lmp, "atom", "full")) GTEST_SKIP(); std::string input = path_join(INPUT_DIR, "in.fourmol"); ::testing::internal::CaptureStdout(); @@ -105,6 +109,59 @@ TEST_F(LibraryProperties, thermo) EXPECT_DOUBLE_EQ(lammps_get_thermo(lmp, "vol"), 3375.0); EXPECT_DOUBLE_EQ(lammps_get_thermo(lmp, "density"), 0.12211250945013695); EXPECT_DOUBLE_EQ(lammps_get_thermo(lmp, "cellalpha"), 90.0); + + bval = *(bigint *)lammps_last_thermo(lmp, "step", 0); + EXPECT_EQ(bval, 2); + int ival = *(int *)lammps_last_thermo(lmp, "num", 0); + EXPECT_EQ(ival, 6); + + const char *key = (const char *)lammps_last_thermo(lmp, "keyword", 0); + EXPECT_THAT(key, StrEq("Step")); + ival = *(int *)lammps_last_thermo(lmp, "type", 0); +#if defined(LAMMPS_SMALLSMALL) + EXPECT_EQ(ival, LAMMPS_INT); + ival = *(int *)lammps_last_thermo(lmp, "data", 0); + EXPECT_EQ(ival, 2); +#else + EXPECT_EQ(ival, LAMMPS_INT64); + bval = *(bigint *)lammps_last_thermo(lmp, "data", 0); + EXPECT_EQ(bval, 2); +#endif + + key = (const char *)lammps_last_thermo(lmp, "keyword", 1); + EXPECT_THAT(key, StrEq("Temp")); + ival = *(int *)lammps_last_thermo(lmp, "type", 1); + EXPECT_EQ(ival, LAMMPS_DOUBLE); + double dval = *(double *)lammps_last_thermo(lmp, "data", 1); + EXPECT_DOUBLE_EQ(dval, 28.042780385852982); + + key = (const char *)lammps_last_thermo(lmp, "keyword", 2); + EXPECT_THAT(key, StrEq("E_pair")); + ival = *(int *)lammps_last_thermo(lmp, "type", 2); + EXPECT_EQ(ival, LAMMPS_DOUBLE); + dval = *(double *)lammps_last_thermo(lmp, "data", 2); + EXPECT_DOUBLE_EQ(dval, 0.0); + + key = (const char *)lammps_last_thermo(lmp, "keyword", 3); + EXPECT_THAT(key, StrEq("E_mol")); + ival = *(int *)lammps_last_thermo(lmp, "type", 3); + EXPECT_EQ(ival, LAMMPS_DOUBLE); + dval = *(double *)lammps_last_thermo(lmp, "data", 3); + EXPECT_DOUBLE_EQ(dval, 0.0); + + key = (const char *)lammps_last_thermo(lmp, "keyword", 4); + EXPECT_THAT(key, StrEq("TotEng")); + ival = *(int *)lammps_last_thermo(lmp, "type", 4); + EXPECT_EQ(ival, LAMMPS_DOUBLE); + dval = *(double *)lammps_last_thermo(lmp, "data", 4); + EXPECT_DOUBLE_EQ(dval, 2.3405256449146163); + + key = (const char *)lammps_last_thermo(lmp, "keyword", 5); + EXPECT_THAT(key, StrEq("Press")); + ival = *(int *)lammps_last_thermo(lmp, "type", 5); + EXPECT_EQ(ival, LAMMPS_DOUBLE); + dval = *(double *)lammps_last_thermo(lmp, "data", 5); + EXPECT_DOUBLE_EQ(dval, 31.700964689115658); }; TEST_F(LibraryProperties, box) @@ -325,8 +382,8 @@ TEST_F(LibraryProperties, global) EXPECT_EQ(lammps_extract_global_datatype(lmp, "special_lj"), LAMMPS_DOUBLE); EXPECT_EQ(lammps_extract_global_datatype(lmp, "special_coul"), LAMMPS_DOUBLE); - double *special_lj = (double *)lammps_extract_global(lmp, "special_lj"); - double *special_coul= (double *)lammps_extract_global(lmp, "special_coul"); + double *special_lj = (double *)lammps_extract_global(lmp, "special_lj"); + double *special_coul = (double *)lammps_extract_global(lmp, "special_coul"); EXPECT_DOUBLE_EQ(special_lj[0], 1.0); EXPECT_DOUBLE_EQ(special_lj[1], 0.0); EXPECT_DOUBLE_EQ(special_lj[2], 0.5); diff --git a/unittest/python/python-commands.py b/unittest/python/python-commands.py index 33b19ba4f0..1c25751191 100644 --- a/unittest/python/python-commands.py +++ b/unittest/python/python-commands.py @@ -533,6 +533,33 @@ create_atoms 1 single & result = self.lmp.get_thermo(key) self.assertEqual(value, result, key) + + def test_last_thermo(self): + self.lmp.command("units lj") + self.lmp.command("atom_style atomic") + self.lmp.command("atom_modify map array") + self.lmp.command("boundary f f f") + self.lmp.command("region box block 0 2 0 2 0 2") + self.lmp.command("create_box 1 box") + self.lmp.command("mass * 1") + + x = [ + 0.5, 0.5, 0.5, + 1.5, 1.5, 1.5 + ] + types = [1, 1] + self.lmp.create_atoms(2, id=None, type=types, x=x) + + self.assertEqual(self.lmp.last_thermo(), None) + self.lmp.command("run 2 post no") + ref = { "Step" : 2, + "Temp" : 0.0, + "E_pair" : 0.0, + "E_mol" : 0.0, + "TotEng" : 0.0, + "Press" : 0.0} + self.assertDictEqual(self.lmp.last_thermo(), ref) + def test_extract_global(self): self.lmp.command("region box block -1 1 -2 2 -3 3") self.lmp.command("create_box 1 box") From 2e1190bfee1bee986abe9e8272e3ab3718815feb Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Thu, 8 Jun 2023 15:02:17 -0700 Subject: [PATCH 373/448] Fixing issue with when atom styles using torque are mixed with intel pair styles not using torque. Generating runtime error for mixing intel gayberne style with non-ellipsoid intel pair styles. --- src/INTEL/fix_intel.cpp | 31 +++++++++++++++++++++++++------ src/INTEL/fix_intel.h | 2 +- src/INTEL/intel_buffers.cpp | 3 ++- src/INTEL/intel_buffers.h | 6 ++++-- 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/INTEL/fix_intel.cpp b/src/INTEL/fix_intel.cpp index 2b786b6eed..ef6bfc3408 100644 --- a/src/INTEL/fix_intel.cpp +++ b/src/INTEL/fix_intel.cpp @@ -61,6 +61,7 @@ FixIntel::FixIntel(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg) _hybrid_nonpair = 0; _print_pkg_info = 1; _nthreads = comm->nthreads; + _torque_flag = 0; _precision_mode = PREC_MODE_MIXED; _offload_balance = -1.0; @@ -301,14 +302,29 @@ void FixIntel::init() } #endif + _torque_flag = 0; + if (force->pair_match("gayberne/intel$", 0)) _torque_flag = 1; + const int nstyles = _pair_intel_count; if (force->pair_match("^hybrid", 0) != nullptr) { _pair_hybrid_flag = 1; + + // Check if need to handle torque + auto hybrid = dynamic_cast(force->pair); + for (int i = 0; i < hybrid->nstyles; i++) + if (utils::strmatch(hybrid->keywords[i],"/intel$") && + utils::strmatch(hybrid->keywords[i],"gayberne")) + _torque_flag = 1; + if (force->newton_pair != 0 && force->pair->no_virial_fdotr_compute) error->all(FLERR,"INTEL package requires fdotr virial with newton on."); } else _pair_hybrid_flag = 0; + if (_torque_flag && nstyles > 1) + error->all(FLERR,"gayberne/intel style cannot yet be used with other " + "intel pair styles."); + if (nstyles > 1 && _pair_hybrid_flag) _pair_hybrid_flag = 2; else if (force->newton_pair == 0) _pair_hybrid_flag = 0; @@ -335,14 +351,17 @@ void FixIntel::init() int off_mode = 0; if (_offload_balance != 0.0) off_mode = 1; if (_precision_mode == PREC_MODE_SINGLE) { + _single_buffers->set_torque_flag(_torque_flag); _single_buffers->zero_ev(); _single_buffers->grow_ncache(off_mode, comm->nthreads); _single_buffers->free_list_ptrs(); } else if (_precision_mode == PREC_MODE_MIXED) { + _mixed_buffers->set_torque_flag(_torque_flag); _mixed_buffers->zero_ev(); _mixed_buffers->grow_ncache(off_mode, comm->nthreads); _mixed_buffers->free_list_ptrs(); } else { + _double_buffers->set_torque_flag(_torque_flag); _double_buffers->zero_ev(); _double_buffers->grow_ncache(off_mode, comm->nthreads); _double_buffers->free_list_ptrs(); @@ -620,7 +639,7 @@ void FixIntel::reduce_results(acc_t * _noalias const f_scalar) o_range = atom->nlocal + atom->nghost; else o_range = atom->nlocal; - IP_PRE_get_stride(f_stride, o_range, (sizeof(acc_t)*4), lmp->atom->torque); + IP_PRE_get_stride(f_stride, o_range, (sizeof(acc_t)*4), _torque_flag); o_range *= 4; const int f_stride4 = f_stride * 4; @@ -719,7 +738,7 @@ void FixIntel::add_results(const ft * _noalias const f_in, add_oresults(f_in, ev_global, eatom, vatom, 0, _offload_nlocal); const acc_t * _noalias const enull = 0; int offset = _offload_nlocal; - if (atom->torque) offset *= 2; + if (_torque_flag) offset *= 2; add_oresults(f_in + offset, enull, eatom, vatom, _offload_min_ghost, _offload_nghost); } else @@ -730,7 +749,7 @@ void FixIntel::add_results(const ft * _noalias const f_in, _host_min_local, _host_used_local); const acc_t * _noalias const enull = 0; int offset = _host_used_local; - if (atom->torque) offset *= 2; + if (_torque_flag) offset *= 2; add_oresults(f_in + offset, enull, eatom, vatom, _host_min_ghost, _host_used_ghost); } else { @@ -779,7 +798,7 @@ void FixIntel::add_oresults(const ft * _noalias const f_in, const int eatom, const int /*vatom*/, const int out_offset, const int nall) { lmp_ft * _noalias const f = (lmp_ft *) lmp->atom->f[0] + out_offset; - if (atom->torque) { + if (_torque_flag) { if (f_in[1].w) { if (f_in[1].w == 1) @@ -803,7 +822,7 @@ void FixIntel::add_oresults(const ft * _noalias const f_in, #endif int ifrom, ito; IP_PRE_omp_range_align(ifrom, ito, tid, nall, packthreads, sizeof(acc_t)); - if (atom->torque) { + if (_torque_flag) { int ii = ifrom * 2; lmp_ft * _noalias const tor = (lmp_ft *) lmp->atom->torque[0] + out_offset; @@ -927,7 +946,7 @@ void FixIntel::add_off_results(const ft * _noalias const f_in, _offload_nlocal; } - if (atom->torque) + if (_torque_flag) if (f_in[1].w < 0.0) error->all(FLERR,"Bad matrix inversion in mldivide3"); add_results(f_in, ev_global, _off_results_eatom, _off_results_vatom, 1); diff --git a/src/INTEL/fix_intel.h b/src/INTEL/fix_intel.h index 050b27c313..08d0a534d9 100644 --- a/src/INTEL/fix_intel.h +++ b/src/INTEL/fix_intel.h @@ -116,7 +116,7 @@ class FixIntel : public Fix { int _precision_mode, _nthreads, _nbor_pack_width, _three_body_neighbor; int _pair_intel_count, _pair_hybrid_flag, _print_pkg_info; // These should be removed in subsequent update w/ simpler hybrid arch - int _pair_hybrid_zero, _hybrid_nonpair, _zero_master; + int _pair_hybrid_zero, _hybrid_nonpair, _zero_master, _torque_flag; public: inline int *get_overflow_flag() { return _overflow_flag; } diff --git a/src/INTEL/intel_buffers.cpp b/src/INTEL/intel_buffers.cpp index bb54577097..6d4c9bffcd 100644 --- a/src/INTEL/intel_buffers.cpp +++ b/src/INTEL/intel_buffers.cpp @@ -28,6 +28,7 @@ template IntelBuffers::IntelBuffers(class LAMMPS *lmp_in) : lmp(lmp_in), _x(nullptr), _q(nullptr), _quat(nullptr), _f(nullptr), _off_threads(0), _n_list_ptrs(1), _max_list_ptrs(4), _buf_size(0), _buf_local_size(0) { + _torque_flag = 0; _neigh_list_ptrs = new IntelNeighListPtrs[_max_list_ptrs]; _neigh_list_ptrs[0].cnumneigh = nullptr; _list_alloc_atoms = 0; @@ -695,7 +696,7 @@ double IntelBuffers::memory_usage(const int nthreads) { double tmem = sizeof(atom_t); if (lmp->atom->q) tmem += sizeof(flt_t); - if (lmp->atom->torque) tmem += sizeof(quat_t); + if (_torque_flag) tmem += sizeof(quat_t); #ifdef _LMP_INTEL_OFFLOAD if (_separate_buffers) tmem *= 2; #endif diff --git a/src/INTEL/intel_buffers.h b/src/INTEL/intel_buffers.h index 7422850184..1e9739c3b2 100644 --- a/src/INTEL/intel_buffers.h +++ b/src/INTEL/intel_buffers.h @@ -57,7 +57,7 @@ class IntelBuffers { inline int get_stride(int nall) { int stride; IP_PRE_get_stride(stride, nall, sizeof(vec3_acc_t), - lmp->atom->torque); + _torque_flag); return stride; } @@ -76,6 +76,8 @@ class IntelBuffers { _neigh_list_ptrs[0].numneighhalf = atombin; } + inline void set_torque_flag(const int in) { _torque_flag = in; } + inline void grow(const int nall, const int nlocal, const int nthreads, const int offload_end) { if (nall >= _buf_size || nlocal >= _buf_local_size) @@ -329,7 +331,7 @@ class IntelBuffers { flt_t *_q; quat_t *_quat; vec3_acc_t * _f; - int _off_threads, _off_map_listlocal; + int _torque_flag, _off_threads, _off_map_listlocal; int _list_alloc_atoms; int *_list_alloc, *_cnumneigh, *_atombin, *_binpacked; From ce38bb988d67f1b82f9093bf1d1563198795cda8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 19:12:59 -0400 Subject: [PATCH 374/448] add lammps_last_thermo support to swig, plugin and fortran interface --- examples/COUPLE/plugin/liblammpsplugin.c | 1 + examples/COUPLE/plugin/liblammpsplugin.h | 1 + fortran/lammps.f90 | 80 +++++++++++++++++++++++- tools/swig/lammps.i | 2 + 4 files changed, 83 insertions(+), 1 deletion(-) diff --git a/examples/COUPLE/plugin/liblammpsplugin.c b/examples/COUPLE/plugin/liblammpsplugin.c index d446f9cd2f..0cf9bea512 100644 --- a/examples/COUPLE/plugin/liblammpsplugin.c +++ b/examples/COUPLE/plugin/liblammpsplugin.c @@ -90,6 +90,7 @@ liblammpsplugin_t *liblammpsplugin_load(const char *lib) ADDSYM(get_natoms); ADDSYM(get_thermo); + ADDSYM(last_thermo); ADDSYM(extract_box); ADDSYM(reset_box); diff --git a/examples/COUPLE/plugin/liblammpsplugin.h b/examples/COUPLE/plugin/liblammpsplugin.h index c6ec03e498..40fba6b9e3 100644 --- a/examples/COUPLE/plugin/liblammpsplugin.h +++ b/examples/COUPLE/plugin/liblammpsplugin.h @@ -133,6 +133,7 @@ struct _liblammpsplugin { double (*get_natoms)(void *); double (*get_thermo)(void *, const char *); + void *(*last_thermo)(void *, const char *, int); void (*extract_box)(void *, double *, double *, double *, double *, double *, int *, int *); diff --git a/fortran/lammps.f90 b/fortran/lammps.f90 index cb7adfd34b..f511e6bb60 100644 --- a/fortran/lammps.f90 +++ b/fortran/lammps.f90 @@ -87,10 +87,15 @@ MODULE LIBLAMMPS INTEGER(c_int) :: scalar, vector, array END TYPE lammps_type + TYPE lammps_dtype + INTEGER(c_int) :: i32, i64, r64, str + END TYPE lammps_dtype + TYPE lammps TYPE(c_ptr) :: handle = c_null_ptr TYPE(lammps_style) :: style TYPE(lammps_type) :: type + TYPE(lammps_dtype) :: dtype CONTAINS PROCEDURE :: close => lmp_close PROCEDURE :: error => lmp_error @@ -100,6 +105,7 @@ MODULE LIBLAMMPS PROCEDURE :: commands_string => lmp_commands_string PROCEDURE :: get_natoms => lmp_get_natoms PROCEDURE :: get_thermo => lmp_get_thermo + PROCEDURE :: last_thermo => lmp_last_thermo PROCEDURE :: extract_box => lmp_extract_box PROCEDURE :: reset_box => lmp_reset_box PROCEDURE :: memory_usage => lmp_memory_usage @@ -243,7 +249,7 @@ MODULE LIBLAMMPS END TYPE lammps_data_baseclass ! Derived type for receiving LAMMPS data (in lieu of the ability to type cast - ! pointers). Used for extract_compute, extract_atom + ! pointers). Used for extract_compute, extract_atom, last_thermo TYPE, EXTENDS(lammps_data_baseclass) :: lammps_data INTEGER(c_int), POINTER :: i32 => NULL() INTEGER(c_int), DIMENSION(:), POINTER :: i32_vec => NULL() @@ -439,6 +445,15 @@ MODULE LIBLAMMPS TYPE(c_ptr), INTENT(IN), VALUE :: name END FUNCTION lammps_get_thermo + FUNCTION lammps_last_thermo(handle,what,index) BIND(C) + IMPORT :: c_ptr, c_int + IMPLICIT NONE + TYPE(c_ptr) :: lammps_last_thermo + TYPE(c_ptr), INTENT(IN), VALUE :: handle + TYPE(c_ptr), INTENT(IN), VALUE :: what + INTEGER(c_int), INTENT(IN), VALUE :: index + END FUNCTION lammps_last_thermo + SUBROUTINE lammps_extract_box(handle,boxlo,boxhi,xy,yz,xz,pflags, & boxflag) BIND(C) IMPORT :: c_ptr, c_double, c_int @@ -995,6 +1010,10 @@ CONTAINS lmp_open%type%scalar = LMP_TYPE_SCALAR lmp_open%type%vector = LMP_TYPE_VECTOR lmp_open%type%array = LMP_TYPE_ARRAY + lmp_open%dtype%i32 = LAMMPS_INT + lmp_open%dtype%i64 = LAMMPS_INT64 + lmp_open%dtype%r64 = LAMMPS_DOUBLE + lmp_open%dtype%str = LAMMPS_STRING ! Assign constants for bigint and tagint for use elsewhere SIZE_TAGINT = lmp_extract_setting(lmp_open, 'tagint') @@ -1103,6 +1122,65 @@ CONTAINS CALL lammps_free(Cname) END FUNCTION lmp_get_thermo + ! equivalent function to lammps_last_thermo + FUNCTION lmp_last_thermo(self,what,index) RESULT(thermo_data) + CLASS(lammps), INTENT(IN), TARGET :: self + CHARACTER(LEN=*), INTENT(IN) :: what + INTEGER(c_int) :: index + TYPE(lammps_data) :: thermo_data, type_data + INTEGER(c_int) :: datatype + TYPE(c_ptr) :: Cname, Cptr + + ! set data type for known cases + SELECT CASE (what) + CASE ('step') + IF (SIZE_BIGINT == 4_c_int) THEN + datatype = LAMMPS_INT + ELSE + datatype = LAMMPS_INT64 + END IF + CASE ('num') + datatype = LAMMPS_INT + CASE ('type') + datatype = LAMMPS_INT + CASE ('keyword') + datatype = LAMMPS_STRING + CASE ('data') + Cname = f2c_string('type') + Cptr = lammps_last_thermo(self%handle,Cname,index-1) + type_data%lammps_instance => self + type_data%datatype = DATA_INT + CALL C_F_POINTER(Cptr, type_data%i32) + datatype = type_data%i32 + CALL lammps_free(Cname) + CASE DEFAULT + datatype = -1 + END SELECT + + Cname = f2c_string(what) + Cptr = lammps_last_thermo(self%handle,Cname,index-1) + CALL lammps_free(Cname) + + thermo_data%lammps_instance => self + SELECT CASE (datatype) + CASE (LAMMPS_INT) + thermo_data%datatype = DATA_INT + CALL C_F_POINTER(Cptr, thermo_data%i32) + CASE (LAMMPS_INT64) + thermo_data%datatype = DATA_INT64 + CALL C_F_POINTER(Cptr, thermo_data%i64) + CASE (LAMMPS_DOUBLE) + thermo_data%datatype = DATA_DOUBLE + CALL C_F_POINTER(Cptr, thermo_data%r64) + CASE (LAMMPS_STRING) + thermo_data%datatype = DATA_STRING + thermo_data%str = c2f_string(Cptr) + CASE DEFAULT + CALL lmp_error(self, LMP_ERROR_ALL + LMP_ERROR_WORLD, & + 'Unknown pointer type in last_thermo') + END SELECT + END FUNCTION lmp_last_thermo + ! equivalent subroutine to lammps_extract_box SUBROUTINE lmp_extract_box(self, boxlo, boxhi, xy, yz, xz, pflags, boxflag) CLASS(lammps), INTENT(IN) :: self diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i index b7414573ba..c4ef0a7109 100644 --- a/tools/swig/lammps.i +++ b/tools/swig/lammps.i @@ -113,6 +113,7 @@ extern void lammps_commands_string(void *handle, const char *str); extern double lammps_get_natoms(void *handle); extern double lammps_get_thermo(void *handle, const char *keyword); +extern void *lammps_last_thermo(void *handle, const char *what, int index); extern void lammps_extract_box(void *handle, double *boxlo, double *boxhi, double *xy, double *yz, double *xz, int *pflags, int *boxflag); @@ -295,6 +296,7 @@ extern void lammps_commands_string(void *handle, const char *str); extern double lammps_get_natoms(void *handle); extern double lammps_get_thermo(void *handle, const char *keyword); +extern void *lammps_last_thermo(void *handle, const char *what, int index); extern void lammps_extract_box(void *handle, double *boxlo, double *boxhi, double *xy, double *yz, double *xz, int *pflags, int *boxflag); From 4cad18a057ea81b92ebb119af520fc517dba3fe2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 8 Jun 2023 19:59:47 -0400 Subject: [PATCH 375/448] document Fortran version of lammps_last_thermo --- doc/src/Fortran.rst | 191 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 154 insertions(+), 37 deletions(-) diff --git a/doc/src/Fortran.rst b/doc/src/Fortran.rst index 92a42997b8..a0e4da56b5 100644 --- a/doc/src/Fortran.rst +++ b/doc/src/Fortran.rst @@ -203,40 +203,62 @@ Below is an example demonstrating some of the possible uses. .. code-block:: fortran - PROGRAM testprop - USE LIBLAMMPS - USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double, c_int64_t - USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT - TYPE(lammps) :: lmp - INTEGER(KIND=c_int64_t), POINTER :: natoms - REAL(KIND=c_double), POINTER :: dt - INTEGER(KIND=c_int64_t), POINTER :: ntimestep - REAL(KIND=c_double) :: pe, ke + PROGRAM testprop + USE LIBLAMMPS + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double, c_int64_t, c_int + USE, INTRINSIC :: ISO_FORTRAN_ENV, ONLY : OUTPUT_UNIT + TYPE(lammps) :: lmp + INTEGER(KIND=c_int64_t), POINTER :: natoms, ntimestep, bval + REAL(KIND=c_double), POINTER :: dt, dval + INTEGER(KIND=c_int), POINTER :: nfield, typ, ival + INTEGER(KIND=c_int) :: i + CHARACTER(LEN=11) :: key + REAL(KIND=c_double) :: pe, ke - lmp = lammps() - CALL lmp%file('in.sysinit') - natoms = lmp%extract_global('natoms') - WRITE(OUTPUT_UNIT,'(A,I0,A)') 'Running a simulation with ', natoms, ' atoms' - WRITE(OUTPUT_UNIT,'(I0,A,I0,A,I0,A)') lmp%extract_setting('nlocal'), & - ' local and ', lmp%extract_setting('nghost'), ' ghost atoms. ', & - lmp%extract_setting('ntypes'), ' atom types' + lmp = lammps() + CALL lmp%file('in.sysinit') + natoms = lmp%extract_global('natoms') + WRITE(OUTPUT_UNIT,'(A,I0,A)') 'Running a simulation with ', natoms, ' atoms' + WRITE(OUTPUT_UNIT,'(I0,A,I0,A,I0,A)') lmp%extract_setting('nlocal'), & + ' local and ', lmp%extract_setting('nghost'), ' ghost atoms. ', & + lmp%extract_setting('ntypes'), ' atom types' - CALL lmp%command('run 2 post no') - dt = lmp%extract_global('dt') - ntimestep = lmp%extract_global('ntimestep') - WRITE(OUTPUT_UNIT,'(A,I0,A,F4.1,A)') 'At step: ', ntimestep, & - ' Changing timestep from', dt, ' to 0.5' - dt = 0.5_c_double - CALL lmp%command('run 2 post no') + CALL lmp%command('run 2 post no') - WRITE(OUTPUT_UNIT,'(A,I0)') 'At step: ', ntimestep - pe = lmp%get_thermo('pe') - ke = lmp%get_thermo('ke') - PRINT*, 'PE = ', pe - PRINT*, 'KE = ', ke + ntimestep = lmp%last_thermo('step', 0) + nfield = lmp%last_thermo('num', 0) + WRITE(OUTPUT_UNIT,'(A,I0,A,I0)') 'Last thermo output on step: ', ntimestep, & + ', number of fields: ', nfield + DO i=1, nfield + key = lmp%last_thermo('keyword',i) + typ = lmp%last_thermo('type',i) + IF (typ == lmp%dtype%i32) THEN + ival = lmp%last_thermo('data',i) + WRITE(OUTPUT_UNIT,*) key, ':', ival + ELSE IF (typ == lmp%dtype%i64) THEN + bval = lmp%last_thermo('data',i) + WRITE(OUTPUT_UNIT,*) key, ':', bval + ELSE IF (typ == lmp%dtype%r64) THEN + dval = lmp%last_thermo('data',i) + WRITE(OUTPUT_UNIT,*) key, ':', dval + END IF + END DO - CALL lmp%close(.TRUE.) - END PROGRAM testprop + dt = lmp%extract_global('dt') + ntimestep = lmp%extract_global('ntimestep') + WRITE(OUTPUT_UNIT,'(A,I0,A,F4.1,A)') 'At step: ', ntimestep, & + ' Changing timestep from', dt, ' to 0.5' + dt = 0.5_c_double + CALL lmp%command('run 2 post no') + + WRITE(OUTPUT_UNIT,'(A,I0)') 'At step: ', ntimestep + pe = lmp%get_thermo('pe') + ke = lmp%get_thermo('ke') + WRITE(OUTPUT_UNIT,*) 'PE = ', pe + WRITE(OUTPUT_UNIT,*) 'KE = ', ke + + CALL lmp%close(.TRUE.) + END PROGRAM testprop --------------- @@ -262,6 +284,8 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS. :ftype style: type(lammps_style) :f type: derived type to access lammps type constants :ftype type: type(lammps_type) + :f dtype: derived type to access lammps data type constants + :ftype dtype: type(lammps_dtype) :f close: :f:subr:`close` :ftype close: subroutine :f subroutine error: :f:subr:`error` @@ -278,6 +302,8 @@ of the contents of the :f:mod:`LIBLAMMPS` Fortran interface to LAMMPS. :ftype get_natoms: function :f get_thermo: :f:func:`get_thermo` :ftype get_thermo: function + :f last_thermo: :f:func:`last_thermo` + :ftype last_thermo: function :f extract_box: :f:subr:`extract_box` :ftype extract_box: subroutine :f reset_box: :f:subr:`reset_box` @@ -587,6 +613,96 @@ Procedures Bound to the :f:type:`lammps` Derived Type -------- +.. f:function:: last_thermo(what, index) + + This function will call :cpp:func:`lammps_last_thermo` and returns + either a string or a pointer to a cached copy of LAMMPS last thermodynamic + output, depending on the data requested through *what*. Note that *index* + uses 1-based indexing to access thermo output columns. + + .. versionadded:: TBD + + Note that this function actually does not return a value, but rather + associates the pointer on the left side of the assignment to point to + internal LAMMPS data (with the exception of string data, which are + copied and returned as ordinary Fortran strings). Pointers must be + of the correct data type to point to said data (typically + ``INTEGER(c_int)``, ``INTEGER(c_int64_t)``, or ``REAL(c_double)``). + The pointer being associated with LAMMPS data is type-checked at + run-time via an overloaded assignment operator. The pointers + returned by this function point to temporary, read-only data that may + be overwritten at any time, so their target values need to be copied + to local storage if they are supposed to persist. + + For example, + + .. code-block:: fortran + + PROGRAM thermo + USE LIBLAMMPS + USE, INTRINSIC :: ISO_C_BINDING, ONLY : c_double, c_int64_t, c_int + TYPE(lammps) :: lmp + INTEGER(KIND=c_int64_t), POINTER :: ntimestep, bval + REAL(KIND=c_double), POINTER :: dval + INTEGER(KIND=c_int), POINTER :: nfield, typ, ival + INTEGER(KIND=c_int) :: i + CHARACTER(LEN=11) :: key + + lmp = lammps() + CALL lmp%file('in.sysinit') + + ntimestep = lmp%last_thermo('step', 0) + nfield = lmp%last_thermo('num', 0) + PRINT*, 'Last thermo output on step: ', ntimestep, ' Number of fields: ', nfield + DO i=1, nfield + key = lmp%last_thermo('keyword',i) + typ = lmp%last_thermo('type',i) + IF (typ == lmp%dtype%i32) THEN + ival = lmp%last_thermo('data',i) + PRINT*, key, ':', ival + ELSE IF (typ == lmp%dtype%i64) THEN + bval = lmp%last_thermo('data',i) + PRINT*, key, ':', bval + ELSE IF (typ == lmp%dtype%r64) THEN + dval = lmp%last_thermo('data',i) + PRINT*, key, ':', dval + END IF + END DO + CALL lmp%close(.TRUE.) + END PROGRAM thermo + + would extract the last timestep where thermo output was done and the number + of columns it printed. Then it loops over the columns to print out column + header keywords and the corresponding data. + + .. note:: + + If :f:func:`last_thermo` returns a string, the string must have a length + greater than or equal to the length of the string (not including the + terminal ``NULL`` character) that LAMMPS returns. If the variable's + length is too short, the string will be truncated. As usual in Fortran, + strings are padded with spaces at the end. If you use an allocatable + string, the string **must be allocated** prior to calling this function. + + :p character(len=\*) what: string with the name of the thermo keyword + :p integer(c_int) index: 1-based column index + :to: :cpp:func:`lammps_last_thermo` + :r pointer [polymorphic]: pointer to LAMMPS data. The left-hand side of the + assignment should be either a string (if expecting string data) or a + C-compatible pointer (e.g., ``INTEGER(c_int), POINTER :: nlocal``) to the + extracted property. + + .. warning:: + + Modifying the data in the location pointed to by the returned pointer + may lead to inconsistent internal data and thus may cause failures, + crashes, or bogus simulations. In general, it is much better + to use a LAMMPS input command that sets or changes these parameters. + Using an input command will take care of all side effects and necessary + updates of settings derived from such settings. + +-------- + .. f:subroutine:: extract_box([boxlo][, boxhi][, xy][, yz][, xz][, pflags][, boxflag]) This subroutine will call :cpp:func:`lammps_extract_box`. All @@ -764,13 +880,14 @@ Procedures Bound to the :f:type:`lammps` Derived Type .. note:: - If :f:func:`extract_global` returns a string, the string must have length - greater than or equal to the length of the string (not including the - terminal ``NULL`` character) that LAMMPS returns. If the variable's - length is too short, the string will be truncated. As usual in Fortran, - strings are padded with spaces at the end. If you use an allocatable - string, the string **must be allocated** prior to calling this function, - but you can automatically reallocate it to the correct length after the + If :f:func:`extract_global` returns a string, the string must have + a length greater than or equal to the length of the string (not + including the terminal ``NULL`` character) that LAMMPS returns. If + the variable's length is too short, the string will be + truncated. As usual in Fortran, strings are padded with spaces at + the end. If you use an allocatable string, the string **must be + allocated** prior to calling this function, but you can + automatically reallocate it to the correct length after the function returns, viz., .. code-block :: fortran From 2cb87bc9a2e3758f342ec6f47b8265d52f05f0bf Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Thu, 8 Jun 2023 21:47:30 -0700 Subject: [PATCH 376/448] Intel package should not reset atom sort frequency if it is 0 (disabled). --- src/INTEL/fix_intel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/INTEL/fix_intel.cpp b/src/INTEL/fix_intel.cpp index ef6bfc3408..59224cc511 100644 --- a/src/INTEL/fix_intel.cpp +++ b/src/INTEL/fix_intel.cpp @@ -411,7 +411,7 @@ bool FixIntel::pair_hybrid_check() void FixIntel::pair_init_check(const bool cdmessage) { #ifdef INTEL_VMASK - atom->sortfreq = 1; + if (atom->sortfreq) atom->sortfreq = 1; #endif _nbor_pack_width = 1; From f6b0981474c0a8ec20c3808efdeae5664280bc49 Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Fri, 9 Jun 2023 14:05:41 -0700 Subject: [PATCH 377/448] Fixing some issues introduced into verlet_lrt_intel.cpp --- src/INTEL/verlet_lrt_intel.cpp | 42 +++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/INTEL/verlet_lrt_intel.cpp b/src/INTEL/verlet_lrt_intel.cpp index 42414420b6..9df17d8cef 100644 --- a/src/INTEL/verlet_lrt_intel.cpp +++ b/src/INTEL/verlet_lrt_intel.cpp @@ -19,7 +19,6 @@ #include "atom_vec.h" #include "bond.h" #include "comm.h" -#include "compute.h" #include "dihedral.h" #include "domain.h" #include "error.h" @@ -27,7 +26,6 @@ #include "force.h" #include "improper.h" #include "kspace.h" -#include "memory.h" #include "modify.h" #include "neighbor.h" #include "output.h" @@ -35,9 +33,7 @@ #include "timer.h" #include "update.h" -#if defined(_OPENMP) -#include -#endif +#include using namespace LAMMPS_NS; @@ -67,7 +63,7 @@ void VerletLRTIntel::init() { Verlet::init(); - _intel_kspace = dynamic_cast(force->kspace_match("^pppm\\..*intel$", 0)); + _intel_kspace = dynamic_cast(force->kspace_match("^pppm/.*intel$", 0)); // include pppm/electrode/intel #ifndef LMP_INTEL_USELRT @@ -95,12 +91,15 @@ void VerletLRTIntel::setup(int flag) } #endif - if (comm->me == 0) { - fprintf(screen,"Setting up VerletLRTIntel run ...\n"); - fprintf(screen," Unit style : %s\n", update->unit_style); - fmt::print(screen," Current step : {}\n", update->ntimestep); - fprintf(screen," Time step : %g\n", update->dt); - timer->print_timeout(screen); + if (comm->me == 0 && screen) { + fputs("Setting up VerletLRTIntel run ...\n",screen); + if (flag) { + fmt::print(screen," Unit style : {}\n" + " Current step : {}\n" + " Time step : {}\n", + update->unit_style,update->ntimestep,update->dt); + timer->print_timeout(screen); + } } #if defined(_LMP_INTEL_LRT_PTHREAD) @@ -110,8 +109,9 @@ void VerletLRTIntel::setup(int flag) sched_getaffinity(0, sizeof(cpuset), &cpuset); int my_cpu_count = CPU_COUNT(&cpuset); if (my_cpu_count < comm->nthreads + 1) { - error->warning(FLERR, "Using {} threads per MPI rank, but only {} core(s) allocated " - "for each MPI rank", comm->nthreads + 1, my_cpu_count); + error->warning(FLERR, "Using {} threads per MPI rank, but only {} " + "core(s) allocated for each MPI rank", + comm->nthreads + 1, my_cpu_count); } } #endif @@ -144,6 +144,7 @@ void VerletLRTIntel::setup(int flag) domain->box_too_small_check(); modify->setup_pre_neighbor(); neighbor->build(1); + modify->setup_post_neighbor(); neighbor->ncalls = 0; // compute all forces @@ -189,11 +190,11 @@ void VerletLRTIntel::setup(int flag) if (kspace_compute_flag) _intel_kspace->compute_second(eflag,vflag); - modify->pre_reverse(eflag,vflag); + modify->setup_pre_reverse(eflag,vflag); if (force->newton) comm->reverse_comm(); modify->setup(vflag); - output->setup(); + output->setup(flag); update->setupflag = 0; } @@ -214,9 +215,10 @@ void VerletLRTIntel::run(int n) int n_post_integrate = modify->n_post_integrate; int n_pre_exchange = modify->n_pre_exchange; int n_pre_neighbor = modify->n_pre_neighbor; + int n_post_neighbor = modify->n_post_neighbor; int n_pre_force = modify->n_pre_force; int n_pre_reverse = modify->n_pre_reverse; - int n_post_force = modify->n_post_force_any; + int n_post_force_any = modify->n_post_force_any; int n_end_of_step = modify->n_end_of_step; if (atom->sortfreq > 0) sortflag = 1; @@ -279,6 +281,10 @@ void VerletLRTIntel::run(int n) } neighbor->build(1); timer->stamp(Timer::NEIGH); + if (n_post_neighbor) { + modify->post_neighbor(); + timer->stamp(Timer::MODIFY); + } } // force computations @@ -353,7 +359,7 @@ void VerletLRTIntel::run(int n) // force modifications, final time integration, diagnostics - if (n_post_force) modify->post_force(vflag); + if (n_post_force_any) modify->post_force(vflag); modify->final_integrate(); if (n_end_of_step) modify->end_of_step(); timer->stamp(Timer::MODIFY); From ecf7c24e874cb70c19888811b09838d42cd1912b Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 9 Jun 2023 00:06:00 -0600 Subject: [PATCH 378/448] Avoid static int in lammps_last_thermo --- src/library.cpp | 15 ++------------- src/lmptype.h | 3 ++- 2 files changed, 4 insertions(+), 14 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index 0fcedfc20b..a94e385148 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -794,7 +794,7 @@ argument string. - yes * - type - data type of thermo output column; see :cpp:enum:`_LMP_DATATYPE_CONST` - - pointer to static int + - pointer to int - yes * - data - actual field data for column @@ -815,7 +815,6 @@ void *lammps_last_thermo(void *handle, const char *what, int index) Thermo *th = lmp->output->thermo; if (!th) return nullptr; const int nfield = *th->get_nfield(); - static int datatype; BEGIN_CAPTURE { @@ -833,17 +832,7 @@ void *lammps_last_thermo(void *handle, const char *what, int index) } else if (strcmp(what, "type") == 0) { if ((index < 0) || (index >= nfield)) return nullptr; const auto &field = th->get_fields()[index]; - if (field.type == multitype::INT) { - datatype = LAMMPS_INT; - val = (void *) &datatype; - } else if (field.type == multitype::BIGINT) { - datatype = LAMMPS_INT64; - val = (void *) &datatype; - } else if (field.type == multitype::DOUBLE) { - datatype = LAMMPS_DOUBLE; - val = (void *) &datatype; - } - + val = (void *) &field.type; } else if (strcmp(what, "data") == 0) { if ((index < 0) || (index >= nfield)) return nullptr; const auto &field = th->get_fields()[index]; diff --git a/src/lmptype.h b/src/lmptype.h index 6e0b54d988..e559bd9416 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -276,7 +276,8 @@ union ubuf { \endverbatim */ struct multitype { - enum { NONE, DOUBLE, INT, BIGINT }; + // same values as LAMMPS_INT, LAMMPS_DOUBLE, and LAMMPS_INT64 in library.h + enum { NONE = -1, INT = 0, DOUBLE = 2, BIGINT = 4 }; int type; union { From fe45b766c3067052805548b7ee1a9f5abbcd5f45 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 9 Jun 2023 02:29:30 -0600 Subject: [PATCH 379/448] pylammps: make use of lammps_last_thermo this now avoids parsing LAMMPS output to extract thermo data, but instead uses the new lammps_last_thermo library function --- python/lammps/core.py | 9 +++-- python/lammps/pylammps.py | 75 +++++++++++++-------------------------- 2 files changed, 31 insertions(+), 53 deletions(-) diff --git a/python/lammps/core.py b/python/lammps/core.py index d34d5de4d4..cf613fcbf4 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -746,6 +746,11 @@ class lammps(object): return self.lib.lammps_get_thermo(self.lmp,name) # ------------------------------------------------------------------------- + @property + def last_thermo_step(self): + with ExceptionCheck(self): + ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("step".encode()), 0) + return cast(ptr, POINTER(self.c_bigint)).contents.value def last_thermo(self): """Get a dictionary of the last thermodynamic output @@ -760,9 +765,7 @@ class lammps(object): """ rv = dict() - with ExceptionCheck(self): - ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("step".encode()), 0) - mystep = cast(ptr, POINTER(self.c_bigint)).contents.value + mystep = self.last_thermo_step if mystep < 0: return None diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index d0ff7ab1aa..a7349ebd2c 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -377,55 +377,6 @@ class variable_set: def __repr__(self): return self.__str__() -# ------------------------------------------------------------------------- - -def get_thermo_data(output): - """ traverse output of runs and extract thermo data columns """ - if isinstance(output, str): - lines = output.splitlines() - else: - lines = output - - runs = [] - columns = [] - in_run = False - current_run = {} - - for line in lines: - if line.startswith("Per MPI rank memory allocation"): - in_run = True - elif in_run and len(columns) == 0: - # first line after memory usage are column names - columns = line.split() - - current_run = {} - - for col in columns: - current_run[col] = [] - - elif line.startswith("Loop time of "): - in_run = False - columns = [] - thermo_data = variable_set('ThermoData', current_run) - r = {'thermo' : thermo_data } - runs.append(namedtuple('Run', list(r.keys()))(*list(r.values()))) - elif in_run and len(columns) > 0: - items = line.split() - # Convert thermo output and store it. - # It must have the same number of columns and - # all of them must be convertible to floats. - # Otherwise we ignore the line - if len(items) == len(columns): - try: - values = [float(x) for x in items] - for i, col in enumerate(columns): - current_run[col].append(values[i]) - except ValueError: - # cannot convert. must be a non-thermo output. ignore. - pass - - return runs - # ------------------------------------------------------------------------- # ------------------------------------------------------------------------- @@ -573,6 +524,13 @@ class PyLammps(object): if self.enable_cmd_history: self._cmd_history.append(cmd) + def _append_run_thermo(self, thermo): + for k, v in thermo.items(): + if k in self._current_run: + self._current_run[k].append(v) + else: + self._current_run[k] = [v] + def run(self, *args, **kwargs): """ Execute LAMMPS run command with given arguments @@ -581,8 +539,25 @@ class PyLammps(object): :py:attr:`PyLammps.runs`. The latest run can be retrieved by :py:attr:`PyLammps.last_run`. """ + self._current_run = {} + self._last_thermo_step = -1 + def end_of_step_callback(lmp): + if self.lmp.last_thermo_step == self._last_thermo_step: return + thermo = self.lmp.last_thermo() + self._append_run_thermo(thermo) + self._last_thermo_step = thermo['Step'] + + import __main__ + __main__._PyLammps_end_of_step_callback = end_of_step_callback + + self.fix("__pylammps_internal_run_callback", "all", "python/invoke", "1", "end_of_step", "_PyLammps_end_of_step_callback") output = self.__getattr__('run')(*args, **kwargs) - self.runs += get_thermo_data(output) + self.unfix("__pylammps_internal_run_callback") + self._append_run_thermo(self.lmp.last_thermo()) + + thermo_data = variable_set('ThermoData', self._current_run) + r = {'thermo' : thermo_data } + self.runs.append(namedtuple('Run', list(r.keys()))(*list(r.values()))) return output @property From 235e98ee6a2995adf9b431d98fd1550d6b8a2fd4 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Fri, 9 Jun 2023 09:49:07 -0600 Subject: [PATCH 380/448] pylammps: only capture all thermo if PYTHON package is enabled --- python/lammps/pylammps.py | 18 +++++++++++++++--- unittest/python/python-pylammps.py | 28 ++++++++++++++++++++-------- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index a7349ebd2c..6efc355f5c 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -434,6 +434,9 @@ class PyLammps(object): self._enable_cmd_history = False self.runs = [] + if not self.lmp.has_package("PYTHON"): + print("WARNING: run thermo data not captured since PYTHON LAMMPS package is not enabled") + def __enter__(self): return self @@ -535,9 +538,13 @@ class PyLammps(object): """ Execute LAMMPS run command with given arguments - All thermo output during the run is captured and saved as new entry in + Thermo data of the run is recorded and saved as new entry in :py:attr:`PyLammps.runs`. The latest run can be retrieved by :py:attr:`PyLammps.last_run`. + + Note, for recording of all thermo steps during a run, the PYTHON package + needs to be enabled in LAMMPS. Otherwise, it will only capture the final + timestep. """ self._current_run = {} self._last_thermo_step = -1 @@ -549,10 +556,15 @@ class PyLammps(object): import __main__ __main__._PyLammps_end_of_step_callback = end_of_step_callback + capture_thermo = self.lmp.has_package("PYTHON") + + if capture_thermo: + self.fix("__pylammps_internal_run_callback", "all", "python/invoke", "1", "end_of_step", "_PyLammps_end_of_step_callback") - self.fix("__pylammps_internal_run_callback", "all", "python/invoke", "1", "end_of_step", "_PyLammps_end_of_step_callback") output = self.__getattr__('run')(*args, **kwargs) - self.unfix("__pylammps_internal_run_callback") + + if capture_thermo: + self.unfix("__pylammps_internal_run_callback") self._append_run_thermo(self.lmp.last_thermo()) thermo_data = variable_set('ThermoData', self._current_run) diff --git a/unittest/python/python-pylammps.py b/unittest/python/python-pylammps.py index 2b92f82248..9e691b1b8c 100644 --- a/unittest/python/python-pylammps.py +++ b/unittest/python/python-pylammps.py @@ -82,14 +82,26 @@ class PythonPyLammps(unittest.TestCase): self.pylmp.variable("fx atom fx") self.pylmp.run(10) - self.assertEqual(len(self.pylmp.runs), 1) - self.assertEqual(self.pylmp.last_run, self.pylmp.runs[0]) - self.assertEqual(len(self.pylmp.last_run.thermo.Step), 2) - self.assertEqual(len(self.pylmp.last_run.thermo.Temp), 2) - self.assertEqual(len(self.pylmp.last_run.thermo.E_pair), 2) - self.assertEqual(len(self.pylmp.last_run.thermo.E_mol), 2) - self.assertEqual(len(self.pylmp.last_run.thermo.TotEng), 2) - self.assertEqual(len(self.pylmp.last_run.thermo.Press), 2) + # thermo data is only captured during a run if PYTHON package is enabled + # without it, it will only capture the final thermo at completion + if self.pylmp.lmp.has_package("PYTHON"): + self.assertEqual(len(self.pylmp.runs), 1) + self.assertEqual(self.pylmp.last_run, self.pylmp.runs[0]) + self.assertEqual(len(self.pylmp.last_run.thermo.Step), 2) + self.assertEqual(len(self.pylmp.last_run.thermo.Temp), 2) + self.assertEqual(len(self.pylmp.last_run.thermo.E_pair), 2) + self.assertEqual(len(self.pylmp.last_run.thermo.E_mol), 2) + self.assertEqual(len(self.pylmp.last_run.thermo.TotEng), 2) + self.assertEqual(len(self.pylmp.last_run.thermo.Press), 2) + else: + self.assertEqual(len(self.pylmp.runs), 1) + self.assertEqual(self.pylmp.last_run, self.pylmp.runs[0]) + self.assertEqual(len(self.pylmp.last_run.thermo.Step), 1) + self.assertEqual(len(self.pylmp.last_run.thermo.Temp), 1) + self.assertEqual(len(self.pylmp.last_run.thermo.E_pair), 1) + self.assertEqual(len(self.pylmp.last_run.thermo.E_mol), 1) + self.assertEqual(len(self.pylmp.last_run.thermo.TotEng), 1) + self.assertEqual(len(self.pylmp.last_run.thermo.Press), 1) def test_info_queries(self): self.pylmp.lattice("fcc", 0.8442), From 0e7d91b6114d63b49a121e3817318db98c0019c6 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sat, 10 Jun 2023 07:45:52 -0600 Subject: [PATCH 381/448] add missing documentation --- doc/src/Python_properties.rst | 5 +++++ python/lammps/core.py | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/doc/src/Python_properties.rst b/doc/src/Python_properties.rst index d8e772379c..031461660a 100644 --- a/doc/src/Python_properties.rst +++ b/doc/src/Python_properties.rst @@ -53,6 +53,7 @@ against invalid accesses. * :py:meth:`version() `: return the numerical version id, e.g. LAMMPS 2 Sep 2015 -> 20150902 * :py:meth:`get_thermo() `: return current value of a thermo keyword + * :py:meth:`last_thermo() `: return a dictionary of the last thermodynamic output * :py:meth:`get_natoms() `: total # of atoms as int * :py:meth:`reset_box() `: reset the simulation box size * :py:meth:`extract_setting() `: return a global setting @@ -60,6 +61,10 @@ against invalid accesses. * :py:meth:`extract_box() `: extract box info * :py:meth:`create_atoms() `: create N atoms with IDs, types, x, v, and image flags + **Properties**: + + * :py:attr:`last_thermo_step `: the last timestep thermodynamic output was computed + .. tab:: PyLammps/IPyLammps API In addition to the functions provided by :py:class:`lammps `, :py:class:`PyLammps ` objects diff --git a/python/lammps/core.py b/python/lammps/core.py index cf613fcbf4..84a80e77a3 100644 --- a/python/lammps/core.py +++ b/python/lammps/core.py @@ -748,6 +748,11 @@ class lammps(object): # ------------------------------------------------------------------------- @property def last_thermo_step(self): + """ Get the last timestep where thermodynamic data was computed + + :return: the timestep or a negative number if there has not been any thermo output yet + :rtype: int + """ with ExceptionCheck(self): ptr = self.lib.lammps_last_thermo(self.lmp, c_char_p("step".encode()), 0) return cast(ptr, POINTER(self.c_bigint)).contents.value @@ -760,7 +765,7 @@ class lammps(object): data from the last timestep into a dictionary. The return value is None, if there has not been any thermo output yet. - :return: value of thermo keyword + :return: a dictionary containing the last computed thermo output values :rtype: dict or None """ From acaa2b7f9b3aa8adda8e5d8f228f3799f808259a Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sat, 10 Jun 2023 11:35:36 -0600 Subject: [PATCH 382/448] pylammps: update email --- python/lammps/pylammps.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index 6efc355f5c..72cfed53f0 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -13,7 +13,7 @@ ################################################################################ # Alternative Python Wrapper -# Written by Richard Berger +# Written by Richard Berger ################################################################################ # for python2/3 compatibility From da9637e94c13c20bbc66c6b83e27f45c1e96ac4f Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Sat, 10 Jun 2023 13:33:10 -0700 Subject: [PATCH 383/448] Adding std namespace specifier to transcendentals in intel pkg --- src/INTEL/angle_charmm_intel.cpp | 10 ++-- src/INTEL/angle_harmonic_intel.cpp | 8 +-- src/INTEL/bond_harmonic_intel.cpp | 2 +- src/INTEL/dihedral_charmm_intel.cpp | 6 +- src/INTEL/dihedral_fourier_intel.cpp | 4 +- src/INTEL/dihedral_harmonic_intel.cpp | 4 +- src/INTEL/dihedral_opls_intel.cpp | 14 ++--- src/INTEL/fix_nh_intel.cpp | 28 ++++----- src/INTEL/improper_cvff_intel.cpp | 10 ++-- src/INTEL/improper_harmonic_intel.cpp | 12 ++-- src/INTEL/intel_intrinsics.h | 2 +- src/INTEL/math_extra_intel.h | 14 ++--- src/INTEL/pair_airebo_intel.cpp | 2 +- src/INTEL/pair_buck_coul_cut_intel.cpp | 2 +- src/INTEL/pair_buck_coul_long_intel.cpp | 2 +- src/INTEL/pair_buck_intel.cpp | 2 +- src/INTEL/pair_dpd_intel.cpp | 4 +- src/INTEL/pair_eam_intel.cpp | 4 +- src/INTEL/pair_gayberne_intel.cpp | 2 +- .../pair_lj_charmm_coul_charmm_intel.cpp | 2 +- src/INTEL/pair_lj_charmm_coul_long_intel.cpp | 6 +- src/INTEL/pair_lj_cut_coul_long_intel.cpp | 2 +- src/INTEL/pair_sw_intel.cpp | 4 +- src/INTEL/pppm_disp_intel.cpp | 60 +++++++++---------- src/INTEL/pppm_intel.cpp | 12 ++-- 25 files changed, 109 insertions(+), 109 deletions(-) diff --git a/src/INTEL/angle_charmm_intel.cpp b/src/INTEL/angle_charmm_intel.cpp index 1ea9c8348e..e13448e28a 100644 --- a/src/INTEL/angle_charmm_intel.cpp +++ b/src/INTEL/angle_charmm_intel.cpp @@ -178,7 +178,7 @@ void AngleCharmmIntel::eval(const int vflag, const flt_t delz1 = x[i1].z - x[i2].z; const flt_t rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; - flt_t ir12 = (flt_t)1.0/sqrt(rsq1); + flt_t ir12 = (flt_t)1.0/std::sqrt(rsq1); // 2nd bond @@ -187,7 +187,7 @@ void AngleCharmmIntel::eval(const int vflag, const flt_t delz2 = x[i3].z - x[i2].z; const flt_t rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; - ir12 *= (flt_t)1.0/sqrt(rsq2); + ir12 *= (flt_t)1.0/std::sqrt(rsq2); // Urey-Bradley bond @@ -196,7 +196,7 @@ void AngleCharmmIntel::eval(const int vflag, const flt_t delzUB = x[i3].z - x[i1].z; const flt_t rsqUB = delxUB*delxUB + delyUB*delyUB + delzUB*delzUB; - const flt_t irUB = (flt_t)1.0/sqrt(rsqUB); + const flt_t irUB = (flt_t)1.0/std::sqrt(rsqUB); // Urey-Bradley force & energy @@ -219,12 +219,12 @@ void AngleCharmmIntel::eval(const int vflag, if (c < (flt_t)-1.0) c = (flt_t)-1.0; const flt_t sd = (flt_t)1.0 - c * c; - flt_t s = (flt_t)1.0 / sqrt(sd); + flt_t s = (flt_t)1.0 / std::sqrt(sd); if (sd < SMALL2) s = INVSMALL; // harmonic force & energy - const flt_t dtheta = acos(c) - fc.fc[type].theta0; + const flt_t dtheta = std::acos(c) - fc.fc[type].theta0; const flt_t tk = fc.fc[type].k * dtheta; if (EFLAG) eangle += tk*dtheta; diff --git a/src/INTEL/angle_harmonic_intel.cpp b/src/INTEL/angle_harmonic_intel.cpp index 8cdab1d43a..98125b164b 100644 --- a/src/INTEL/angle_harmonic_intel.cpp +++ b/src/INTEL/angle_harmonic_intel.cpp @@ -178,7 +178,7 @@ void AngleHarmonicIntel::eval(const int vflag, const flt_t delz1 = x[i1].z - x[i2].z; const flt_t rsq1 = delx1*delx1 + dely1*dely1 + delz1*delz1; - const flt_t r1 = (flt_t)1.0/sqrt(rsq1); + const flt_t r1 = (flt_t)1.0/std::sqrt(rsq1); // 2nd bond @@ -187,7 +187,7 @@ void AngleHarmonicIntel::eval(const int vflag, const flt_t delz2 = x[i3].z - x[i2].z; const flt_t rsq2 = delx2*delx2 + dely2*dely2 + delz2*delz2; - const flt_t r2 = (flt_t)1.0/sqrt(rsq2); + const flt_t r2 = (flt_t)1.0/std::sqrt(rsq2); // angle (cos and sin) @@ -199,12 +199,12 @@ void AngleHarmonicIntel::eval(const int vflag, if (c < (flt_t)-1.0) c = (flt_t)-1.0; const flt_t sd = (flt_t)1.0 - c * c; - flt_t s = (flt_t)1.0/sqrt(sd); + flt_t s = (flt_t)1.0/std::sqrt(sd); if (sd < SMALL2) s = INVSMALL; // harmonic force & energy - const flt_t dtheta = acos(c) - fc.fc[type].theta0; + const flt_t dtheta = std::acos(c) - fc.fc[type].theta0; const flt_t tk = fc.fc[type].k * dtheta; flt_t eangle; diff --git a/src/INTEL/bond_harmonic_intel.cpp b/src/INTEL/bond_harmonic_intel.cpp index a60050bb6b..ab38cefea4 100644 --- a/src/INTEL/bond_harmonic_intel.cpp +++ b/src/INTEL/bond_harmonic_intel.cpp @@ -168,7 +168,7 @@ void BondHarmonicIntel::eval(const int vflag, const flt_t delz = x[i1].z - x[i2].z; const flt_t rsq = delx*delx + dely*dely + delz*delz; - const flt_t r = sqrt(rsq); + const flt_t r = std::sqrt(rsq); const flt_t dr = r - fc.fc[type].r0; const flt_t rk = fc.fc[type].k * dr; diff --git a/src/INTEL/dihedral_charmm_intel.cpp b/src/INTEL/dihedral_charmm_intel.cpp index 6c3ae2c927..a41cfb867c 100644 --- a/src/INTEL/dihedral_charmm_intel.cpp +++ b/src/INTEL/dihedral_charmm_intel.cpp @@ -240,14 +240,14 @@ void DihedralCharmmIntel::eval(const int vflag, const flt_t rasq = ax*ax + ay*ay + az*az; const flt_t rbsq = bx*bx + by*by + bz*bz; const flt_t rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; - const flt_t rg = sqrt(rgsq); + const flt_t rg = std::sqrt(rgsq); flt_t rginv, ra2inv, rb2inv; rginv = ra2inv = rb2inv = (flt_t)0.0; if (rg > 0) rginv = (flt_t)1.0/rg; if (rasq > 0) ra2inv = (flt_t)1.0/rasq; if (rbsq > 0) rb2inv = (flt_t)1.0/rbsq; - const flt_t rabinv = sqrt(ra2inv*rb2inv); + const flt_t rabinv = std::sqrt(ra2inv*rb2inv); flt_t c = (ax*bx + ay*by + az*bz)*rabinv; const flt_t s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); @@ -367,7 +367,7 @@ void DihedralCharmmIntel::eval(const int vflag, flt_t forcecoul; if (implicit) forcecoul = qqrd2e * q[i1]*q[i4]*r2inv; - else forcecoul = qqrd2e * q[i1]*q[i4]*sqrt(r2inv); + else forcecoul = qqrd2e * q[i1]*q[i4]*std::sqrt(r2inv); const flt_t forcelj = r6inv * (fc.ljp[itype][jtype].lj1*r6inv - fc.ljp[itype][jtype].lj2); const flt_t fpair = tweight * (forcelj+forcecoul)*r2inv; diff --git a/src/INTEL/dihedral_fourier_intel.cpp b/src/INTEL/dihedral_fourier_intel.cpp index 5448fdae98..595d747839 100644 --- a/src/INTEL/dihedral_fourier_intel.cpp +++ b/src/INTEL/dihedral_fourier_intel.cpp @@ -199,14 +199,14 @@ void DihedralFourierIntel::eval(const int vflag, const flt_t rasq = ax*ax + ay*ay + az*az; const flt_t rbsq = bx*bx + by*by + bz*bz; const flt_t rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; - const flt_t rg = sqrt(rgsq); + const flt_t rg = std::sqrt(rgsq); flt_t rginv, ra2inv, rb2inv; rginv = ra2inv = rb2inv = (flt_t)0.0; if (rg > 0) rginv = (flt_t)1.0/rg; if (rasq > 0) ra2inv = (flt_t)1.0/rasq; if (rbsq > 0) rb2inv = (flt_t)1.0/rbsq; - const flt_t rabinv = sqrt(ra2inv*rb2inv); + const flt_t rabinv = std::sqrt(ra2inv*rb2inv); flt_t c = (ax*bx + ay*by + az*bz)*rabinv; const flt_t s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); diff --git a/src/INTEL/dihedral_harmonic_intel.cpp b/src/INTEL/dihedral_harmonic_intel.cpp index 8d91a3fd27..138545d94a 100644 --- a/src/INTEL/dihedral_harmonic_intel.cpp +++ b/src/INTEL/dihedral_harmonic_intel.cpp @@ -199,14 +199,14 @@ void DihedralHarmonicIntel::eval(const int vflag, const flt_t rasq = ax*ax + ay*ay + az*az; const flt_t rbsq = bx*bx + by*by + bz*bz; const flt_t rgsq = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; - const flt_t rg = sqrt(rgsq); + const flt_t rg = std::sqrt(rgsq); flt_t rginv, ra2inv, rb2inv; rginv = ra2inv = rb2inv = (flt_t)0.0; if (rg > 0) rginv = (flt_t)1.0/rg; if (rasq > 0) ra2inv = (flt_t)1.0/rasq; if (rbsq > 0) rb2inv = (flt_t)1.0/rbsq; - const flt_t rabinv = sqrt(ra2inv*rb2inv); + const flt_t rabinv = std::sqrt(ra2inv*rb2inv); flt_t c = (ax*bx + ay*by + az*bz)*rabinv; const flt_t s = rg*rabinv*(ax*vb3x + ay*vb3y + az*vb3z); diff --git a/src/INTEL/dihedral_opls_intel.cpp b/src/INTEL/dihedral_opls_intel.cpp index 82151a8585..52763e6bd8 100644 --- a/src/INTEL/dihedral_opls_intel.cpp +++ b/src/INTEL/dihedral_opls_intel.cpp @@ -195,15 +195,15 @@ void DihedralOPLSIntel::eval(const int vflag, // 1st and 2nd angle const flt_t b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; - const flt_t rb1 = (flt_t)1.0 / sqrt(b1mag2); + const flt_t rb1 = (flt_t)1.0 / std::sqrt(b1mag2); const flt_t sb1 = (flt_t)1.0 / b1mag2; const flt_t b2mag2 = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; - const flt_t rb2 = (flt_t)1.0 / sqrt(b2mag2); + const flt_t rb2 = (flt_t)1.0 / std::sqrt(b2mag2); const flt_t sb2 = (flt_t)1.0 / b2mag2; const flt_t b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; - const flt_t rb3 = (flt_t)1.0 / sqrt(b3mag2); + const flt_t rb3 = (flt_t)1.0 / std::sqrt(b3mag2); const flt_t sb3 = (flt_t)1.0 / b3mag2; const flt_t c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3; @@ -219,11 +219,11 @@ void DihedralOPLSIntel::eval(const int vflag, // cos and sin of 2 angles and final c flt_t sin2 = MAX((flt_t)1.0 - c1mag*c1mag,(flt_t)0.0); - flt_t sc1 = (flt_t)1.0/sqrt(sin2); + flt_t sc1 = (flt_t)1.0/std::sqrt(sin2); if (sin2 < SMALL2) sc1 = INVSMALL; sin2 = MAX((flt_t)1.0 - c2mag*c2mag,(flt_t)0.0); - flt_t sc2 = (flt_t)1.0/sqrt(sin2); + flt_t sc2 = (flt_t)1.0/std::sqrt(sin2); if (sin2 < SMALL2) sc2 = INVSMALL; const flt_t s1 = sc1 * sc1; @@ -234,7 +234,7 @@ void DihedralOPLSIntel::eval(const int vflag, const flt_t cx = vb1z*vb2ym - vb1y*vb2zm; const flt_t cy = vb1x*vb2zm - vb1z*vb2xm; const flt_t cz = vb1y*vb2xm - vb1x*vb2ym; - const flt_t cmag = (flt_t)1.0/sqrt(cx*cx + cy*cy + cz*cz); + const flt_t cmag = (flt_t)1.0/std::sqrt(cx*cx + cy*cy + cz*cz); const flt_t dx = (cx*vb3x + cy*vb3y + cz*vb3z)*cmag*rb3; // error check @@ -252,7 +252,7 @@ void DihedralOPLSIntel::eval(const int vflag, const flt_t cossq = c * c; const flt_t sinsq = (flt_t)1.0 - cossq; - flt_t siinv = (flt_t)1.0/sqrt(sinsq); + flt_t siinv = (flt_t)1.0/std::sqrt(sinsq); if (sinsq < SMALLER2 ) siinv = INVSMALLER; if (dx < (flt_t)0.0) siinv = -siinv; diff --git a/src/INTEL/fix_nh_intel.cpp b/src/INTEL/fix_nh_intel.cpp index 87ce0dbe43..2c05c3f6fa 100644 --- a/src/INTEL/fix_nh_intel.cpp +++ b/src/INTEL/fix_nh_intel.cpp @@ -166,28 +166,28 @@ void FixNHIntel::remap() if (pstyle == TRICLINIC) { if (p_flag[4]) { - expfac = exp(dto8*omega_dot[0]); + expfac = std::exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; } if (p_flag[3]) { - expfac = exp(dto4*omega_dot[1]); + expfac = std::exp(dto4*omega_dot[1]); h[3] *= expfac; h[3] += dto2*(omega_dot[3]*h[2]); h[3] *= expfac; } if (p_flag[5]) { - expfac = exp(dto4*omega_dot[0]); + expfac = std::exp(dto4*omega_dot[0]); h[5] *= expfac; h[5] += dto2*(omega_dot[5]*h[1]); h[5] *= expfac; } if (p_flag[4]) { - expfac = exp(dto8*omega_dot[0]); + expfac = std::exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; @@ -200,7 +200,7 @@ void FixNHIntel::remap() if (p_flag[0]) { oldlo = domain->boxlo[0]; oldhi = domain->boxhi[0]; - expfac = exp(dto*omega_dot[0]); + expfac = std::exp(dto*omega_dot[0]); domain->boxlo[0] = (oldlo-fixedpoint[0])*expfac + fixedpoint[0]; domain->boxhi[0] = (oldhi-fixedpoint[0])*expfac + fixedpoint[0]; } @@ -208,7 +208,7 @@ void FixNHIntel::remap() if (p_flag[1]) { oldlo = domain->boxlo[1]; oldhi = domain->boxhi[1]; - expfac = exp(dto*omega_dot[1]); + expfac = std::exp(dto*omega_dot[1]); domain->boxlo[1] = (oldlo-fixedpoint[1])*expfac + fixedpoint[1]; domain->boxhi[1] = (oldhi-fixedpoint[1])*expfac + fixedpoint[1]; if (scalexy) h[5] *= expfac; @@ -217,7 +217,7 @@ void FixNHIntel::remap() if (p_flag[2]) { oldlo = domain->boxlo[2]; oldhi = domain->boxhi[2]; - expfac = exp(dto*omega_dot[2]); + expfac = std::exp(dto*omega_dot[2]); domain->boxlo[2] = (oldlo-fixedpoint[2])*expfac + fixedpoint[2]; domain->boxhi[2] = (oldhi-fixedpoint[2])*expfac + fixedpoint[2]; if (scalexz) h[4] *= expfac; @@ -229,28 +229,28 @@ void FixNHIntel::remap() if (pstyle == TRICLINIC) { if (p_flag[4]) { - expfac = exp(dto8*omega_dot[0]); + expfac = std::exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; } if (p_flag[3]) { - expfac = exp(dto4*omega_dot[1]); + expfac = std::exp(dto4*omega_dot[1]); h[3] *= expfac; h[3] += dto2*(omega_dot[3]*h[2]); h[3] *= expfac; } if (p_flag[5]) { - expfac = exp(dto4*omega_dot[0]); + expfac = std::exp(dto4*omega_dot[0]); h[5] *= expfac; h[5] += dto2*(omega_dot[5]*h[1]); h[5] *= expfac; } if (p_flag[4]) { - expfac = exp(dto8*omega_dot[0]); + expfac = std::exp(dto8*omega_dot[0]); h[4] *= expfac; h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); h[4] *= expfac; @@ -427,9 +427,9 @@ void FixNHIntel::nh_v_press() int nlocal = atom->nlocal; if (igroup == atom->firstgroup) nlocal = atom->nfirst; - double f0 = exp(-dt4*(omega_dot[0]+mtk_term2)); - double f1 = exp(-dt4*(omega_dot[1]+mtk_term2)); - double f2 = exp(-dt4*(omega_dot[2]+mtk_term2)); + double f0 = std::exp(-dt4*(omega_dot[0]+mtk_term2)); + double f1 = std::exp(-dt4*(omega_dot[1]+mtk_term2)); + double f2 = std::exp(-dt4*(omega_dot[2]+mtk_term2)); f0 *= f0; f1 *= f1; f2 *= f2; diff --git a/src/INTEL/improper_cvff_intel.cpp b/src/INTEL/improper_cvff_intel.cpp index 09b2d42167..a503f45541 100644 --- a/src/INTEL/improper_cvff_intel.cpp +++ b/src/INTEL/improper_cvff_intel.cpp @@ -191,15 +191,15 @@ void ImproperCvffIntel::eval(const int vflag, // 1st and 2nd angle const flt_t b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z; - const flt_t rb1 = (flt_t)1.0 / sqrt(b1mag2); + const flt_t rb1 = (flt_t)1.0 / std::sqrt(b1mag2); const flt_t sb1 = (flt_t)1.0 / b1mag2; const flt_t b2mag2 = vb2xm*vb2xm + vb2ym*vb2ym + vb2zm*vb2zm; - const flt_t rb2 = (flt_t)1.0 / sqrt(b2mag2); + const flt_t rb2 = (flt_t)1.0 / std::sqrt(b2mag2); const flt_t sb2 = (flt_t)1.0 / b2mag2; const flt_t b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; - const flt_t rb3 = (flt_t)1.0 / sqrt(b3mag2); + const flt_t rb3 = (flt_t)1.0 / std::sqrt(b3mag2); const flt_t sb3 = (flt_t)1.0 / b3mag2; const flt_t c0 = (vb1x * vb3x + vb1y * vb3y + vb1z * vb3z) * rb1 * rb3; @@ -215,11 +215,11 @@ void ImproperCvffIntel::eval(const int vflag, // cos and sin of 2 angles and final c const flt_t sd1 = (flt_t)1.0 - c1mag * c1mag; - flt_t sc1 = (flt_t)1.0/sqrt(sd1); + flt_t sc1 = (flt_t)1.0/std::sqrt(sd1); if (sd1 < SMALL2) sc1 = INVSMALL; const flt_t sd2 = (flt_t)1.0 - c2mag * c2mag; - flt_t sc2 = (flt_t)1.0/sqrt(sd2); + flt_t sc2 = (flt_t)1.0/std::sqrt(sd2); if (sc2 < SMALL2) sc2 = INVSMALL; const flt_t s1 = sc1 * sc1; diff --git a/src/INTEL/improper_harmonic_intel.cpp b/src/INTEL/improper_harmonic_intel.cpp index a9a152d5f0..869051ab6b 100644 --- a/src/INTEL/improper_harmonic_intel.cpp +++ b/src/INTEL/improper_harmonic_intel.cpp @@ -194,9 +194,9 @@ void ImproperHarmonicIntel::eval(const int vflag, flt_t ss2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z; flt_t ss3 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z; - const flt_t r1 = (flt_t)1.0 / sqrt(ss1); - const flt_t r2 = (flt_t)1.0 / sqrt(ss2); - const flt_t r3 = (flt_t)1.0 / sqrt(ss3); + const flt_t r1 = (flt_t)1.0 / std::sqrt(ss1); + const flt_t r2 = (flt_t)1.0 / std::sqrt(ss2); + const flt_t r3 = (flt_t)1.0 / std::sqrt(ss3); ss1 = (flt_t)1.0 / ss1; ss2 = (flt_t)1.0 / ss2; @@ -214,7 +214,7 @@ void ImproperHarmonicIntel::eval(const int vflag, flt_t s2 = (flt_t)1.0 - c2*c2; if (s2 < SMALL) s2 = SMALL; - flt_t s12 = (flt_t)1.0 / sqrt(s1*s2); + flt_t s12 = (flt_t)1.0 / std::sqrt(s1*s2); s1 = (flt_t)1.0 / s1; s2 = (flt_t)1.0 / s2; flt_t c = (c1*c2 + c0) * s12; @@ -229,12 +229,12 @@ void ImproperHarmonicIntel::eval(const int vflag, if (c < (flt_t)-1.0) c = (flt_t)-1.0; const flt_t sd = (flt_t)1.0 - c * c; - flt_t s = (flt_t)1.0 / sqrt(sd); + flt_t s = (flt_t)1.0 / std::sqrt(sd); if (sd < SMALL2) s = INVSMALL; // force & energy - const flt_t domega = acos(c) - fc.fc[type].chi; + const flt_t domega = std::acos(c) - fc.fc[type].chi; flt_t a; a = fc.fc[type].k * domega; diff --git a/src/INTEL/intel_intrinsics.h b/src/INTEL/intel_intrinsics.h index 1ff405edd2..c106dfd411 100644 --- a/src/INTEL/intel_intrinsics.h +++ b/src/INTEL/intel_intrinsics.h @@ -1764,7 +1764,7 @@ struct vector_ops { return a < b; } static fvec invsqrt(const fvec &a) { - return 1. / sqrt(a); + return 1. / std::sqrt(a); } static fvec sincos(fvec *c, const fvec &a) { *c = cos(a); diff --git a/src/INTEL/math_extra_intel.h b/src/INTEL/math_extra_intel.h index a8869f7384..556f3f4590 100644 --- a/src/INTEL/math_extra_intel.h +++ b/src/INTEL/math_extra_intel.h @@ -100,12 +100,12 @@ normalize a vector, return in ans ------------------------------------------------------------------------- */ -#define ME_normalize3(v0, v1, v2, ans) \ -{ \ - flt_t scale = (flt_t)1.0 / sqrt(v0*v0+v1*v1+v2*v2); \ - ans##_0 = v0 * scale; \ - ans##_1 = v1 * scale; \ - ans##_2 = v2 * scale; \ +#define ME_normalize3(v0, v1, v2, ans) \ +{ \ + flt_t scale = (flt_t)1.0 / std::sqrt(v0*v0+v1*v1+v2*v2); \ + ans##_0 = v0 * scale; \ + ans##_1 = v1 * scale; \ + ans##_2 = v2 * scale; \ } /* ---------------------------------------------------------------------- @@ -359,7 +359,7 @@ #define ME_qnormalize(q) \ { \ double norm = 1.0 / \ - sqrt(q##_w*q##_w + q##_i*q##_i + q##_j*q##_j + q##_k*q##_k); \ + std::sqrt(q##_w*q##_w + q##_i*q##_i + q##_j*q##_j + q##_k*q##_k); \ q##_w *= norm; \ q##_i *= norm; \ q##_j *= norm; \ diff --git a/src/INTEL/pair_airebo_intel.cpp b/src/INTEL/pair_airebo_intel.cpp index 0b05447dd7..7bc2b3edb8 100644 --- a/src/INTEL/pair_airebo_intel.cpp +++ b/src/INTEL/pair_airebo_intel.cpp @@ -905,7 +905,7 @@ inline flt_t frebo_pij(KernelArgsAIREBOT * ka, int i, int j, flt_t rho_k = ka->params.rho[ktype][1]; flt_t rho_j = ka->params.rho[jtype][1]; flt_t lamdajik = 4 * itype * ((rho_k - rikmag) - (rho_j - rijmag)); - flt_t ex_lam = exp(lamdajik); + flt_t ex_lam = overloaded::exp(lamdajik); flt_t rcminik = ka->params.rcmin[itype][ktype]; flt_t rcmaxik = ka->params.rcmax[itype][ktype]; flt_t dwik; diff --git a/src/INTEL/pair_buck_coul_cut_intel.cpp b/src/INTEL/pair_buck_coul_cut_intel.cpp index 01a9f91bcf..424e38c16a 100644 --- a/src/INTEL/pair_buck_coul_cut_intel.cpp +++ b/src/INTEL/pair_buck_coul_cut_intel.cpp @@ -267,7 +267,7 @@ void PairBuckCoulCutIntel::eval(const int offload, const int vflag, const flt_t delz = ztmp - x[j].z; const int jtype = IP_PRE_dword_index(x[j].w); const flt_t rsq = delx * delx + dely * dely + delz * delz; - const flt_t r = sqrt(rsq); + const flt_t r = std::sqrt(rsq); const flt_t r2inv = (flt_t)1.0 / rsq; #ifdef INTEL_VMASK diff --git a/src/INTEL/pair_buck_coul_long_intel.cpp b/src/INTEL/pair_buck_coul_long_intel.cpp index ff57b571a4..48007c30d9 100644 --- a/src/INTEL/pair_buck_coul_long_intel.cpp +++ b/src/INTEL/pair_buck_coul_long_intel.cpp @@ -322,7 +322,7 @@ void PairBuckCoulLongIntel::eval(const int offload, const int vflag, const int jtype = tjtype[jj]; const flt_t rsq = trsq[jj]; const flt_t r2inv = (flt_t)1.0 / rsq; - const flt_t r = (flt_t)1.0 / sqrt(r2inv); + const flt_t r = (flt_t)1.0 / std::sqrt(r2inv); #ifdef INTEL_ALLOW_TABLE if (!ncoultablebits || rsq <= tabinnersq) { diff --git a/src/INTEL/pair_buck_intel.cpp b/src/INTEL/pair_buck_intel.cpp index 2461361788..1f2a033784 100644 --- a/src/INTEL/pair_buck_intel.cpp +++ b/src/INTEL/pair_buck_intel.cpp @@ -255,7 +255,7 @@ void PairBuckIntel::eval(const int offload, const int vflag, const flt_t delz = ztmp - x[j].z; const int jtype = IP_PRE_dword_index(x[j].w); const flt_t rsq = delx * delx + dely * dely + delz * delz; - const flt_t r = sqrt(rsq); + const flt_t r = std::sqrt(rsq); const flt_t r2inv = (flt_t)1.0 / rsq; #ifdef INTEL_VMASK diff --git a/src/INTEL/pair_dpd_intel.cpp b/src/INTEL/pair_dpd_intel.cpp index 011979223e..7b11053d41 100644 --- a/src/INTEL/pair_dpd_intel.cpp +++ b/src/INTEL/pair_dpd_intel.cpp @@ -180,7 +180,7 @@ void PairDPDIntel::eval(const int offload, const int vflag, ATOM_T * _noalias const x = buffers->get_x(offload); typedef struct { double x, y, z; } lmp_vt; auto *v = (lmp_vt *)atom->v[0]; - const flt_t dtinvsqrt = 1.0/sqrt(update->dt); + const flt_t dtinvsqrt = 1.0/std::sqrt(update->dt); const int * _noalias const ilist = list->ilist; const int * _noalias const numneigh = list->numneigh; @@ -322,7 +322,7 @@ void PairDPDIntel::eval(const int offload, const int vflag, icut = parami[jtype].icut; } const flt_t rsq = delx * delx + dely * dely + delz * delz; - const flt_t rinv = (flt_t)1.0/sqrt(rsq); + const flt_t rinv = (flt_t)1.0/std::sqrt(rsq); if (rinv > icut) { flt_t factor_dpd, factor_sqrt; diff --git a/src/INTEL/pair_eam_intel.cpp b/src/INTEL/pair_eam_intel.cpp index ba5047a15a..9c5d6da5e5 100644 --- a/src/INTEL/pair_eam_intel.cpp +++ b/src/INTEL/pair_eam_intel.cpp @@ -340,7 +340,7 @@ void PairEAMIntel::eval(const int offload, const int vflag, const int j = tj[jj] & NEIGHMASK; if (!ONETYPE) jtype = tjtype[jj]; const flt_t rsq = trsq[jj]; - flt_t p = sqrt(rsq)*frdr + (flt_t)1.0; + flt_t p = std::sqrt(rsq)*frdr + (flt_t)1.0; int m = static_cast (p); m = MIN(m,nr-1); p -= m; @@ -546,7 +546,7 @@ void PairEAMIntel::eval(const int offload, const int vflag, const int j = tj[jj] & NEIGHMASK; if (!ONETYPE) jtype = tjtype[jj]; const flt_t rsq = trsq[jj]; - const flt_t r = sqrt(rsq); + const flt_t r = std::sqrt(rsq); flt_t p = r*frdr + (flt_t)1.0; int m = static_cast (p); m = MIN(m,nr-1); diff --git a/src/INTEL/pair_gayberne_intel.cpp b/src/INTEL/pair_gayberne_intel.cpp index 5609479388..92e074e5e1 100644 --- a/src/INTEL/pair_gayberne_intel.cpp +++ b/src/INTEL/pair_gayberne_intel.cpp @@ -492,7 +492,7 @@ void PairGayBerneIntel::eval(const int offload, const int vflag, flt_t r12hat_0, r12hat_1, r12hat_2; ME_normalize3(delx_form[jj], dely_form[jj], delz_form[jj], r12hat); - flt_t r = sqrt(rsq_form[jj]); + flt_t r = std::sqrt(rsq_form[jj]); // compute distance of closest approach diff --git a/src/INTEL/pair_lj_charmm_coul_charmm_intel.cpp b/src/INTEL/pair_lj_charmm_coul_charmm_intel.cpp index e920257ef4..faae6e5cbc 100644 --- a/src/INTEL/pair_lj_charmm_coul_charmm_intel.cpp +++ b/src/INTEL/pair_lj_charmm_coul_charmm_intel.cpp @@ -306,7 +306,7 @@ void PairLJCharmmCoulCharmmIntel::eval(const int offload, const int vflag, const int sbindex = tj[jj] >> SBBITS & 3; const flt_t rsq = trsq[jj]; const flt_t r2inv = (flt_t)1.0 / rsq; - const flt_t r_inv = (flt_t)1.0 / sqrt(rsq); + const flt_t r_inv = (flt_t)1.0 / std::sqrt(rsq); forcecoul = qqrd2e * qtmp * q[j] * r_inv; if (rsq > cut_coul_innersq) { const flt_t ccr = cut_coulsq - rsq; diff --git a/src/INTEL/pair_lj_charmm_coul_long_intel.cpp b/src/INTEL/pair_lj_charmm_coul_long_intel.cpp index 0a93621bcd..412af17357 100644 --- a/src/INTEL/pair_lj_charmm_coul_long_intel.cpp +++ b/src/INTEL/pair_lj_charmm_coul_long_intel.cpp @@ -339,7 +339,7 @@ void PairLJCharmmCoulLongIntel::eval(const int offload, const int vflag, const flt_t EWALD_F = 1.12837917; const flt_t INV_EWALD_P = 1.0 / 0.3275911; - const flt_t r = (flt_t)1.0 / sqrt(r2inv); + const flt_t r = (flt_t)1.0 / std::sqrt(r2inv); const flt_t grij = g_ewald * r; const flt_t expm2 = std::exp(-grij * grij); const flt_t t = INV_EWALD_P / (INV_EWALD_P + grij); @@ -591,10 +591,10 @@ void PairLJCharmmCoulLongIntel::pack_force_const(ForceConst &fc, for (int j = 1; j < tp1; j++) { if (i <= j) { fc.lj[i][j].x = epsilon[i][j] * 4.0; - fc.lj[i][j].y = pow(sigma[i][j],6.0); + fc.lj[i][j].y = std::pow(sigma[i][j],6.0); } else { fc.lj[i][j].x = epsilon[j][i] * 4.0; - fc.lj[i][j].y = pow(sigma[j][i],6.0); + fc.lj[i][j].y = std::pow(sigma[j][i],6.0); } fc.cutsq[i][j] = cutsq[i][j]; } diff --git a/src/INTEL/pair_lj_cut_coul_long_intel.cpp b/src/INTEL/pair_lj_cut_coul_long_intel.cpp index 89e556defa..5eb3cbc1f7 100644 --- a/src/INTEL/pair_lj_cut_coul_long_intel.cpp +++ b/src/INTEL/pair_lj_cut_coul_long_intel.cpp @@ -332,7 +332,7 @@ void PairLJCutCoulLongIntel::eval(const int offload, const int vflag, const flt_t EWALD_F = 1.12837917; const flt_t INV_EWALD_P = 1.0 / 0.3275911; - const flt_t r = (flt_t)1.0 / sqrt(r2inv); + const flt_t r = (flt_t)1.0 / std::sqrt(r2inv); const flt_t grij = g_ewald * r; const flt_t expm2 = std::exp(-grij * grij); const flt_t t = INV_EWALD_P / (INV_EWALD_P + grij); diff --git a/src/INTEL/pair_sw_intel.cpp b/src/INTEL/pair_sw_intel.cpp index 07d590ee2c..fa62f499de 100644 --- a/src/INTEL/pair_sw_intel.cpp +++ b/src/INTEL/pair_sw_intel.cpp @@ -382,7 +382,7 @@ void PairSWIntel::eval(const int offload, const int vflag, const flt_t rsq1 = trsq[jj]; const flt_t rinvsq1 = (flt_t)1.0 / rsq1; - const flt_t r1 = (flt_t)1.0/sqrt(rinvsq1); + const flt_t r1 = (flt_t)1.0/std::sqrt(rinvsq1); if (!ONETYPE) cut = p2f[ijtype].cut; const flt_t rainv1 = (flt_t)1.0 / (r1 - cut); @@ -475,7 +475,7 @@ void PairSWIntel::eval(const int offload, const int vflag, const flt_t rsq2 = trsq[kk]; const flt_t rinvsq2 = (flt_t)1.0 / rsq2; - const flt_t r2 = (flt_t)1.0 / sqrt(rinvsq2); + const flt_t r2 = (flt_t)1.0 / std::sqrt(rinvsq2); const flt_t rainv2 = (flt_t)1.0 / (r2 - cut); const flt_t gsrainv2 = sigma_gamma * rainv2; const flt_t gsrainvsq2 = gsrainv2 * rainv2 / r2; diff --git a/src/INTEL/pppm_disp_intel.cpp b/src/INTEL/pppm_disp_intel.cpp index fdff23fe5e..e17c077c6e 100644 --- a/src/INTEL/pppm_disp_intel.cpp +++ b/src/INTEL/pppm_disp_intel.cpp @@ -662,8 +662,8 @@ void PPPMDispIntel::compute(int eflag, int vflag) energy_1 -= g_ewald*qsqsum/MY_PIS + MY_PI2*qsum*qsum / (g_ewald*g_ewald*volume); - energy_6 += - MY_PI*MY_PIS/(6*volume)*pow(g_ewald_6,3)*csumij + - 1.0/12.0*pow(g_ewald_6,6)*csum; + energy_6 += - MY_PI*MY_PIS/(6*volume)*std::pow(g_ewald_6,3)*csumij + + 1.0/12.0*std::pow(g_ewald_6,6)*csum; energy_1 *= qscale; } @@ -676,7 +676,7 @@ void PPPMDispIntel::compute(int eflag, int vflag) MPI_Allreduce(virial_6,virial_all,6,MPI_DOUBLE,MPI_SUM,world); for (i = 0; i < 6; i++) virial[i] += 0.5*volume*virial_all[i]; if (function[1]+function[2]+function[3]) { - double a = MY_PI*MY_PIS/(6*volume)*pow(g_ewald_6,3)*csumij; + double a = MY_PI*MY_PIS/(6*volume)*std::pow(g_ewald_6,3)*csumij; virial[0] -= a; virial[1] -= a; virial[2] -= a; @@ -695,8 +695,8 @@ void PPPMDispIntel::compute(int eflag, int vflag) int tmp; for (i = 0; i < atom->nlocal; i++) { tmp = atom->type[i]; - eatom[i] += - MY_PI*MY_PIS/(6*volume)*pow(g_ewald_6,3)*csumi[tmp] + - 1.0/12.0*pow(g_ewald_6,6)*cii[tmp]; + eatom[i] += - MY_PI*MY_PIS/(6*volume)*std::pow(g_ewald_6,3)* + csumi[tmp] + 1.0/12.0*std::pow(g_ewald_6,6)*cii[tmp]; } } } @@ -708,7 +708,7 @@ void PPPMDispIntel::compute(int eflag, int vflag) tmp = atom->type[i]; //dispersion self virial correction for (int n = 0; n < 3; n++) vatom[i][n] -= MY_PI*MY_PIS/(6*volume)* - pow(g_ewald_6,3)*csumi[tmp]; + std::pow(g_ewald_6,3)*csumi[tmp]; } } } @@ -1788,18 +1788,18 @@ void PPPMDispIntel::fieldforce_c_ad(IntelBuffers * /*buffers*/) const flt_t s1 = x[i][0] * hx_inv; const flt_t s2 = x[i][1] * hy_inv; const flt_t s3 = x[i][2] * hz_inv; - flt_t sf = fsf_coeff0 * sin(ftwo_pi * s1); - sf += fsf_coeff1 * sin(ffour_pi * s1); + flt_t sf = fsf_coeff0 * std::sin(ftwo_pi * s1); + sf += fsf_coeff1 * std::sin(ffour_pi * s1); sf *= twoqsq; f[i][0] += qfactor * particle_ekx[i] - fqqrd2es * sf; - sf = fsf_coeff2 * sin(ftwo_pi * s2); - sf += fsf_coeff3 * sin(ffour_pi * s2); + sf = fsf_coeff2 * std::sin(ftwo_pi * s2); + sf += fsf_coeff3 * std::sin(ffour_pi * s2); sf *= twoqsq; f[i][1] += qfactor * particle_eky[i] - fqqrd2es * sf; - sf = fsf_coeff4 * sin(ftwo_pi * s3); - sf += fsf_coeff5 * sin(ffour_pi * s3); + sf = fsf_coeff4 * std::sin(ftwo_pi * s3); + sf += fsf_coeff5 * std::sin(ffour_pi * s3); sf *= twoqsq; if (slabflag != 2) f[i][2] += qfactor * particle_ekz[i] - fqqrd2es * sf; @@ -2160,18 +2160,18 @@ void PPPMDispIntel::fieldforce_g_ad(IntelBuffers * /*buffers*/) const flt_t s1 = x[i][0] * hx_inv; const flt_t s2 = x[i][1] * hy_inv; const flt_t s3 = x[i][2] * hz_inv; - flt_t sf = fsf_coeff0 * sin(ftwo_pi * s1); - sf += fsf_coeff1 * sin(ffour_pi * s1); + flt_t sf = fsf_coeff0 * std::sin(ftwo_pi * s1); + sf += fsf_coeff1 * std::sin(ffour_pi * s1); sf *= twoljsq; f[i][0] += lj * particle_ekx[i] - sf; - sf = fsf_coeff2 * sin(ftwo_pi * s2); - sf += fsf_coeff3 * sin(ffour_pi * s2); + sf = fsf_coeff2 * std::sin(ftwo_pi * s2); + sf += fsf_coeff3 * std::sin(ffour_pi * s2); sf *= twoljsq; f[i][1] += lj * particle_eky[i] - sf; - sf = fsf_coeff4 * sin(ftwo_pi * s3); - sf += fsf_coeff5 * sin(ffour_pi * s3); + sf = fsf_coeff4 * std::sin(ftwo_pi * s3); + sf += fsf_coeff5 * std::sin(ffour_pi * s3); sf *= twoljsq; if (slabflag != 2) f[i][2] += lj * particle_ekz[i] - sf; @@ -2707,22 +2707,22 @@ void PPPMDispIntel::fieldforce_a_ad(IntelBuffers * /*buffers*/) const flt_t s1 = x[i][0] * hx_inv; const flt_t s2 = x[i][1] * hy_inv; const flt_t s3 = x[i][2] * hz_inv; - flt_t sf = fsf_coeff0 * sin(ftwo_pi * s1); - sf += fsf_coeff1 * sin(ffour_pi * s1); + flt_t sf = fsf_coeff0 * std::sin(ftwo_pi * s1); + sf += fsf_coeff1 * std::sin(ffour_pi * s1); sf *= 4*lj0*lj6 + 4*lj1*lj5 + 4*lj2*lj4 + 2*lj3*lj3; f[i][0] += lj0*particle_ekx0[i] + lj1*particle_ekx1[i] + lj2*particle_ekx2[i] + lj3*particle_ekx3[i] + lj4*particle_ekx4[i] + lj5*particle_ekx5[i] + lj6*particle_ekx6[i] - sf; - sf = fsf_coeff2 * sin(ftwo_pi * s2); - sf += fsf_coeff3 * sin(ffour_pi * s2); + sf = fsf_coeff2 * std::sin(ftwo_pi * s2); + sf += fsf_coeff3 * std::sin(ffour_pi * s2); sf *= 4*lj0*lj6 + 4*lj1*lj5 + 4*lj2*lj4 + 2*lj3*lj3; f[i][1] += lj0*particle_eky0[i] + lj1*particle_eky1[i] + lj2*particle_eky2[i] + lj3*particle_eky3[i] + lj4*particle_eky4[i] + lj5*particle_eky5[i] + lj6*particle_eky6[i] - sf; - sf = fsf_coeff4 * sin(ftwo_pi * s3); - sf += fsf_coeff5 * sin(ffour_pi * s3); + sf = fsf_coeff4 * std::sin(ftwo_pi * s3); + sf += fsf_coeff5 * std::sin(ffour_pi * s3); sf *= 4*lj0*lj6 + 4*lj1*lj5 + 4*lj2*lj4 + 2*lj3*lj3; if (slabflag != 2) f[i][2] += lj0*particle_ekz0[i] + lj1*particle_ekz1[i] + @@ -3106,14 +3106,14 @@ void PPPMDispIntel::fieldforce_none_ad(IntelBuffers * /*buffers*/) const flt_t s1 = x[i][0] * hx_inv; const flt_t s2 = x[i][1] * hy_inv; const flt_t s3 = x[i][2] * hz_inv; - flt_t sf1 = fsf_coeff0 * sin(ftwo_pi * s1); - sf1 += fsf_coeff1 * sin(ffour_pi * s1); + flt_t sf1 = fsf_coeff0 * std::sin(ftwo_pi * s1); + sf1 += fsf_coeff1 * std::sin(ffour_pi * s1); - flt_t sf2 = fsf_coeff2 * sin(ftwo_pi * s2); - sf2 += fsf_coeff3 * sin(ffour_pi * s2); + flt_t sf2 = fsf_coeff2 * std::sin(ftwo_pi * s2); + sf2 += fsf_coeff3 * std::sin(ffour_pi * s2); - flt_t sf3 = fsf_coeff4 * sin(ftwo_pi * s3); - sf3 += fsf_coeff5 * sin(ffour_pi * s3); + flt_t sf3 = fsf_coeff4 * std::sin(ftwo_pi * s3); + sf3 += fsf_coeff5 * std::sin(ffour_pi * s3); for (int k = 0; k < nsplit; k++) { const flt_t lj = B[nsplit*type + k]; const flt_t twoljsq = lj*lj * B[k] * 2; diff --git a/src/INTEL/pppm_intel.cpp b/src/INTEL/pppm_intel.cpp index 2ceca54d29..f67b3a89b3 100644 --- a/src/INTEL/pppm_intel.cpp +++ b/src/INTEL/pppm_intel.cpp @@ -953,18 +953,18 @@ void PPPMIntel::fieldforce_ad(IntelBuffers *buffers) const flt_t s1 = x[i].x * hx_inv; const flt_t s2 = x[i].y * hy_inv; const flt_t s3 = x[i].z * hz_inv; - flt_t sf = fsf_coeff0 * sin(ftwo_pi * s1); - sf += fsf_coeff1 * sin(ffour_pi * s1); + flt_t sf = fsf_coeff0 * std::sin(ftwo_pi * s1); + sf += fsf_coeff1 * std::sin(ffour_pi * s1); sf *= twoqsq; f[i].x += qfactor * particle_ekx[i] - fqqrd2es * sf; - sf = fsf_coeff2 * sin(ftwo_pi * s2); - sf += fsf_coeff3 * sin(ffour_pi * s2); + sf = fsf_coeff2 * std::sin(ftwo_pi * s2); + sf += fsf_coeff3 * std::sin(ffour_pi * s2); sf *= twoqsq; f[i].y += qfactor * particle_eky[i] - fqqrd2es * sf; - sf = fsf_coeff4 * sin(ftwo_pi * s3); - sf += fsf_coeff5 * sin(ffour_pi * s3); + sf = fsf_coeff4 * std::sin(ftwo_pi * s3); + sf += fsf_coeff5 * std::sin(ffour_pi * s3); sf *= twoqsq; if (slabflag != 2) f[i].z += qfactor * particle_ekz[i] - fqqrd2es * sf; From 0dab1910db6c6e8fb945567131f7da287f6b5e44 Mon Sep 17 00:00:00 2001 From: "W. Michael Brown" Date: Sat, 10 Jun 2023 13:34:16 -0700 Subject: [PATCH 384/448] Small updates to benchmark script in INTEL/TEST --- src/INTEL/TEST/run_benchmarks.sh | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/INTEL/TEST/run_benchmarks.sh b/src/INTEL/TEST/run_benchmarks.sh index 01ddfbebf3..82eb51c928 100755 --- a/src/INTEL/TEST/run_benchmarks.sh +++ b/src/INTEL/TEST/run_benchmarks.sh @@ -7,12 +7,10 @@ # --------------------- MPI Launch Command export MPI="mpirun" -#export MPI="numactl -p 1 mpirun" # -- Systems w/ MCDRAM in flat mode # ------------- Name and location of the LAMMPS binary export LMP_BIN=../../lmp_intel_cpu_intelmpi -#export LMP_BIN=../../lmp_knl # ------------- Directory containing the LAMMPS installation @@ -20,21 +18,18 @@ export LMP_ROOT=../../../ # ------------- Number of physical cores (not HW threads) -export LMP_CORES=36 # -- For Intel Xeon E5-2697v4 SKU -#export LMP_CORES=68 # -- For Intel Xeon Phi x200 7250 SKU +export LMP_CORES=36 +# Set automatically with lscpu +export LMP_CORES=`lscpu | awk '$1=="Core(s)"{t=NF; cores=$t}$1=="Socket(s):"{t=NF; sockets=$t}END{print cores*sockets}'` # ------------- Number of HW threads to use in tests -export LMP_THREAD_LIST="2" # -- For 2 threads per core w/ HT enabled -#export LMP_THREAD_LIST="2 4" # -- For 2 threads per core w/ HT enabled +export LMP_THREAD_LIST="1 2" # -- Also test 2 threads per core w/ HT enabled # ------------- MPI Tuning Parameters -#export I_MPI_SHM_LMT=shm # -- Uncomment for Xeon Phi x200 series - -# ------------- Library locations for build - -#source /opt/intel/parallel_studio_xe_2017.2.050/psxevars.sh +export I_MPI_FABRICS=shm +export I_MPI_PIN_DOMAIN=core ######################################################################### # End settings for your system @@ -50,8 +45,6 @@ export DATE_STRING=`date +%s` export LOG_DIR=$LOG_DIR_HOST"_"$LOG_DIR_HEADER"_"$DATE_STRING mkdir $LOG_DIR -export I_MPI_PIN_DOMAIN=core -#export I_MPI_FABRICS=shm export KMP_BLOCKTIME=0 echo -n "Creating restart file...." @@ -73,6 +66,9 @@ do export LOGFILE=$LOG_DIR/$workload"_lrt".$LMP_CORES"c"$threads"t".log cmd="$MPI -np $LMP_CORES $LMP_BIN -in in.intel.$workload -log $LOGFILE $RLMP_ARGS"; rthreads=$((threads-1)) + if [ $rthreads -lt 1 ]; then + rthreads=1 + fi export KMP_AFFINITY=none export OMP_NUM_THREADS=$rthreads echo " $cmd" >> $LOG_DIR/commands.info @@ -82,4 +78,5 @@ do done # Performance reported by LAMMPS (Timesteps/second ignoring warm-up run) -grep Perf $LOG_DIR/*.log | awk 'BEGIN{n=1}n%2==0{print $0}{n++}' | sed 's/\/day//g' | sed 's/steps\/s/steps_s/g' | sed 's/hours\/ns//g' | sed 's/.*\///g' | sed 's/\.log:Performance://g' | awk '{c=NF-1; print $1,$c}' +grep Perf $LOG_DIR/*.log | awk 'n%2==1{c=NF-3; print $1,$c}{n++}' | sed -e 's/.*\///g' -e 's/:.*://g' + From 62b388b48fd34e1d5e2bfbd4af221ad062f4847e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 10 Jun 2023 19:23:11 -0400 Subject: [PATCH 385/448] consolidate LAMMPS data type constants and enums and use the same names --- examples/COUPLE/plugin/liblammpsplugin.h | 5 +++-- fortran/lammps.f90 | 3 ++- python/lammps/constants.py | 8 ++++++-- src/EXTRA-DUMP/dump_yaml.cpp | 6 +++--- src/NETCDF/dump_netcdf.cpp | 12 ++++++------ src/NETCDF/dump_netcdf_mpiio.cpp | 12 ++++++------ src/library.cpp | 6 +++--- src/library.h | 3 ++- src/lmptype.h | 25 ++++++++++++++++++------ tools/swig/lammps.i | 3 ++- unittest/utils/test_lmptype.cpp | 16 +++++++-------- 11 files changed, 60 insertions(+), 39 deletions(-) diff --git a/examples/COUPLE/plugin/liblammpsplugin.h b/examples/COUPLE/plugin/liblammpsplugin.h index 40fba6b9e3..1520ef638d 100644 --- a/examples/COUPLE/plugin/liblammpsplugin.h +++ b/examples/COUPLE/plugin/liblammpsplugin.h @@ -37,12 +37,13 @@ #endif /* The following enums must be kept in sync with the equivalent enums - * or constants in python/lammps/constants.py, fortran/lammps.f90, - * tools/swig/lammps.i, and examples/COUPLE/plugin/liblammpsplugin.h */ + * or constants in src/library.h, src/lmptype.h, python/lammps/constants.py, + * fortran/lammps.f90, and tools/swig/lammps.i */ /* Data type constants for extracting data from atoms, computes and fixes */ enum _LMP_DATATYPE_CONST { + LAMMPS_NONE = -1, /*!< no data type assigned (yet) */ LAMMPS_INT = 0, /*!< 32-bit integer (array) */ LAMMPS_INT_2D = 1, /*!< two-dimensional 32-bit integer array */ LAMMPS_DOUBLE = 2, /*!< 64-bit double (array) */ diff --git a/fortran/lammps.f90 b/fortran/lammps.f90 index f511e6bb60..669e9c700d 100644 --- a/fortran/lammps.f90 +++ b/fortran/lammps.f90 @@ -44,11 +44,12 @@ MODULE LIBLAMMPS ! Data type constants for extracting data from global, atom, compute, and fix ! ! Must be kept in sync with the equivalent declarations in - ! src/library.h, python/lammps/constants.py, tools/swig/lammps.i, + ! src/library.h, src/lmptype.h, python/lammps/constants.py, tools/swig/lammps.i, ! and examples/COUPLE/plugin/liblammpsplugin.h ! ! These are NOT part of the API (the part the user sees) INTEGER(c_int), PARAMETER :: & + LAMMPS_NONE = -1, & ! no data type assigned (yet) LAMMPS_INT = 0, & ! 32-bit integer (or array) LAMMPS_INT_2D = 1, & ! two-dimensional 32-bit integer array LAMMPS_DOUBLE = 2, & ! 64-bit double (or array) diff --git a/python/lammps/constants.py b/python/lammps/constants.py index 8fd6a9eaf5..1d0d8adb78 100644 --- a/python/lammps/constants.py +++ b/python/lammps/constants.py @@ -13,7 +13,13 @@ # various symbolic constants to be used # in certain calls to select data formats + +# these must be kept in sync with the enums in src/library.h, src/lmptype.h, +# tools/swig/lammps.i, examples/COUPLE/plugin/liblammpsplugin.h, +# and the constants in fortran/lammps.f90 + LAMMPS_AUTODETECT = None +LAMMPS_NONE = -1 LAMMPS_INT = 0 LAMMPS_INT_2D = 1 LAMMPS_DOUBLE = 2 @@ -22,8 +28,6 @@ LAMMPS_INT64 = 4 LAMMPS_INT64_2D = 5 LAMMPS_STRING = 6 -# these must be kept in sync with the enums in src/library.h, tools/swig/lammps.i, -# examples/COUPLE/plugin/liblammpsplugin.h, and the constants in fortran/lammps.f90 LMP_STYLE_GLOBAL = 0 LMP_STYLE_ATOM = 1 LMP_STYLE_LOCAL = 2 diff --git a/src/EXTRA-DUMP/dump_yaml.cpp b/src/EXTRA-DUMP/dump_yaml.cpp index 47cab1ee02..3ca5c59edf 100644 --- a/src/EXTRA-DUMP/dump_yaml.cpp +++ b/src/EXTRA-DUMP/dump_yaml.cpp @@ -71,11 +71,11 @@ void DumpYAML::write_header(bigint ndump) thermo_data += "]\n - data: [ "; for (int i = 0; i < nfield; ++i) { - if (fields[i].type == multitype::DOUBLE) + if (fields[i].type == multitype::LAMMPS_DOUBLE) thermo_data += fmt::format("{}, ", fields[i].data.d); - else if (fields[i].type == multitype::INT) + else if (fields[i].type == multitype::LAMMPS_INT) thermo_data += fmt::format("{}, ", fields[i].data.i); - else if (fields[i].type == multitype::BIGINT) + else if (fields[i].type == multitype::LAMMPS_INT64) thermo_data += fmt::format("{}, ", fields[i].data.b); else thermo_data += ", "; diff --git a/src/NETCDF/dump_netcdf.cpp b/src/NETCDF/dump_netcdf.cpp index 0115c0bbe9..a4699897a3 100644 --- a/src/NETCDF/dump_netcdf.cpp +++ b/src/NETCDF/dump_netcdf.cpp @@ -442,11 +442,11 @@ void DumpNetCDF::openfile() const int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { - if (fields[i].type == multitype::DOUBLE) { + if (fields[i].type == multitype::LAMMPS_DOUBLE) { NCERRX( nc_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() ); - } else if (fields[i].type == multitype::INT) { + } else if (fields[i].type == multitype::LAMMPS_INT) { NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() ); - } else if (fields[i].type == multitype::BIGINT) { + } else if (fields[i].type == multitype::LAMMPS_INT64) { NCERRX( nc_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() ); } } @@ -624,11 +624,11 @@ void DumpNetCDF::write() int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { if (filewriter) { - if (fields[i].type == multitype::DOUBLE) { + if (fields[i].type == multitype::LAMMPS_DOUBLE) { NCERRX( nc_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() ); - } else if (fields[i].type == multitype::INT) { + } else if (fields[i].type == multitype::LAMMPS_INT) { NCERRX( nc_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() ); - } else if (fields[i].type == multitype::BIGINT) { + } else if (fields[i].type == multitype::LAMMPS_INT64) { NCERRX( nc_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() ); } } diff --git a/src/NETCDF/dump_netcdf_mpiio.cpp b/src/NETCDF/dump_netcdf_mpiio.cpp index f9382dacef..2407678386 100644 --- a/src/NETCDF/dump_netcdf_mpiio.cpp +++ b/src/NETCDF/dump_netcdf_mpiio.cpp @@ -432,11 +432,11 @@ void DumpNetCDFMPIIO::openfile() const int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { - if (fields[i].type == multitype::DOUBLE) { + if (fields[i].type == multitype::LAMMPS_DOUBLE) { NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), type_nc_real, 1, dims, &thermovar[i]), keywords[i].c_str() ); - } else if (fields[i].type == multitype::INT) { + } else if (fields[i].type == multitype::LAMMPS_INT) { NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT, 1, dims, &thermovar[i]), keywords[i].c_str() ); - } else if (fields[i].type == multitype::BIGINT) { + } else if (fields[i].type == multitype::LAMMPS_INT64) { NCERRX( ncmpi_def_var(ncid, keywords[i].c_str(), NC_INT64, 1, dims, &thermovar[i]), keywords[i].c_str() ); } } @@ -617,11 +617,11 @@ void DumpNetCDFMPIIO::write() int nfield = *th->get_nfield(); for (int i = 0; i < nfield; i++) { if (filewriter) { - if (fields[i].type == multitype::DOUBLE) { + if (fields[i].type == multitype::LAMMPS_DOUBLE) { NCERRX( ncmpi_put_var1_double(ncid, thermovar[i], start, &fields[i].data.d), keywords[i].c_str() ); - } else if (fields[i].type == multitype::INT) { + } else if (fields[i].type == multitype::LAMMPS_INT) { NCERRX( ncmpi_put_var1_int(ncid, thermovar[i], start, &fields[i].data.i), keywords[i].c_str() ); - } else if (fields[i].type == multitype::BIGINT) { + } else if (fields[i].type == multitype::LAMMPS_INT64) { NCERRX( ncmpi_put_var1_bigint(ncid, thermovar[i], start, &fields[i].data.b), keywords[i].c_str() ); } } diff --git a/src/library.cpp b/src/library.cpp index a94e385148..96af7cbf43 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -836,11 +836,11 @@ void *lammps_last_thermo(void *handle, const char *what, int index) } else if (strcmp(what, "data") == 0) { if ((index < 0) || (index >= nfield)) return nullptr; const auto &field = th->get_fields()[index]; - if (field.type == multitype::INT) { + if (field.type == multitype::LAMMPS_INT) { val = (void *) &field.data.i; - } else if (field.type == multitype::BIGINT) { + } else if (field.type == multitype::LAMMPS_INT64) { val = (void *) &field.data.b; - } else if (field.type == multitype::DOUBLE) { + } else if (field.type == multitype::LAMMPS_DOUBLE) { val = (void *) &field.data.d; } diff --git a/src/library.h b/src/library.h index 5f46e36ccf..30a12ebdef 100644 --- a/src/library.h +++ b/src/library.h @@ -41,10 +41,11 @@ /** Data type constants for extracting data from atoms, computes and fixes * * Must be kept in sync with the equivalent constants in ``python/lammps/constants.py``, - * ``fortran/lammps.f90``, ``tools/swig/lammps.i``, and + * ``fortran/lammps.f90``, ``tools/swig/lammps.i``, ``src/lmptype.h``, and *``examples/COUPLE/plugin/liblammpsplugin.h`` */ enum _LMP_DATATYPE_CONST { + LAMMPS_NONE = -1, /*!< no data type assigned (yet) */ LAMMPS_INT = 0, /*!< 32-bit integer (array) */ LAMMPS_INT_2D = 1, /*!< two-dimensional 32-bit integer array */ LAMMPS_DOUBLE = 2, /*!< 64-bit double (array) */ diff --git a/src/lmptype.h b/src/lmptype.h index e559bd9416..2089350f48 100644 --- a/src/lmptype.h +++ b/src/lmptype.h @@ -276,8 +276,21 @@ union ubuf { \endverbatim */ struct multitype { - // same values as LAMMPS_INT, LAMMPS_DOUBLE, and LAMMPS_INT64 in library.h - enum { NONE = -1, INT = 0, DOUBLE = 2, BIGINT = 4 }; + /** Data type constants for extracting data from atoms, computes and fixes + * + * This enum must be kept in sync with the corresponding enum or constants + * in ``python/lammps/constants.py``, ``fortran/lammps.f90``, ``tools/swig/lammps.i``, + * ``src/library.h``, and ``examples/COUPLE/plugin/liblammpsplugin.h`` */ + enum _LMP_DATATYPE_CONST { + LAMMPS_NONE = -1, /*!< no data type assigned (yet) */ + LAMMPS_INT = 0, /*!< 32-bit integer (array) */ + LAMMPS_INT_2D = 1, /*!< two-dimensional 32-bit integer array */ + LAMMPS_DOUBLE = 2, /*!< 64-bit double (array) */ + LAMMPS_DOUBLE_2D = 3, /*!< two-dimensional 64-bit double array */ + LAMMPS_INT64 = 4, /*!< 64-bit integer (array) */ + LAMMPS_INT64_2D = 5, /*!< two-dimensional 64-bit integer array */ + LAMMPS_STRING = 6 /*!< C-String */ + }; int type; union { @@ -286,26 +299,26 @@ struct multitype { int64_t b; } data; - multitype() : type(NONE) { data.d = 0.0; } + multitype() : type(LAMMPS_NONE) { data.d = 0.0; } multitype(const multitype &) = default; multitype(multitype &&) = default; ~multitype() = default; multitype &operator=(const double &_d) { - type = DOUBLE; + type = LAMMPS_DOUBLE; data.d = _d; return *this; } multitype &operator=(const int &_i) { - type = INT; + type = LAMMPS_INT; data.i = _i; return *this; } multitype &operator=(const int64_t &_b) { - type = BIGINT; + type = LAMMPS_INT64; data.b = _b; return *this; } diff --git a/tools/swig/lammps.i b/tools/swig/lammps.i index c4ef0a7109..91a6866107 100644 --- a/tools/swig/lammps.i +++ b/tools/swig/lammps.i @@ -28,9 +28,10 @@ * * Must be kept in sync with the equivalent constants in ``src/library.h``, * ``python/lammps/constants.py``, ``examples/COUPLE/plugin/liblammpsplugin.h``, - * and ``fortran/lammps.f90`` */ + * ``src/lmptype.h``, and ``fortran/lammps.f90`` */ enum _LMP_DATATYPE_CONST { + LAMMPS_NONE =-1, /*!< no data type assigned (yet) */ LAMMPS_INT = 0, /*!< 32-bit integer (array) */ LAMMPS_INT_2D = 1, /*!< two-dimensional 32-bit integer array */ LAMMPS_DOUBLE = 2, /*!< 64-bit double (array) */ diff --git a/unittest/utils/test_lmptype.cpp b/unittest/utils/test_lmptype.cpp index e5dc871953..383c9d4b2c 100644 --- a/unittest/utils/test_lmptype.cpp +++ b/unittest/utils/test_lmptype.cpp @@ -54,18 +54,18 @@ TEST(Types, multitype) m[4] = -1023; m[5] = -2.225; - EXPECT_EQ(m[0].type, multitype::BIGINT); - EXPECT_EQ(m[1].type, multitype::INT); - EXPECT_EQ(m[2].type, multitype::DOUBLE); + EXPECT_EQ(m[0].type, multitype::LAMMPS_INT64); + EXPECT_EQ(m[1].type, multitype::LAMMPS_INT); + EXPECT_EQ(m[2].type, multitype::LAMMPS_DOUBLE); #if defined(LAMMPS_SMALLSMALL) - EXPECT_EQ(m[3].type, multitype::INT); + EXPECT_EQ(m[3].type, multitype::LAMMPS_INT); #else - EXPECT_EQ(m[3].type, multitype::BIGINT); + EXPECT_EQ(m[3].type, multitype::LAMMPS_INT64); #endif - EXPECT_EQ(m[4].type, multitype::INT); - EXPECT_EQ(m[5].type, multitype::DOUBLE); - EXPECT_EQ(m[6].type, multitype::NONE); + EXPECT_EQ(m[4].type, multitype::LAMMPS_INT); + EXPECT_EQ(m[5].type, multitype::LAMMPS_DOUBLE); + EXPECT_EQ(m[6].type, multitype::LAMMPS_NONE); EXPECT_EQ(m[0].data.b, b1); EXPECT_EQ(m[1].data.i, i1); From 92e069b19deaf39ea79cadd36b5bce53c18e4988 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 10 Jun 2023 21:36:56 -0400 Subject: [PATCH 386/448] add fortran unit tests for lammps_last_thermo --- fortran/lammps.f90 | 8 +- unittest/fortran/test_fortran_get_thermo.f90 | 108 +++++++++++++++++++ unittest/fortran/wrap_get_thermo.cpp | 41 +++++++ 3 files changed, 154 insertions(+), 3 deletions(-) diff --git a/fortran/lammps.f90 b/fortran/lammps.f90 index 669e9c700d..ba3997ac8e 100644 --- a/fortran/lammps.f90 +++ b/fortran/lammps.f90 @@ -1127,11 +1127,13 @@ CONTAINS FUNCTION lmp_last_thermo(self,what,index) RESULT(thermo_data) CLASS(lammps), INTENT(IN), TARGET :: self CHARACTER(LEN=*), INTENT(IN) :: what - INTEGER(c_int) :: index + INTEGER :: index + INTEGER(c_int) :: idx TYPE(lammps_data) :: thermo_data, type_data INTEGER(c_int) :: datatype TYPE(c_ptr) :: Cname, Cptr + idx = index - 1 ! set data type for known cases SELECT CASE (what) CASE ('step') @@ -1148,7 +1150,7 @@ CONTAINS datatype = LAMMPS_STRING CASE ('data') Cname = f2c_string('type') - Cptr = lammps_last_thermo(self%handle,Cname,index-1) + Cptr = lammps_last_thermo(self%handle,Cname,idx) type_data%lammps_instance => self type_data%datatype = DATA_INT CALL C_F_POINTER(Cptr, type_data%i32) @@ -1159,7 +1161,7 @@ CONTAINS END SELECT Cname = f2c_string(what) - Cptr = lammps_last_thermo(self%handle,Cname,index-1) + Cptr = lammps_last_thermo(self%handle,Cname,idx) CALL lammps_free(Cname) thermo_data%lammps_instance => self diff --git a/unittest/fortran/test_fortran_get_thermo.f90 b/unittest/fortran/test_fortran_get_thermo.f90 index 7911ab07d5..965e6d58f7 100644 --- a/unittest/fortran/test_fortran_get_thermo.f90 +++ b/unittest/fortran/test_fortran_get_thermo.f90 @@ -152,3 +152,111 @@ FUNCTION f_lammps_get_thermo_zhi() BIND(C) f_lammps_get_thermo_zhi = lmp%get_thermo('zhi') END FUNCTION f_lammps_get_thermo_zhi + +SUBROUTINE f_lammps_last_thermo_setup() BIND(C) + USE liblammps + USE keepstuff, ONLY : lmp, big_input, cont_input, pair_input + IMPLICIT NONE + + CALL lmp%commands_list(big_input) + CALL lmp%commands_list(cont_input) + CALL lmp%commands_list(pair_input) + CALL lmp%command('thermo 10') + CALL lmp%command('run 15 post no') +END SUBROUTINE f_lammps_last_thermo_setup + +FUNCTION f_lammps_last_thermo_step() BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_int, c_int64_t + USE liblammps + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int) :: f_lammps_last_thermo_step + INTEGER :: size_bigint + INTEGER(c_int), POINTER :: ival + INTEGER(c_int64_t), POINTER :: bval + + size_bigint = lmp%extract_setting('bigint') + IF (size_bigint == 4) THEN + ival = lmp%last_thermo('step',1) + f_lammps_last_thermo_step = INT(ival) + ELSE + bval = lmp%last_thermo('step',1) + f_lammps_last_thermo_step = INT(bval) + END IF +END FUNCTION f_lammps_last_thermo_step + +FUNCTION f_lammps_last_thermo_num() BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_int + USE liblammps + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int) :: f_lammps_last_thermo_num + INTEGER(c_int), POINTER :: ival + + ival = lmp%last_thermo('num',1) + f_lammps_last_thermo_num = ival +END FUNCTION f_lammps_last_thermo_num + +FUNCTION f_lammps_last_thermo_type(idx) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_int + USE liblammps + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int), VALUE :: idx + INTEGER(c_int) :: f_lammps_last_thermo_type + INTEGER(c_int), POINTER :: ival + + ival = lmp%last_thermo('type',idx) + f_lammps_last_thermo_type = ival +END FUNCTION f_lammps_last_thermo_type + +FUNCTION f_lammps_last_thermo_string(idx) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_int, c_ptr, c_null_ptr + USE liblammps + USE keepstuff, ONLY : lmp, f2c_string + IMPLICIT NONE + INTEGER(c_int), VALUE :: idx + TYPE(c_ptr) :: f_lammps_last_thermo_string + CHARACTER(LEN=12) :: buffer + + buffer = lmp%last_thermo('keyword',idx) + IF (LEN_TRIM(buffer) > 0) THEN + f_lammps_last_thermo_string = f2c_string(buffer) + ELSE + f_lammps_last_thermo_string = c_null_ptr + END IF +END FUNCTION f_lammps_last_thermo_string + +FUNCTION f_lammps_last_thermo_int(idx) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_int, c_int64_t + USE liblammps + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int), VALUE :: idx + INTEGER(c_int), POINTER :: ival + INTEGER(c_int64_t), POINTER :: bval + INTEGER(c_int) :: f_lammps_last_thermo_int + INTEGER :: size_bigint + + size_bigint = lmp%extract_setting('bigint') + IF (size_bigint == 4) THEN + ival = lmp%last_thermo('data',idx) + f_lammps_last_thermo_int = INT(ival) + ELSE + bval = lmp%last_thermo('data',idx) + f_lammps_last_thermo_int = INT(bval) + END IF +END FUNCTION f_lammps_last_thermo_int + +FUNCTION f_lammps_last_thermo_double(idx) BIND(C) + USE, INTRINSIC :: ISO_C_BINDING, ONLY: c_int, c_double + USE liblammps + USE keepstuff, ONLY : lmp + IMPLICIT NONE + INTEGER(c_int), VALUE :: idx + REAL(c_double), POINTER :: dval + REAL(c_double) :: f_lammps_last_thermo_double + + dval = lmp%last_thermo('data',idx) + f_lammps_last_thermo_double = dval +END FUNCTION f_lammps_last_thermo_double diff --git a/unittest/fortran/wrap_get_thermo.cpp b/unittest/fortran/wrap_get_thermo.cpp index 71b51609eb..e18697ba9b 100644 --- a/unittest/fortran/wrap_get_thermo.cpp +++ b/unittest/fortran/wrap_get_thermo.cpp @@ -1,6 +1,7 @@ // unit tests for getting thermodynamic output from a LAMMPS instance through the Fortran wrapper #include "lammps.h" +#include "lmptype.h" #include #include @@ -23,8 +24,18 @@ double f_lammps_get_thermo_ylo(); double f_lammps_get_thermo_yhi(); double f_lammps_get_thermo_zlo(); double f_lammps_get_thermo_zhi(); + +void f_lammps_last_thermo_setup(); +int f_lammps_last_thermo_step(); +int f_lammps_last_thermo_num(); +int f_lammps_last_thermo_type(int); +const char *f_lammps_last_thermo_string(int); +int f_lammps_last_thermo_int(int); +double f_lammps_last_thermo_double(int); } +using LAMMPS_NS::multitype; + class LAMMPS_thermo : public ::testing::Test { protected: LAMMPS_NS::LAMMPS *lmp; @@ -65,3 +76,33 @@ TEST_F(LAMMPS_thermo, get_thermo) EXPECT_DOUBLE_EQ(f_lammps_get_thermo_zlo(), 0.0); EXPECT_DOUBLE_EQ(f_lammps_get_thermo_zhi(), 4.0); }; + +TEST_F(LAMMPS_thermo, last_thermo) +{ + EXPECT_EQ(f_lammps_last_thermo_step(), -1); + EXPECT_EQ(f_lammps_last_thermo_type(1), multitype::LAMMPS_NONE); + EXPECT_EQ(f_lammps_last_thermo_type(2), multitype::LAMMPS_NONE); + f_lammps_last_thermo_setup(); + EXPECT_EQ(f_lammps_last_thermo_step(), 15); + EXPECT_EQ(f_lammps_last_thermo_num(), 6); + EXPECT_STREQ(f_lammps_last_thermo_string(1), "Step"); + EXPECT_STREQ(f_lammps_last_thermo_string(2), "Temp"); + EXPECT_STREQ(f_lammps_last_thermo_string(3), "E_pair"); + EXPECT_STREQ(f_lammps_last_thermo_string(6), "Press"); +#if defined(LAMMPS_SMALLSMALL) + EXPECT_EQ(f_lammps_last_thermo_type(1), multitype::LAMMPS_INT); +#else + EXPECT_EQ(f_lammps_last_thermo_type(1), multitype::LAMMPS_INT64); +#endif + EXPECT_EQ(f_lammps_last_thermo_int(1), 15); + EXPECT_EQ(f_lammps_last_thermo_type(2), multitype::LAMMPS_DOUBLE); + EXPECT_EQ(f_lammps_last_thermo_type(3), multitype::LAMMPS_DOUBLE); + EXPECT_EQ(f_lammps_last_thermo_type(4), multitype::LAMMPS_DOUBLE); + EXPECT_EQ(f_lammps_last_thermo_type(5), multitype::LAMMPS_DOUBLE); + EXPECT_EQ(f_lammps_last_thermo_type(6), multitype::LAMMPS_DOUBLE); + EXPECT_DOUBLE_EQ(f_lammps_last_thermo_double(2), 0.0); + EXPECT_DOUBLE_EQ(f_lammps_last_thermo_double(3), -0.13713425198078993); + EXPECT_DOUBLE_EQ(f_lammps_last_thermo_double(4), 0.0); + EXPECT_DOUBLE_EQ(f_lammps_last_thermo_double(5), -0.13713425198078993); + EXPECT_DOUBLE_EQ(f_lammps_last_thermo_double(6), -0.022421073321023492); +}; From 23552d4b7a93f4a8a5982880173a076c4c15eb61 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Sun, 11 Jun 2023 17:59:16 -0400 Subject: [PATCH 387/448] refactor to carry around extra per-reaction values --- src/REACTION/fix_bond_react.cpp | 79 ++++++++++++++++++--------------- src/REACTION/fix_bond_react.h | 2 + 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 784c163f70..4d2d4a0680 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -131,6 +131,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : global_freq = 1; extvector = 0; rxnID = 0; + cuff = 1; maxnconstraints = 0; narrhenius = 0; status = PROCEED; @@ -388,7 +389,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (iarg+2 > narg) error->all(FLERR,"Illegal fix bond/react command: " "'rescale_charges' has too few arguments"); if (strcmp(arg[iarg+1],"no") == 0) rescale_charges_flag[rxn] = 0; //default - else if (strcmp(arg[iarg+1],"yes") == 0) rescale_charges_flag[rxn] = 1; + else if (strcmp(arg[iarg+1],"yes") == 0) { + rescale_charges_flag[rxn] = 1; + cuff = 2; // index shift for extra values carried around by mega_gloves + } else error->one(FLERR,"Bond/react: Illegal option for 'rescale_charges' keyword"); iarg += 2; } else if (strcmp(arg[iarg],"molecule") == 0) { @@ -1282,9 +1286,9 @@ void FixBondReact::superimpose_algorithm() memory->create(restore_pt,MAXGUESS,4,"bond/react:restore_pt"); memory->create(pioneers,max_natoms,"bond/react:pioneers"); memory->create(restore,max_natoms,MAXGUESS*4,"bond/react:restore"); - memory->create(my_mega_glove,max_natoms+1,allnattempt,"bond/react:local_mega_glove"); + memory->create(my_mega_glove,max_natoms+cuff,allnattempt,"bond/react:my_mega_glove"); - for (int i = 0; i < max_natoms+1; i++) + for (int i = 0; i < max_natoms+cuff; i++) for (int j = 0; j < allnattempt; j++) my_mega_glove[i][j] = 0; @@ -1338,7 +1342,7 @@ void FixBondReact::superimpose_algorithm() status = ACCEPT; my_mega_glove[0][my_num_mega] = rxnID; for (int i = 0; i < onemol->natoms; i++) { - my_mega_glove[i+1][my_num_mega] = glove[i][1]; + my_mega_glove[i+cuff][my_num_mega] = glove[i][1]; } my_num_mega++; } @@ -1386,7 +1390,7 @@ void FixBondReact::superimpose_algorithm() else { my_mega_glove[0][my_num_mega] = rxnID; for (int i = 0; i < onemol->natoms; i++) { - my_mega_glove[i+1][my_num_mega] = glove[i][1]; + my_mega_glove[i+cuff][my_num_mega] = glove[i][1]; } my_num_mega++; } @@ -1405,10 +1409,10 @@ void FixBondReact::superimpose_algorithm() global_megasize = 0; - memory->create(local_mega_glove,max_natoms+1,my_num_mega,"bond/react:local_mega_glove"); - memory->create(ghostly_mega_glove,max_natoms+1,my_num_mega,"bond/react:ghostly_mega_glove"); + memory->create(local_mega_glove,max_natoms+cuff,my_num_mega,"bond/react:local_mega_glove"); + memory->create(ghostly_mega_glove,max_natoms+cuff,my_num_mega,"bond/react:ghostly_mega_glove"); - for (int i = 0; i < max_natoms+1; i++) { + for (int i = 0; i < max_natoms+cuff; i++) { for (int j = 0; j < my_num_mega; j++) { local_mega_glove[i][j] = 0; ghostly_mega_glove[i][j] = 0; @@ -2674,17 +2678,17 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) } tagint **dedup_glove; - memory->create(dedup_glove,max_natoms+1,dedup_size,"bond/react:dedup_glove"); + memory->create(dedup_glove,max_natoms+cuff,dedup_size,"bond/react:dedup_glove"); if (dedup_mode == LOCAL) { for (int i = 0; i < dedup_size; i++) { - for (int j = 0; j < max_natoms+1; j++) { + for (int j = 0; j < max_natoms+cuff; j++) { dedup_glove[j][i] = my_mega_glove[j][i]; } } } else if (dedup_mode == GLOBAL) { for (int i = 0; i < dedup_size; i++) { - for (int j = 0; j < max_natoms+1; j++) { + for (int j = 0; j < max_natoms+cuff; j++) { dedup_glove[j][i] = global_mega_glove[j][i]; } } @@ -2700,16 +2704,16 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) // let's randomly mix up our reaction instances first // then we can feel okay about ignoring ones we've already deleted (or accepted) // based off std::shuffle - int *temp_rxn = new int[max_natoms+1]; + int *temp_rxn = new int[max_natoms+cuff]; for (int i = dedup_size-1; i > 0; --i) { //dedup_size // choose random entry to swap current one with int k = floor(random[0]->uniform()*(i+1)); // swap entries - for (int j = 0; j < max_natoms+1; j++) + for (int j = 0; j < max_natoms+cuff; j++) temp_rxn[j] = dedup_glove[j][i]; - for (int j = 0; j < max_natoms+1; j++) { + for (int j = 0; j < max_natoms+cuff; j++) { dedup_glove[j][i] = dedup_glove[j][k]; dedup_glove[j][k] = temp_rxn[j]; } @@ -2721,13 +2725,13 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) int myrxnid1 = dedup_glove[0][i]; onemol = atom->molecules[unreacted_mol[myrxnid1]]; for (int j = 0; j < onemol->natoms; j++) { - int check1 = dedup_glove[j+1][i]; + int check1 = dedup_glove[j+cuff][i]; for (int ii = i + 1; ii < dedup_size; ii++) { if (dedup_mask[ii] == 0) { int myrxnid2 = dedup_glove[0][ii]; twomol = atom->molecules[unreacted_mol[myrxnid2]]; for (int jj = 0; jj < twomol->natoms; jj++) { - int check2 = dedup_glove[jj+1][ii]; + int check2 = dedup_glove[jj+cuff][ii]; if (check2 == check1) { dedup_mask[ii] = 1; break; @@ -2745,7 +2749,7 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) int my_new_megasize = 0; for (int i = 0; i < my_num_mega; i++) { if (dedup_mask[i] == 0) { - for (int j = 0; j < max_natoms+1; j++) { + for (int j = 0; j < max_natoms+cuff; j++) { my_mega_glove[j][my_new_megasize] = dedup_glove[j][i]; } my_new_megasize++; @@ -2761,7 +2765,7 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) for (int i = 0; i < global_megasize; i++) { if (dedup_mask[i] == 0) { ghostly_rxn_count[dedup_glove[0][i]]++; - for (int j = 0; j < max_natoms + 1; j++) { + for (int j = 0; j < max_natoms + cuff; j++) { global_mega_glove[j][new_global_megasize] = dedup_glove[j][i]; } new_global_megasize++; @@ -2839,7 +2843,7 @@ void FixBondReact::glove_ghostcheck() ghostly = 1; } else { for (int j = 0; j < onemol->natoms; j++) { - int ilocal = atom->map(my_mega_glove[j+1][i]); + int ilocal = atom->map(my_mega_glove[j+cuff][i]); if (ilocal >= atom->nlocal || localsendlist[ilocal] == 1) { ghostly = 1; break; @@ -2852,15 +2856,13 @@ void FixBondReact::glove_ghostcheck() #endif if (ghostly == 1) { - ghostly_mega_glove[0][ghostly_num_mega] = rxnID; - for (int j = 0; j < onemol->natoms+1; j++) { + for (int j = 0; j < onemol->natoms+cuff; j++) { ghostly_mega_glove[j][ghostly_num_mega] = my_mega_glove[j][i]; } ghostly_num_mega++; } else { - local_mega_glove[0][local_num_mega] = rxnID; local_rxn_count[rxnID]++; - for (int j = 0; j < onemol->natoms+1; j++) { + for (int j = 0; j < onemol->natoms+cuff; j++) { local_mega_glove[j][local_num_mega] = my_mega_glove[j][i]; } local_num_mega++; @@ -2899,8 +2901,8 @@ void FixBondReact::ghost_glovecast() } MPI_Allgather(&start, 1, MPI_INT, allstarts, 1, MPI_INT, world); MPI_Datatype columnunsized, column; - int sizes[2] = {max_natoms+1, global_megasize}; - int subsizes[2] = {max_natoms+1, 1}; + int sizes[2] = {max_natoms+cuff, global_megasize}; + int subsizes[2] = {max_natoms+cuff, 1}; int starts[2] = {0,0}; MPI_Type_create_subarray (2, sizes, subsizes, starts, MPI_ORDER_C, MPI_LMP_TAGINT, &columnunsized); @@ -2908,14 +2910,14 @@ void FixBondReact::ghost_glovecast() MPI_Type_commit(&column); memory->destroy(global_mega_glove); - memory->create(global_mega_glove,max_natoms+1,global_megasize,"bond/react:global_mega_glove"); + memory->create(global_mega_glove,max_natoms+cuff,global_megasize,"bond/react:global_mega_glove"); - for (int i = 0; i < max_natoms+1; i++) + for (int i = 0; i < max_natoms+cuff; i++) for (int j = 0; j < global_megasize; j++) global_mega_glove[i][j] = 0; if (ghostly_num_mega > 0) { - for (int i = 0; i < max_natoms+1; i++) { + for (int i = 0; i < max_natoms+cuff; i++) { for (int j = 0; j < ghostly_num_mega; j++) { global_mega_glove[i][j+start] = ghostly_mega_glove[i][j]; } @@ -3006,6 +3008,7 @@ void FixBondReact::update_everything() int update_num_mega; tagint **update_mega_glove; + // for now, keeping rxnID in update_mega_glove, but not rest of cuff memory->create(update_mega_glove,max_natoms+1,MAX(local_num_mega,global_megasize),"bond/react:update_mega_glove"); for (int pass = 0; pass < 2; pass++) { @@ -3030,8 +3033,9 @@ void FixBondReact::update_everything() } } - for (int j = 0; j < max_natoms+1; j++) - update_mega_glove[j][update_num_mega] = local_mega_glove[j][i]; + update_mega_glove[0][update_num_mega] = local_mega_glove[0][i]; + for (int j = 0; j < max_natoms; j++) + update_mega_glove[j+1][update_num_mega] = local_mega_glove[j+cuff][i]; update_num_mega++; } } else if (pass == 1) { @@ -3054,8 +3058,9 @@ void FixBondReact::update_everything() } } - for (int j = 0; j < max_natoms+1; j++) - update_mega_glove[j][update_num_mega] = global_mega_glove[j][i]; + update_mega_glove[0][update_num_mega] = global_mega_glove[0][i]; + for (int j = 0; j < max_natoms; j++) + update_mega_glove[j+1][update_num_mega] = global_mega_glove[j+cuff][i]; update_num_mega++; } } @@ -3692,7 +3697,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) n2superpose++; } - int ifit = atom->map(my_mega_glove[ibonding[rxnID]+1][iupdate]); // use this local ID to find fitting proc + int ifit = atom->map(my_mega_glove[ibonding[rxnID]+cuff][iupdate]); // use this local ID to find fitting proc Superpose3D superposer(n2superpose); int fitroot = 0; if (ifit >= 0 && ifit < atom->nlocal) { @@ -3713,12 +3718,12 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) if (!twomol->fragmentmask[modify_create_fragid[rxnID]][j]) continue; int ipre = equivalences[j][1][rxnID]-1; // equiv pre-reaction template index if (!create_atoms[j][rxnID] && !delete_atoms[ipre][rxnID]) { - if (atom->map(my_mega_glove[ipre+1][iupdate]) < 0) { + if (atom->map(my_mega_glove[ipre+cuff][iupdate]) < 0) { error->warning(FLERR," eligible atoms skipped for created-atoms fit on rank {}\n", comm->me); continue; } - iatom = atom->map(my_mega_glove[ipre+1][iupdate]); + iatom = atom->map(my_mega_glove[ipre+cuff][iupdate]); if (iref == -1) iref = iatom; iatom = domain->closest_image(iref,iatom); for (int k = 0; k < 3; k++) { @@ -3838,7 +3843,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) atom->tag[n] = maxtag_all + add_count; // locally update mega_glove - my_mega_glove[preID][iupdate] = atom->tag[n]; + my_mega_glove[preID+cuff-1][iupdate] = atom->tag[n]; if (atom->molecule_flag) { if (twomol->moleculeflag) { @@ -3866,7 +3871,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) } // globally update mega_glove and equivalences MPI_Allreduce(MPI_IN_PLACE,&root,1,MPI_INT,MPI_SUM,world); - MPI_Bcast(&my_mega_glove[preID][iupdate],1,MPI_LMP_TAGINT,root,world); + MPI_Bcast(&my_mega_glove[preID+cuff-1][iupdate],1,MPI_LMP_TAGINT,root,world); equivalences[m][0][rxnID] = m+1; equivalences[m][1][rxnID] = preID; reverse_equiv[preID-1][0][rxnID] = preID; diff --git a/src/REACTION/fix_bond_react.h b/src/REACTION/fix_bond_react.h index 66a5e4d6a0..5e7ffb733a 100644 --- a/src/REACTION/fix_bond_react.h +++ b/src/REACTION/fix_bond_react.h @@ -156,6 +156,8 @@ class FixBondReact : public Fix { int lcl_inst; // reaction instance tagint **glove; // 1st colmn: pre-reacted template, 2nd colmn: global IDs // for all mega_gloves: first row is the ID of bond/react + // 'cuff' leaves room for additional values carried around + int cuff; // default = 1, w/ rescale_charges_flag = 2 tagint **my_mega_glove; // local + ghostly reaction instances tagint **local_mega_glove; // consolidation of local reaction instances tagint **ghostly_mega_glove; // consolidation of nonlocal reaction instances From c214f654b6c5206fa40e7fcd96cf623c31ebfb00 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Sun, 11 Jun 2023 19:27:58 -0400 Subject: [PATCH 388/448] update communicated rxn instances to doubles --- src/REACTION/fix_bond_react.cpp | 60 ++++++++++++++++++--------------- src/REACTION/fix_bond_react.h | 8 ++--- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 4d2d4a0680..5a2f274d91 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -1340,9 +1340,9 @@ void FixBondReact::superimpose_algorithm() status = REJECT; } else { status = ACCEPT; - my_mega_glove[0][my_num_mega] = rxnID; + my_mega_glove[0][my_num_mega] = (double) rxnID; for (int i = 0; i < onemol->natoms; i++) { - my_mega_glove[i+cuff][my_num_mega] = glove[i][1]; + my_mega_glove[i+cuff][my_num_mega] = (double) glove[i][1]; } my_num_mega++; } @@ -1388,9 +1388,9 @@ void FixBondReact::superimpose_algorithm() if (fraction[rxnID] < 1.0 && random[rxnID]->uniform() >= fraction[rxnID]) status = REJECT; else { - my_mega_glove[0][my_num_mega] = rxnID; + my_mega_glove[0][my_num_mega] = (double) rxnID; for (int i = 0; i < onemol->natoms; i++) { - my_mega_glove[i+cuff][my_num_mega] = glove[i][1]; + my_mega_glove[i+cuff][my_num_mega] = (double) glove[i][1]; } my_num_mega++; } @@ -2677,7 +2677,7 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) dedup_size = global_megasize; } - tagint **dedup_glove; + double **dedup_glove; memory->create(dedup_glove,max_natoms+cuff,dedup_size,"bond/react:dedup_glove"); if (dedup_mode == LOCAL) { @@ -2704,7 +2704,7 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) // let's randomly mix up our reaction instances first // then we can feel okay about ignoring ones we've already deleted (or accepted) // based off std::shuffle - int *temp_rxn = new int[max_natoms+cuff]; + double *temp_rxn = new double[max_natoms+cuff]; for (int i = dedup_size-1; i > 0; --i) { //dedup_size // choose random entry to swap current one with int k = floor(random[0]->uniform()*(i+1)); @@ -2764,7 +2764,7 @@ void FixBondReact::dedup_mega_gloves(int dedup_mode) int new_global_megasize = 0; for (int i = 0; i < global_megasize; i++) { if (dedup_mask[i] == 0) { - ghostly_rxn_count[dedup_glove[0][i]]++; + ghostly_rxn_count[(int) dedup_glove[0][i]]++; for (int j = 0; j < max_natoms + cuff; j++) { global_mega_glove[j][new_global_megasize] = dedup_glove[j][i]; } @@ -2834,7 +2834,7 @@ void FixBondReact::glove_ghostcheck() local_rxn_count[i] = 0; for (int i = 0; i < my_num_mega; i++) { - rxnID = my_mega_glove[0][i]; + rxnID = (int) my_mega_glove[0][i]; onemol = atom->molecules[unreacted_mol[rxnID]]; int ghostly = 0; #if !defined(MPI_STUBS) @@ -2843,7 +2843,7 @@ void FixBondReact::glove_ghostcheck() ghostly = 1; } else { for (int j = 0; j < onemol->natoms; j++) { - int ilocal = atom->map(my_mega_glove[j+cuff][i]); + int ilocal = atom->map((tagint) my_mega_glove[j+cuff][i]); if (ilocal >= atom->nlocal || localsendlist[ilocal] == 1) { ghostly = 1; break; @@ -2905,8 +2905,8 @@ void FixBondReact::ghost_glovecast() int subsizes[2] = {max_natoms+cuff, 1}; int starts[2] = {0,0}; MPI_Type_create_subarray (2, sizes, subsizes, starts, MPI_ORDER_C, - MPI_LMP_TAGINT, &columnunsized); - MPI_Type_create_resized (columnunsized, 0, sizeof(tagint), &column); + MPI_DOUBLE, &columnunsized); + MPI_Type_create_resized (columnunsized, 0, sizeof(double), &column); MPI_Type_commit(&column); memory->destroy(global_mega_glove); @@ -3017,15 +3017,20 @@ void FixBondReact::update_everything() for (int i = 0; i < nreacts; i++) iskip[i] = 0; if (pass == 0) { for (int i = 0; i < local_num_mega; i++) { - rxnID = local_mega_glove[0][i]; + rxnID = (int) local_mega_glove[0][i]; // reactions already shuffled from dedup procedure, so can skip first N if (iskip[rxnID]++ < nlocalskips[rxnID]) continue; + // this will be overwritten if reaction skipped by create_atoms below + update_mega_glove[0][update_num_mega] = (tagint) local_mega_glove[0][i]; + for (int j = 0; j < max_natoms; j++) + update_mega_glove[j+1][update_num_mega] = (tagint) local_mega_glove[j+cuff][i]; + // atoms inserted here for serial MPI_STUBS build only if (create_atoms_flag[rxnID] == 1) { onemol = atom->molecules[unreacted_mol[rxnID]]; twomol = atom->molecules[reacted_mol[rxnID]]; - if (insert_atoms(local_mega_glove,i)) { + if (insert_atoms(update_mega_glove,update_num_mega)) { inserted_atoms_flag = 1; } else { // create aborted reaction_count_total[rxnID]--; @@ -3033,24 +3038,26 @@ void FixBondReact::update_everything() } } - update_mega_glove[0][update_num_mega] = local_mega_glove[0][i]; - for (int j = 0; j < max_natoms; j++) - update_mega_glove[j+1][update_num_mega] = local_mega_glove[j+cuff][i]; update_num_mega++; } } else if (pass == 1) { for (int i = 0; i < global_megasize; i++) { - rxnID = global_mega_glove[0][i]; + rxnID = (int) global_mega_glove[0][i]; // reactions already shuffled from dedup procedure, so can skip first N if (iskip[rxnID]++ < nghostlyskips[rxnID]) continue; + // this will be overwritten if reaction skipped by create_atoms below + update_mega_glove[0][update_num_mega] = (tagint) global_mega_glove[0][i]; + for (int j = 0; j < max_natoms; j++) + update_mega_glove[j+1][update_num_mega] = (tagint) global_mega_glove[j+cuff][i]; + // we can insert atoms here, now that reactions are finalized // can't do it any earlier, due to skipped reactions (max_rxn) // for MPI build, reactions that create atoms are always treated as 'global' if (create_atoms_flag[rxnID] == 1) { onemol = atom->molecules[unreacted_mol[rxnID]]; twomol = atom->molecules[reacted_mol[rxnID]]; - if (insert_atoms(global_mega_glove,i)) { + if (insert_atoms(update_mega_glove,update_num_mega)) { inserted_atoms_flag = 1; } else { // create aborted reaction_count_total[rxnID]--; @@ -3058,9 +3065,6 @@ void FixBondReact::update_everything() } } - update_mega_glove[0][update_num_mega] = global_mega_glove[0][i]; - for (int j = 0; j < max_natoms; j++) - update_mega_glove[j+1][update_num_mega] = global_mega_glove[j+cuff][i]; update_num_mega++; } } @@ -3648,7 +3652,7 @@ void FixBondReact::update_everything() insert created atoms ------------------------------------------------------------------------- */ -int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) +int FixBondReact::insert_atoms(tagint **my_update_mega_glove, int iupdate) { // inserting atoms based off fix_deposit->pre_exchange int flag; @@ -3697,14 +3701,14 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) n2superpose++; } - int ifit = atom->map(my_mega_glove[ibonding[rxnID]+cuff][iupdate]); // use this local ID to find fitting proc + int ifit = atom->map(my_update_mega_glove[ibonding[rxnID]+1][iupdate]); // use this local ID to find fitting proc Superpose3D superposer(n2superpose); int fitroot = 0; if (ifit >= 0 && ifit < atom->nlocal) { fitroot = comm->me; // get 'temperatere' averaged over site, used for created atoms' vels - t = get_temperature(my_mega_glove,1,iupdate); + t = get_temperature(my_update_mega_glove,1,iupdate); double **xfrozen; // coordinates for the "frozen" target molecule double **xmobile; // coordinates for the "mobile" molecule @@ -3718,12 +3722,12 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) if (!twomol->fragmentmask[modify_create_fragid[rxnID]][j]) continue; int ipre = equivalences[j][1][rxnID]-1; // equiv pre-reaction template index if (!create_atoms[j][rxnID] && !delete_atoms[ipre][rxnID]) { - if (atom->map(my_mega_glove[ipre+cuff][iupdate]) < 0) { + if (atom->map(my_update_mega_glove[ipre+1][iupdate]) < 0) { error->warning(FLERR," eligible atoms skipped for created-atoms fit on rank {}\n", comm->me); continue; } - iatom = atom->map(my_mega_glove[ipre+cuff][iupdate]); + iatom = atom->map(my_update_mega_glove[ipre+1][iupdate]); if (iref == -1) iref = iatom; iatom = domain->closest_image(iref,iatom); for (int k = 0; k < 3; k++) { @@ -3843,7 +3847,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) atom->tag[n] = maxtag_all + add_count; // locally update mega_glove - my_mega_glove[preID+cuff-1][iupdate] = atom->tag[n]; + my_update_mega_glove[preID][iupdate] = atom->tag[n]; if (atom->molecule_flag) { if (twomol->moleculeflag) { @@ -3871,7 +3875,7 @@ int FixBondReact::insert_atoms(tagint **my_mega_glove, int iupdate) } // globally update mega_glove and equivalences MPI_Allreduce(MPI_IN_PLACE,&root,1,MPI_INT,MPI_SUM,world); - MPI_Bcast(&my_mega_glove[preID+cuff-1][iupdate],1,MPI_LMP_TAGINT,root,world); + MPI_Bcast(&my_update_mega_glove[preID][iupdate],1,MPI_LMP_TAGINT,root,world); equivalences[m][0][rxnID] = m+1; equivalences[m][1][rxnID] = preID; reverse_equiv[preID-1][0][rxnID] = preID; diff --git a/src/REACTION/fix_bond_react.h b/src/REACTION/fix_bond_react.h index 5e7ffb733a..a028e4b5dc 100644 --- a/src/REACTION/fix_bond_react.h +++ b/src/REACTION/fix_bond_react.h @@ -158,10 +158,10 @@ class FixBondReact : public Fix { // for all mega_gloves: first row is the ID of bond/react // 'cuff' leaves room for additional values carried around int cuff; // default = 1, w/ rescale_charges_flag = 2 - tagint **my_mega_glove; // local + ghostly reaction instances - tagint **local_mega_glove; // consolidation of local reaction instances - tagint **ghostly_mega_glove; // consolidation of nonlocal reaction instances - tagint **global_mega_glove; // consolidation (inter-processor) of gloves + double **my_mega_glove; // local + ghostly reaction instances + double **local_mega_glove; // consolidation of local reaction instances + double **ghostly_mega_glove; // consolidation of nonlocal reaction instances + double **global_mega_glove; // consolidation (inter-processor) of gloves // containing nonlocal atoms int *localsendlist; // indicates ghosts of other procs From 68a73f1c339188beb831d62f9bd20712ea37e29b Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sun, 11 Jun 2023 17:46:58 -0600 Subject: [PATCH 389/448] library: return atom and force styles via extract_global --- src/library.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/library.cpp b/src/library.cpp index a94e385148..4022a6ba7b 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -1340,6 +1340,13 @@ int lammps_extract_global_datatype(void * /*handle*/, const char *name) if (strcmp(name,"q_flag") == 0) return LAMMPS_INT; if (strcmp(name,"units") == 0) return LAMMPS_STRING; + if (strcmp(name,"atom_style") == 0) return LAMMPS_STRING; + if (strcmp(name,"pair_style") == 0) return LAMMPS_STRING; + if (strcmp(name,"bond_style") == 0) return LAMMPS_STRING; + if (strcmp(name,"angle_style") == 0) return LAMMPS_STRING; + if (strcmp(name,"dihedral_style") == 0) return LAMMPS_STRING; + if (strcmp(name,"improper_style") == 0) return LAMMPS_STRING; + if (strcmp(name,"kspace_style") == 0) return LAMMPS_STRING; if (strcmp(name,"boltz") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"hplanck") == 0) return LAMMPS_DOUBLE; if (strcmp(name,"mvv2e") == 0) return LAMMPS_DOUBLE; @@ -1586,6 +1593,34 @@ report the "native" data type. The following tables are provided: - int - 1 - **deprecated**. Use :cpp:func:`lammps_extract_setting` instead. + * - atom_style + - char \* + - 1 + - string with the current atom style. + * - pair_style + - char \* + - 1 + - string with the current pair style. + * - bond_style + - char \* + - 1 + - string with the current bond style. + * - angle_style + - char \* + - 1 + - string with the current angle style. + * - dihedral_style + - char \* + - 1 + - string with the current dihedral style. + * - improper_style + - char \* + - 1 + - string with the current improper style. + * - kspace_style + - char \* + - 1 + - string with the current KSpace style. .. _extract_unit_settings: @@ -1692,6 +1727,13 @@ void *lammps_extract_global(void *handle, const char *name) auto lmp = (LAMMPS *) handle; if (strcmp(name,"units") == 0) return (void *) lmp->update->unit_style; + if (strcmp(name,"atom_style") == 0) return (void *) lmp->atom->atom_style; + if (strcmp(name,"pair_style") == 0) return (void *) lmp->force->pair_style; + if (strcmp(name,"bond_style") == 0) return (void *) lmp->force->bond_style; + if (strcmp(name,"angle_style") == 0) return (void *) lmp->force->angle_style; + if (strcmp(name,"dihedral_style") == 0) return (void *) lmp->force->dihedral_style; + if (strcmp(name,"improper_style") == 0) return (void *) lmp->force->improper_style; + if (strcmp(name,"kspace_style") == 0) return (void *) lmp->force->kspace_style; if (strcmp(name,"dt") == 0) return (void *) &lmp->update->dt; if (strcmp(name,"ntimestep") == 0) return (void *) &lmp->update->ntimestep; // update->atime can be referenced as a pointer From 82cea7a546aadd72079a74b87e8807f21df06731 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Jun 2023 15:31:03 -0400 Subject: [PATCH 390/448] small doc updates for added pppm_table keyword --- doc/src/package.rst | 81 +++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/doc/src/package.rst b/doc/src/package.rst index ce45a1eb79..1988e78245 100644 --- a/doc/src/package.rst +++ b/doc/src/package.rst @@ -49,7 +49,7 @@ Syntax *intel* args = NPhi keyword value ... Nphi = # of co-processors per node zero or more keyword/value pairs may be appended - keywords = *mode* or *omp* or *lrt* or *balance* or *ghost* or *tpc* or *tptask* or *no_affinity* + keywords = *mode* or *omp* or *lrt* or *balance* or *ghost* or *tpc* or *tptask* or *pppm_table* or *no_affinity* *mode* value = *single* or *mixed* or *double* single = perform force calculations in single precision mixed = perform force calculations in mixed precision @@ -395,13 +395,13 @@ is identical to the default *verlet* style aside from supporting the LRT feature. This feature requires setting the pre-processor flag -DLMP_INTEL_USELRT in the makefile when compiling LAMMPS. -The *balance* keyword sets the fraction of :doc:`pair style ` work offloaded to the co-processor for split -values between 0.0 and 1.0 inclusive. While this fraction of work is -running on the co-processor, other calculations will run on the host, -including neighbor and pair calculations that are not offloaded, as -well as angle, bond, dihedral, kspace, and some MPI communications. -If *split* is set to -1, the fraction of work is dynamically adjusted -automatically throughout the run. This typically give performance +The *balance* keyword sets the fraction of :doc:`pair style ` work +offloaded to the co-processor for split values between 0.0 and 1.0 inclusive. +While this fraction of work is running on the co-processor, other calculations +will run on the host, including neighbor and pair calculations that are not +offloaded, as well as angle, bond, dihedral, kspace, and some MPI +communications. If *split* is set to -1, the fraction of work is dynamically +adjusted automatically throughout the run. This typically give performance within 5 to 10 percent of the optimal fixed fraction. The *ghost* keyword determines whether or not ghost atoms, i.e. atoms @@ -433,6 +433,11 @@ with 16 threads, for a total of 128. Note that the default settings for *tpc* and *tptask* are fine for most problems, regardless of how many MPI tasks you assign to a Phi. +The *pppm_table* keyword with the argument yes allows to use a +pre-computed table to efficiently spread the charge to the PPPM grid. +This feature is enabled by default but can be turned off using the +keyword with the argument *no*. + The *no_affinity* keyword will turn off automatic setting of core affinity for MPI tasks and OpenMP threads on the host when using offload to a co-processor. Affinity settings are used when possible @@ -702,39 +707,37 @@ Related commands Default """"""" -For the GPU package, the default is Ngpu = 0 and the option defaults -are neigh = yes, newton = off, binsize = 0.0, split = 1.0, gpuID = 0 -to Ngpu-1, tpa = 1, omp = 0, and platform=-1. These settings are made -automatically if the "-sf gpu" :doc:`command-line switch ` -is used. If it is not used, you must invoke the package gpu command -in your input script or via the "-pk gpu" :doc:`command-line switch `. +For the GPU package, the default is Ngpu = 0 and the option defaults are neigh += yes, newton = off, binsize = 0.0, split = 1.0, gpuID = 0 to Ngpu-1, tpa = 1, +omp = 0, and platform=-1. These settings are made automatically if the "-sf +gpu" :doc:`command-line switch ` is used. If it is not used, you +must invoke the package gpu command in your input script or via the "-pk gpu" +:doc:`command-line switch `. -For the INTEL package, the default is Nphi = 1 and the option -defaults are omp = 0, mode = mixed, lrt = no, balance = -1, tpc = 4, -tptask = 240, pppm_table = yes. The default ghost option is determined -by the pair style being used. This value is output to the screen in -the offload report at the end of each run. Note that all of these -settings, except "omp" and "mode", are ignored if LAMMPS was not built -with Xeon Phi co-processor support. These settings are made -automatically if the "-sf intel" :doc:`command-line switch ` -is used. If it is not used, you must invoke the package intel command -in your input script or via the "-pk intel" :doc:`command-line switch `. +For the INTEL package, the default is Nphi = 1 and the option defaults are omp += 0, mode = mixed, lrt = no, balance = -1, tpc = 4, tptask = 240, pppm_table = +yes. The default ghost option is determined by the pair style being used. +This value is output to the screen in the offload report at the end of each +run. Note that all of these settings, except "omp" and "mode", are ignored if +LAMMPS was not built with Xeon Phi co-processor support. These settings are +made automatically if the "-sf intel" :doc:`command-line switch ` +is used. If it is not used, you must invoke the package intel command in your +input script or via the "-pk intel" :doc:`command-line switch `. For the KOKKOS package, the option defaults for GPUs are neigh = full, -neigh/qeq = full, newton = off, binsize for GPUs = 2x LAMMPS default -value, comm = device, sort = device, neigh/transpose = off, gpu/aware = -on. When LAMMPS can safely detect that GPU-aware MPI is not available, -the default value of gpu/aware becomes "off". For CPUs or Xeon Phis, the -option defaults are neigh = half, neigh/qeq = half, newton = on, binsize -= 0.0, comm = no, and sort = no. The option neigh/thread = on when -there are 16K atoms or less on an MPI rank, otherwise it is "off". These -settings are made automatically by the required "-k on" -:doc:`command-line switch `. You can change them by using -the package kokkos command in your input script or via the :doc:`-pk +neigh/qeq = full, newton = off, binsize for GPUs = 2x LAMMPS default value, +comm = device, sort = device, neigh/transpose = off, gpu/aware = on. When +LAMMPS can safely detect that GPU-aware MPI is not available, the default value +of gpu/aware becomes "off". For CPUs or Xeon Phis, the option defaults are +neigh = half, neigh/qeq = half, newton = on, binsize = 0.0, comm = no, and sort += no. The option neigh/thread = on when there are 16K atoms or less on an MPI +rank, otherwise it is "off". These settings are made automatically by the +required "-k on" :doc:`command-line switch `. You can change them +by using the package kokkos command in your input script or via the :doc:`-pk kokkos command-line switch `. -For the OMP package, the default is Nthreads = 0 and the option -defaults are neigh = yes. These settings are made automatically if -the "-sf omp" :doc:`command-line switch ` is used. If it -is not used, you must invoke the package omp command in your input -script or via the "-pk omp" :doc:`command-line switch `. +For the OMP package, the default is Nthreads = 0 and the option defaults are +neigh = yes. These settings are made automatically if the "-sf omp" +:doc:`command-line switch ` is used. If it is not used, you must +invoke the package omp command in your input script or via the "-pk omp" +:doc:`command-line switch `. From 2ba83a4d8f3ef0451b9de2bcd2a1360b1b21a76a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Jun 2023 15:31:37 -0400 Subject: [PATCH 391/448] add versionadded keyword --- doc/src/package.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/src/package.rst b/doc/src/package.rst index 1988e78245..b0549ba7d9 100644 --- a/doc/src/package.rst +++ b/doc/src/package.rst @@ -433,6 +433,8 @@ with 16 threads, for a total of 128. Note that the default settings for *tpc* and *tptask* are fine for most problems, regardless of how many MPI tasks you assign to a Phi. +.. versionadded:: TBD + The *pppm_table* keyword with the argument yes allows to use a pre-computed table to efficiently spread the charge to the PPPM grid. This feature is enabled by default but can be turned off using the From 603e397919bc9bd5d7898436411229896a9faf8c Mon Sep 17 00:00:00 2001 From: jrgissing Date: Mon, 12 Jun 2023 20:20:45 -0400 Subject: [PATCH 392/448] get_totalcharge routine --- src/REACTION/fix_bond_react.cpp | 49 +++++++++++++++++++++++++++------ src/REACTION/fix_bond_react.h | 2 ++ 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 5a2f274d91..8e4202cad0 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -251,8 +251,9 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : memory->create(ghostly_rxn_count,nreacts,"bond/react:ghostly_rxn_count"); memory->create(reaction_count_total,nreacts,"bond/react:reaction_count_total"); + rescale_charges_anyflag = 0; for (int i = 0; i < nreacts; i++) { - fraction[i] = 1; + fraction[i] = 1.0; seed[i] = 12345; max_rxn[i] = INT_MAX; for (int j = 0; j < 3; j++) @@ -262,7 +263,7 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : rescale_charges_flag[i] = 0; create_atoms_flag[i] = 0; modify_create_fragid[i] = -1; - overlapsq[i] = 0; + overlapsq[i] = 0.0; molecule_keyword[i] = OFF; nconstraints[i] = 0; // set default limit duration to 60 timesteps @@ -390,7 +391,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : "'rescale_charges' has too few arguments"); if (strcmp(arg[iarg+1],"no") == 0) rescale_charges_flag[rxn] = 0; //default else if (strcmp(arg[iarg+1],"yes") == 0) { + if (!atom->q_flag) error->all(FLERR,"Illegal fix bond/react command: " + "cannot use 'rescale_charges' without atomic charges enabled"); rescale_charges_flag[rxn] = 1; + rescale_charges_anyflag = 1; cuff = 2; // index shift for extra values carried around by mega_gloves } else error->one(FLERR,"Bond/react: Illegal option for 'rescale_charges' keyword"); @@ -1290,7 +1294,7 @@ void FixBondReact::superimpose_algorithm() for (int i = 0; i < max_natoms+cuff; i++) for (int j = 0; j < allnattempt; j++) - my_mega_glove[i][j] = 0; + my_mega_glove[i][j] = 0.0; attempted_rxn = 1; @@ -1341,6 +1345,7 @@ void FixBondReact::superimpose_algorithm() } else { status = ACCEPT; my_mega_glove[0][my_num_mega] = (double) rxnID; + if (rescale_charges_flag[rxnID]) my_mega_glove[1][my_num_mega] = get_totalcharge(); for (int i = 0; i < onemol->natoms; i++) { my_mega_glove[i+cuff][my_num_mega] = (double) glove[i][1]; } @@ -1389,6 +1394,7 @@ void FixBondReact::superimpose_algorithm() random[rxnID]->uniform() >= fraction[rxnID]) status = REJECT; else { my_mega_glove[0][my_num_mega] = (double) rxnID; + if (rescale_charges_flag[rxnID]) my_mega_glove[1][my_num_mega] = get_totalcharge(); for (int i = 0; i < onemol->natoms; i++) { my_mega_glove[i+cuff][my_num_mega] = (double) glove[i][1]; } @@ -1414,8 +1420,8 @@ void FixBondReact::superimpose_algorithm() for (int i = 0; i < max_natoms+cuff; i++) { for (int j = 0; j < my_num_mega; j++) { - local_mega_glove[i][j] = 0; - ghostly_mega_glove[i][j] = 0; + local_mega_glove[i][j] = 0.0; + ghostly_mega_glove[i][j] = 0.0; } } @@ -2190,6 +2196,24 @@ double FixBondReact::get_temperature(tagint **myglove, int row_offset, int col) return t; } +/* ---------------------------------------------------------------------- +compute sum of partial charges in rxn site, for updated atoms +note: currently uses global rxnID and onemol variables +------------------------------------------------------------------------- */ + +double FixBondReact::get_totalcharge() +{ + int j,jj,ilocal; + double *q = atom->q; + double sim_total_charge = 0.0; + for (j = 0; j < onemol->natoms; j++) { + jj = equivalences[j][1][rxnID]-1; + if (custom_charges[jj][rxnID] == 1) + sim_total_charge += q[atom->map(glove[jj][1])]; + } + return sim_total_charge; +} + /* ---------------------------------------------------------------------- get per-atom variable names used by custom constraint ------------------------------------------------------------------------- */ @@ -3008,8 +3032,12 @@ void FixBondReact::update_everything() int update_num_mega; tagint **update_mega_glove; - // for now, keeping rxnID in update_mega_glove, but not rest of cuff - memory->create(update_mega_glove,max_natoms+1,MAX(local_num_mega,global_megasize),"bond/react:update_mega_glove"); + // for now, keeping rxnID in update_mega_glove, but not rest of cuff in update_mega_glove + int maxmega = MAX(local_num_mega,global_megasize); + memory->create(update_mega_glove,max_natoms+1,maxmega,"bond/react:update_mega_glove"); + + double *sim_total_charges; + if (rescale_charges_anyflag) memory->create(sim_total_charges,maxmega,"bond/react:sim_total_charges"); for (int pass = 0; pass < 2; pass++) { update_num_mega = 0; @@ -3038,6 +3066,7 @@ void FixBondReact::update_everything() } } + if (rescale_charges_flag[rxnID]) sim_total_charges[update_num_mega] = local_mega_glove[1][i]; update_num_mega++; } } else if (pass == 1) { @@ -3065,6 +3094,7 @@ void FixBondReact::update_everything() } } + if (rescale_charges_flag[rxnID]) sim_total_charges[update_num_mega] = global_mega_glove[1][i]; update_num_mega++; } } @@ -3112,8 +3142,6 @@ void FixBondReact::update_everything() int jj = equivalences[j][1][rxnID]-1; if (atom->map(update_mega_glove[jj+1][i]) >= 0 && atom->map(update_mega_glove[jj+1][i]) < nlocal) { - if (landlocked_atoms[j][rxnID] == 1) - type[atom->map(update_mega_glove[jj+1][i])] = twomol->type[j]; if (twomol->qflag && atom->q_flag && custom_charges[jj][rxnID] == 1) { double *q = atom->q; sim_total_charge += q[atom->map(update_mega_glove[jj+1][i])]; @@ -3122,6 +3150,7 @@ void FixBondReact::update_everything() } } } + printf("check1 %g %g\n",sim_total_charge,sim_total_charges[i]); } charge_rescale_addend = (sim_total_charge-mol_total_charge)/n_custom_charge; } @@ -3564,6 +3593,7 @@ void FixBondReact::update_everything() } memory->destroy(update_mega_glove); + if (rescale_charges_anyflag) memory->destroy(sim_total_charges); // delete atoms. taken from fix_evaporate. but don't think it needs to be in pre_exchange // loop in reverse order to avoid copying marked atoms @@ -3708,6 +3738,7 @@ int FixBondReact::insert_atoms(tagint **my_update_mega_glove, int iupdate) fitroot = comm->me; // get 'temperatere' averaged over site, used for created atoms' vels + // note: row_offset for my_update_mega_glove is unity, not 'cuff' t = get_temperature(my_update_mega_glove,1,iupdate); double **xfrozen; // coordinates for the "frozen" target molecule diff --git a/src/REACTION/fix_bond_react.h b/src/REACTION/fix_bond_react.h index a028e4b5dc..d8c6c45494 100644 --- a/src/REACTION/fix_bond_react.h +++ b/src/REACTION/fix_bond_react.h @@ -72,6 +72,7 @@ class FixBondReact : public Fix { int *stabilize_steps_flag; int *custom_charges_fragid; int *rescale_charges_flag; + int rescale_charges_anyflag; int *create_atoms_flag; int *modify_create_fragid; double *overlapsq; @@ -193,6 +194,7 @@ class FixBondReact : public Fix { int check_constraints(); void get_IDcoords(int, int, double *); double get_temperature(tagint **, int, int); + double get_totalcharge(); void customvarnames(); // get per-atom variables names used by custom constraint void get_customvars(); // evaluate local values for variables names used by custom constraint double custom_constraint(const std::string &); // evaulate expression for custom constraint From 53f90fff3de67475dfb98b31162343e0577fc4b7 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Mon, 12 Jun 2023 21:28:51 -0400 Subject: [PATCH 393/448] final touch --- src/REACTION/fix_bond_react.cpp | 56 ++++++++++++++++----------------- src/REACTION/fix_bond_react.h | 5 +-- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 8e4202cad0..8315fde557 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -393,11 +393,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[iarg+1],"yes") == 0) { if (!atom->q_flag) error->all(FLERR,"Illegal fix bond/react command: " "cannot use 'rescale_charges' without atomic charges enabled"); - rescale_charges_flag[rxn] = 1; + rescale_charges_flag[rxn] = 1; // overloaded below to also indicate number of atoms to update rescale_charges_anyflag = 1; cuff = 2; // index shift for extra values carried around by mega_gloves - } - else error->one(FLERR,"Bond/react: Illegal option for 'rescale_charges' keyword"); + } else error->one(FLERR,"Bond/react: Illegal option for 'rescale_charges' keyword"); iarg += 2; } else if (strcmp(arg[iarg],"molecule") == 0) { if (iarg+2 > narg) error->all(FLERR,"Illegal fix bond/react command: " @@ -450,8 +449,10 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : memory->create(delete_atoms,max_natoms,nreacts,"bond/react:delete_atoms"); memory->create(create_atoms,max_natoms,nreacts,"bond/react:create_atoms"); memory->create(chiral_atoms,max_natoms,6,nreacts,"bond/react:chiral_atoms"); + memory->create(mol_total_charge,nreacts,"bond/react:mol_total_charge"); for (int j = 0; j < nreacts; j++) { + mol_total_charge[j] = 0.0; for (int i = 0; i < max_natoms; i++) { edge[i][j] = 0; custom_charges[i][j] = 1; // update all partial charges by default @@ -491,6 +492,21 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (custom_charges_fragid[i] >= 0) CustomCharges(custom_charges_fragid[i],i); } + // charge rescaling values must be calculated after calling CustomCharges + for (int myrxn = 0; myrxn < nreacts; myrxn++) { + if (rescale_charges_flag[myrxn]) { + rescale_charges_flag[myrxn] = 0; // will now store number of updated atoms + twomol = atom->molecules[reacted_mol[myrxn]]; + for (int j = 0; j < twomol->natoms; j++) { + int jj = equivalences[j][1][myrxn]-1; + if (twomol->qflag && custom_charges[jj][myrxn] == 1) { + mol_total_charge[myrxn] += twomol->q[j]; + rescale_charges_flag[myrxn]++; + } + } + } + } + // get the names of per-atom variables needed by 'rxn' functions of custom constraint customvarnames(); @@ -613,6 +629,7 @@ FixBondReact::~FixBondReact() memory->destroy(delete_atoms); memory->destroy(create_atoms); memory->destroy(chiral_atoms); + memory->destroy(mol_total_charge); if (vvec != nullptr) memory->destroy(vvec); memory->destroy(rxn_name); @@ -3129,37 +3146,18 @@ void FixBondReact::update_everything() } } - // get charge rescale delta - double charge_rescale_addend = 0; - if (rescale_charges_flag[rxnID] == 1) { - double sim_total_charge = 0; - double mol_total_charge = 0; - int n_custom_charge = 0; - for (int i = 0; i < update_num_mega; i++) { - rxnID = update_mega_glove[0][i]; - twomol = atom->molecules[reacted_mol[rxnID]]; - for (int j = 0; j < twomol->natoms; j++) { - int jj = equivalences[j][1][rxnID]-1; - if (atom->map(update_mega_glove[jj+1][i]) >= 0 && - atom->map(update_mega_glove[jj+1][i]) < nlocal) { - if (twomol->qflag && atom->q_flag && custom_charges[jj][rxnID] == 1) { - double *q = atom->q; - sim_total_charge += q[atom->map(update_mega_glove[jj+1][i])]; - mol_total_charge += twomol->q[j]; - n_custom_charge++; - } - } - } - printf("check1 %g %g\n",sim_total_charge,sim_total_charges[i]); - } - charge_rescale_addend = (sim_total_charge-mol_total_charge)/n_custom_charge; - } - // update charges and types of landlocked atoms // also keep track of 'stabilization' groups here + int n_custom_charge; + double charge_rescale_addend; for (int i = 0; i < update_num_mega; i++) { + charge_rescale_addend = 0; rxnID = update_mega_glove[0][i]; twomol = atom->molecules[reacted_mol[rxnID]]; + if (rescale_charges_flag[rxnID]) { + n_custom_charge = rescale_charges_flag[rxnID]; + charge_rescale_addend = (sim_total_charges[i]-mol_total_charge[rxnID])/n_custom_charge; + } for (int j = 0; j < twomol->natoms; j++) { int jj = equivalences[j][1][rxnID]-1; int ilocal = atom->map(update_mega_glove[jj+1][i]); diff --git a/src/REACTION/fix_bond_react.h b/src/REACTION/fix_bond_react.h index d8c6c45494..534261e11d 100644 --- a/src/REACTION/fix_bond_react.h +++ b/src/REACTION/fix_bond_react.h @@ -71,8 +71,9 @@ class FixBondReact : public Fix { int **store_rxn_count; int *stabilize_steps_flag; int *custom_charges_fragid; - int *rescale_charges_flag; - int rescale_charges_anyflag; + int *rescale_charges_flag; // if nonzero, indicates number of atoms whose charges are updated + int rescale_charges_anyflag; // indicates if any reactions do charge rescaling + double *mol_total_charge; // sum of charges of post-reaction atoms whose charges are updated int *create_atoms_flag; int *modify_create_fragid; double *overlapsq; From 2f7c3bf959b8ebd11e9001b2e610f39acebbdc1b Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sun, 11 Jun 2023 18:02:11 -0600 Subject: [PATCH 394/448] pylammps: reduce dependency to info command output --- python/lammps/pylammps.py | 85 ++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index 72cfed53f0..d3c65f783c 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -707,66 +707,55 @@ class PyLammps(object): def _parse_info_system(self, output): system = {} + system['dimensions'] = self.lmp.extract_setting("dimension") + system['xlo'] = self.lmp.extract_global("boxxlo") + system['ylo'] = self.lmp.extract_global("boxylo") + system['zlo'] = self.lmp.extract_global("boxzlo") + system['xhi'] = self.lmp.extract_global("boxxhi") + system['yhi'] = self.lmp.extract_global("boxyhi") + system['zhi'] = self.lmp.extract_global("boxzhi") + xprd = system["xhi"] - system["xlo"] + yprd = system["yhi"] - system["ylo"] + zprd = system["zhi"] - system["zlo"] + if self.lmp.extract_setting("triclinic") == 1: + system['triclinic_box'] = (xprd, yprd, zprd) + else: + system['orthogonal_box'] = (xprd, yprd, zprd) + system['nangles'] = self.lmp.extract_global("nbonds") + system['nangletypes'] = self.lmp.extract_setting("nbondtypes") + system['angle_style'] = self.lmp.extract_global("angle_style") + system['nbonds'] = self.lmp.extract_global("nbonds") + system['nbondtypes'] = self.lmp.extract_setting("nbondtypes") + system['bond_style'] = self.lmp.extract_global("bond_style") + system['ndihedrals'] = self.lmp.extract_global("ndihedrals") + system['ndihedraltypes'] = self.lmp.extract_setting("ndihedraltypes") + system['dihedral_style'] = self.lmp.extract_global("dihedral_style") + system['nimpropers'] = self.lmp.extract_global("nimpropers") + system['nimpropertypes'] = self.lmp.extract_setting("nimpropertypes") + system['improper_style'] = self.lmp.extract_global("improper_style") + system['kspace_style'] = self.lmp.extract_global("kspace_style") + system['natoms'] = self.lmp.extract_global("natoms") + system['ntypes'] = self.lmp.extract_global("ntypes") + system['pair_style'] = self.lmp.extract_global("pair_style") + system['atom_style'] = self.lmp.extract_global("atom_style") + system['units'] = self.lmp.extract_global("units") for line in output: - if line.startswith("Units"): - system['units'] = self._get_pair(line)[1] - elif line.startswith("Atom style"): - system['atom_style'] = self._get_pair(line)[1] - elif line.startswith("Atom map"): + if line.startswith("Atom map"): system['atom_map'] = self._get_pair(line)[1] elif line.startswith("Atoms"): parts = self._split_values(line) - system['natoms'] = int(self._get_pair(parts[0])[1]) - system['ntypes'] = int(self._get_pair(parts[1])[1]) - system['style'] = self._get_pair(parts[2])[1] - elif line.startswith("Kspace style"): - system['kspace_style'] = self._get_pair(line)[1] - elif line.startswith("Dimensions"): - system['dimensions'] = int(self._get_pair(line)[1]) - elif line.startswith("Orthogonal box"): - system['orthogonal_box'] = [float(x) for x in self._get_pair(line)[1].split('x')] elif line.startswith("Boundaries"): system['boundaries'] = self._get_pair(line)[1] - elif line.startswith("xlo"): - keys, values = [self._split_values(x) for x in self._get_pair(line)] - for key, value in zip(keys, values): - system[key] = float(value) - elif line.startswith("ylo"): - keys, values = [self._split_values(x) for x in self._get_pair(line)] - for key, value in zip(keys, values): - system[key] = float(value) - elif line.startswith("zlo"): - keys, values = [self._split_values(x) for x in self._get_pair(line)] - for key, value in zip(keys, values): - system[key] = float(value) elif line.startswith("Molecule type"): system['molecule_type'] = self._get_pair(line)[1] - elif line.startswith("Bonds"): - parts = self._split_values(line) - system['nbonds'] = int(self._get_pair(parts[0])[1]) - system['nbondtypes'] = int(self._get_pair(parts[1])[1]) - system['bond_style'] = self._get_pair(parts[2])[1] - elif line.startswith("Angles"): - parts = self._split_values(line) - system['nangles'] = int(self._get_pair(parts[0])[1]) - system['nangletypes'] = int(self._get_pair(parts[1])[1]) - system['angle_style'] = self._get_pair(parts[2])[1] - elif line.startswith("Dihedrals"): - parts = self._split_values(line) - system['ndihedrals'] = int(self._get_pair(parts[0])[1]) - system['ndihedraltypes'] = int(self._get_pair(parts[1])[1]) - system['dihedral_style'] = self._get_pair(parts[2])[1] - elif line.startswith("Impropers"): - parts = self._split_values(line) - system['nimpropers'] = int(self._get_pair(parts[0])[1]) - system['nimpropertypes'] = int(self._get_pair(parts[1])[1]) - system['improper_style'] = self._get_pair(parts[2])[1] return system def _parse_info_communication(self, output): comm = {} + comm['nprocs'] = self.lmp.extract_setting("world_size") + comm['nthreads'] = self.lmp.extract_setting("nthreads") for line in output: if line.startswith("MPI library"): @@ -779,10 +768,6 @@ class PyLammps(object): comm['proc_grid'] = [int(x) for x in self._get_pair(line)[1].split('x')] elif line.startswith("Communicate velocities for ghost atoms"): comm['ghost_velocity'] = (self._get_pair(line)[1] == "yes") - elif line.startswith("Nprocs"): - parts = self._split_values(line) - comm['nprocs'] = int(self._get_pair(parts[0])[1]) - comm['nthreads'] = int(self._get_pair(parts[1])[1]) return comm def _parse_element_list(self, output): From d7ecf41ff6acba213e5c2c55725d873342739ad7 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sun, 11 Jun 2023 23:11:28 -0600 Subject: [PATCH 395/448] pylammps: use library API for variable access --- python/lammps/pylammps.py | 48 +++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 14 deletions(-) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index d3c65f783c..7acdff658a 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -28,6 +28,7 @@ import tempfile from collections import namedtuple from .core import lammps +from .constants import * # lgtm [py/polluting-import] # ------------------------------------------------------------------------- @@ -65,22 +66,43 @@ class OutputCapture(object): # ------------------------------------------------------------------------- class Variable(object): - def __init__(self, pylammps_instance, name, style, definition): + def __init__(self, pylammps_instance, name): self._pylmp = pylammps_instance self.name = name - self.style = style - self.definition = definition.split() + + @property + def style(self): + vartype = self._pylmp.lmp.lib.lammps_extract_variable_datatype(self._pylmp.lmp.lmp, self.name.encode()) + if vartype == LMP_VAR_EQUAL: + return "equal" + elif vartype == LMP_VAR_ATOM: + return "atom" + elif vartype == LMP_VAR_VECTOR: + return "vector" + elif vartype == LMP_VAR_STRING: + return "string" + return None @property def value(self): - if self.style == 'atom': - return list(self._pylmp.lmp.extract_variable(self.name, "all", 1)) + return self._pylmp.lmp.extract_variable(self.name) + + @value.setter + def value(self, newvalue): + style = self.style + if style == "equal" or style == "string": + self._pylmp.variable("{} {} {}".format(self.name, style, newvalue)) else: - value = self._pylmp.lmp_print('"${%s}"' % self.name).strip() - try: - return float(value) - except ValueError: - return value + raise Exception("Setter not implemented for {} style variables.".format(style)) + + def __str__(self): + value = self.value + if isinstance(value, str): + value = "\"{}\"".format(value) + return "Variable(name=\"{}\", value={})".format(self.name, value) + + def __repr__(self): + return self.__str__() # ------------------------------------------------------------------------- @@ -676,11 +698,9 @@ class PyLammps(object): :getter: Returns a dictionary of all variables that are defined in this LAMMPS instance :type: dict """ - output = self.lmp_info("variables") - output = output[output.index("Variable information:")+1:] variables = {} - for v in self._parse_element_list(output): - variables[v['name']] = Variable(self, v['name'], v['style'], v['def']) + for name in self.lmp.available_ids("variable"): + variables[name] = Variable(self, name) return variables def eval(self, expr): From 64508e08aac5d6c73c0511fab4903603cd6d8da0 Mon Sep 17 00:00:00 2001 From: Richard Berger Date: Sun, 11 Jun 2023 23:19:20 -0600 Subject: [PATCH 396/448] pylammps: use library API to return available groups --- python/lammps/pylammps.py | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index 7acdff658a..bdbed3e971 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -686,9 +686,7 @@ class PyLammps(object): :getter: Returns a list of atom groups that are currently active in this LAMMPS instance :type: list """ - output = self.lmp_info("groups") - output = output[output.index("Group information:")+1:] - return self._parse_groups(output) + return self.lmp.available_ids("group") @property def variables(self): @@ -802,16 +800,6 @@ class PyLammps(object): elements.append(element) return elements - def _parse_groups(self, output): - groups = [] - group_pattern = re.compile(r"(?P.+) \((?P.+)\)") - - for line in output: - m = group_pattern.match(line.split(':')[1].strip()) - group = {'name': m.group('name'), 'type': m.group('type')} - groups.append(group) - return groups - def lmp_print(self, s): """ needed for Python2 compatibility, since print is a reserved keyword """ return self.__getattr__("print")(s) From f128de7dd0ef6cdd83297399910b287a87ab909b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Tue, 13 Jun 2023 15:13:16 -0400 Subject: [PATCH 397/448] Bugfix from @ndtrung81 for indexing bug when tallying per-atom Coulomb energy --- lib/gpu/lal_answer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/gpu/lal_answer.cpp b/lib/gpu/lal_answer.cpp index 1911be8431..fc8e2cfe7a 100644 --- a/lib/gpu/lal_answer.cpp +++ b/lib/gpu/lal_answer.cpp @@ -260,10 +260,10 @@ double AnswerT::energy_virial(double *eatom, double **vatom, ecoul+=ecv; if (_ef_atom) { if (_ilist==nullptr) { - for (int i=0; i<_ev_stride; i++) - eatom[i]+=engv[i]; - for (int i=_ev_stride; i Date: Tue, 13 Jun 2023 14:24:12 -0500 Subject: [PATCH 398/448] Rescaled EPSILON with a length scale (rounded radii) for contact detection --- src/BODY/fix_wall_body_polygon.cpp | 2 +- src/BODY/fix_wall_body_polyhedron.cpp | 2 +- src/BODY/pair_body_rounded_polygon.cpp | 22 +++++++++++++------- src/BODY/pair_body_rounded_polyhedron.cpp | 25 +++++++++++++++++------ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/BODY/fix_wall_body_polygon.cpp b/src/BODY/fix_wall_body_polygon.cpp index 4d0517e527..6f0622cbf6 100644 --- a/src/BODY/fix_wall_body_polygon.cpp +++ b/src/BODY/fix_wall_body_polygon.cpp @@ -44,7 +44,7 @@ enum {FAR=0,XLO,XHI,YLO,YHI}; //#define _POLYGON_DEBUG #define DELTA 10000 -#define EPSILON 1e-2 +#define EPSILON 1e-2 // dimensionless threshold (dot products, end point checks, contact checks) #define BIG 1.0e20 #define MAX_CONTACTS 4 // maximum number of contacts for 2D models #define EFF_CONTACTS 2 // effective contacts for 2D models diff --git a/src/BODY/fix_wall_body_polyhedron.cpp b/src/BODY/fix_wall_body_polyhedron.cpp index 212830eb81..546ef1f0d4 100644 --- a/src/BODY/fix_wall_body_polyhedron.cpp +++ b/src/BODY/fix_wall_body_polyhedron.cpp @@ -42,7 +42,7 @@ enum {FAR=0,XLO,XHI,YLO,YHI,ZLO,ZHI}; //#define _POLYHEDRON_DEBUG #define DELTA 10000 -#define EPSILON 1e-2 +#define EPSILON 1e-3 // dimensionless threshold (dot products, end point checks) #define BIG 1.0e20 #define MAX_CONTACTS 4 // maximum number of contacts for 2D models #define EFF_CONTACTS 2 // effective contacts for 2D models diff --git a/src/BODY/pair_body_rounded_polygon.cpp b/src/BODY/pair_body_rounded_polygon.cpp index 0e83b63f99..24f38a6a0a 100644 --- a/src/BODY/pair_body_rounded_polygon.cpp +++ b/src/BODY/pair_body_rounded_polygon.cpp @@ -40,7 +40,7 @@ using namespace LAMMPS_NS; #define DELTA 10000 -#define EPSILON 1e-3 +#define EPSILON 1e-3 // dimensionless threshold (dot products, end point checks, contact checks) #define MAX_CONTACTS 4 // maximum number of contacts for 2D models #define EFF_CONTACTS 2 // effective contacts for 2D models @@ -624,7 +624,8 @@ void PairBodyRoundedPolygon::sphere_against_sphere(int i, int j, fy = dely*fpair/rij; fz = delz*fpair/rij; - if (R <= EPSILON) { // in contact + double rmin = MIN(rradi, rradj); + if (R <= EPSILON*rmin) { // in contact // relative translational velocity @@ -1019,6 +1020,7 @@ int PairBodyRoundedPolygon::compute_distance_to_vertex(int ibody, double xi1[3],xi2[3],u[3],v[3],uij[3]; double udotv, magv, magucostheta; double delx,dely,delz; + double rmin = MIN(rounded_radius, x0_rounded_radius); ifirst = dfirst[ibody]; iefirst = edfirst[ibody]; @@ -1105,17 +1107,17 @@ int PairBodyRoundedPolygon::compute_distance_to_vertex(int ibody, // x0 and xmi are on the different sides // t is the ratio to detect if x0 is closer to the vertices xi or xj - if (fabs(xi2[0] - xi1[0]) > EPSILON) + if (fabs(xi2[0] - xi1[0]) > EPSILON*rmin) t = (hi[0] - xi1[0]) / (xi2[0] - xi1[0]); - else if (fabs(xi2[1] - xi1[1]) > EPSILON) + else if (fabs(xi2[1] - xi1[1]) > EPSILON*rmin) t = (hi[1] - xi1[1]) / (xi2[1] - xi1[1]); - else if (fabs(xi2[2] - xi1[2]) > EPSILON) + else if (fabs(xi2[2] - xi1[2]) > EPSILON*rmin) t = (hi[2] - xi1[2]) / (xi2[2] - xi1[2]); double contact_dist = rounded_radius + x0_rounded_radius; if (t >= 0 && t <= 1) { mode = EDGE; - if (d < contact_dist + EPSILON) + if (d < contact_dist + EPSILON*rmin) contact = 1; } else { // t < 0 || t > 1: closer to either vertices of the edge @@ -1293,8 +1295,14 @@ double PairBodyRoundedPolygon::contact_separation(const Contact& c1, double x3 = c2.xv[0]; double y3 = c2.xv[1]; + int ibody = c1.ibody; + int jbody = c1.ibody; + double rradi = rounded_radius[ibody]; + double rradj = rounded_radius[jbody]; + double rmin = MIN(rradi, rradj); + double delta_a = 0.0; - if (fabs(x2 - x1) > EPSILON) { + if (fabs(x2 - x1) > EPSILON*rmin) { double A = (y2 - y1) / (x2 - x1); delta_a = fabs(y1 - A * x1 - y3 + A * x3) / sqrt(1 + A * A); } else { diff --git a/src/BODY/pair_body_rounded_polyhedron.cpp b/src/BODY/pair_body_rounded_polyhedron.cpp index 2c23199e33..d9a79abad0 100644 --- a/src/BODY/pair_body_rounded_polyhedron.cpp +++ b/src/BODY/pair_body_rounded_polyhedron.cpp @@ -44,7 +44,7 @@ using namespace LAMMPS_NS; using namespace MathConst; #define DELTA 10000 -#define EPSILON 1e-3 +#define EPSILON 1e-3 // dimensionless threshold (dot products, end point checks, contact checks) #define MAX_FACE_SIZE 4 // maximum number of vertices per face (same as BodyRoundedPolyhedron) #define MAX_CONTACTS 32 // for 3D models (including duplicated counts) @@ -1186,7 +1186,13 @@ int PairBodyRoundedPolyhedron::interaction_edge_to_edge(int ibody, // singularity case, ignore interactions - if (r < EPSILON) return interact; + double rmin = MIN(rounded_radius_i, rounded_radius_j); + if (r < EPSILON*rmin) { + #ifdef _POLYHEDRON_DEBUG + printf("ignore interaction: r = %0.16f\n", r); + #endif + return interact; + } // include the vertices for interactions @@ -1898,10 +1904,12 @@ void PairBodyRoundedPolyhedron::inside_polygon(int ibody, int face_index, { int i,n,ifirst,iffirst,npi1,npi2; - double xi1[3],xi2[3],u[3],v[3],costheta,anglesum1,anglesum2,magu,magv; + double xi1[3],xi2[3],u[3],v[3],costheta,anglesum1,anglesum2,magu,magv,rradi; ifirst = dfirst[ibody]; iffirst = facfirst[ibody]; + rradi = rounded_radius[ibody]; + double rradsq = rradi*rradi; anglesum1 = anglesum2 = 0;; for (i = 0; i < MAX_FACE_SIZE; i++) { npi1 = static_cast(face[iffirst+face_index][i]); @@ -1929,7 +1937,7 @@ void PairBodyRoundedPolyhedron::inside_polygon(int ibody, int face_index, // the point is at either vertices - if (magu * magv < EPSILON) inside1 = 1; + if (magu * magv < EPSILON*rradsq) inside1 = 1; else { costheta = MathExtra::dot3(u,v)/(magu*magv); anglesum1 += acos(costheta); @@ -1940,7 +1948,7 @@ void PairBodyRoundedPolyhedron::inside_polygon(int ibody, int face_index, MathExtra::sub3(xi2,q2,v); magu = MathExtra::len3(u); magv = MathExtra::len3(v); - if (magu * magv < EPSILON) inside2 = 1; + if (magu * magv < EPSILON*rradsq) inside2 = 1; else { costheta = MathExtra::dot3(u,v)/(magu*magv); anglesum2 += acos(costheta); @@ -2338,7 +2346,12 @@ void PairBodyRoundedPolyhedron::find_unique_contacts(Contact* contact_list, for (int j = i + 1; j < n; j++) { if (contact_list[i].unique == 0) continue; double d = contact_separation(contact_list[i], contact_list[j]); - if (d < EPSILON) contact_list[j].unique = 0; + int ibody = contact_list[i].ibody; + int jbody = contact_list[i].jbody; + double rradi = rounded_radius[ibody]; + double rradj = rounded_radius[jbody]; + double rmin = MIN(rradi, rradj); + if (d < EPSILON*rmin) contact_list[j].unique = 0; } } } From 14a27e98c9e9e2db7b1fc88ebe36a397a2825c05 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Tue, 13 Jun 2023 21:09:29 -0400 Subject: [PATCH 399/448] fix for when deleting atoms --- src/REACTION/fix_bond_react.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 8315fde557..7e5da4a3ca 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -497,11 +497,13 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (rescale_charges_flag[myrxn]) { rescale_charges_flag[myrxn] = 0; // will now store number of updated atoms twomol = atom->molecules[reacted_mol[myrxn]]; - for (int j = 0; j < twomol->natoms; j++) { - int jj = equivalences[j][1][myrxn]-1; - if (twomol->qflag && custom_charges[jj][myrxn] == 1) { - mol_total_charge[myrxn] += twomol->q[j]; - rescale_charges_flag[myrxn]++; + if (twomol->qflag) { + for (int j = 0; j < twomol->natoms; j++) { + int jj = equivalences[j][1][myrxn]-1; + if (custom_charges[jj][myrxn] == 1 && delete_atoms[jj][myrxn] == 0) { + mol_total_charge[myrxn] += twomol->q[j]; + rescale_charges_flag[myrxn]++; + } } } } From 03b25dcbaaab70ac46cec5e323dd577cf84470a2 Mon Sep 17 00:00:00 2001 From: jrgissing Date: Tue, 13 Jun 2023 21:25:58 -0400 Subject: [PATCH 400/448] update error checks --- src/REACTION/fix_bond_react.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/REACTION/fix_bond_react.cpp b/src/REACTION/fix_bond_react.cpp index 7e5da4a3ca..83442ecb25 100644 --- a/src/REACTION/fix_bond_react.cpp +++ b/src/REACTION/fix_bond_react.cpp @@ -391,8 +391,11 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : "'rescale_charges' has too few arguments"); if (strcmp(arg[iarg+1],"no") == 0) rescale_charges_flag[rxn] = 0; //default else if (strcmp(arg[iarg+1],"yes") == 0) { - if (!atom->q_flag) error->all(FLERR,"Illegal fix bond/react command: " - "cannot use 'rescale_charges' without atomic charges enabled"); + if (!atom->q_flag) error->all(FLERR,"Illegal fix bond/react command: cannot use " + "'rescale_charges' without atomic charges enabled"); + twomol = atom->molecules[reacted_mol[rxn]]; + if (!twomol->qflag) error->all(FLERR,"Illegal fix bond/react command: cannot use " + "'rescale_charges' without Charges section in post-reaction template"); rescale_charges_flag[rxn] = 1; // overloaded below to also indicate number of atoms to update rescale_charges_anyflag = 1; cuff = 2; // index shift for extra values carried around by mega_gloves @@ -497,13 +500,11 @@ FixBondReact::FixBondReact(LAMMPS *lmp, int narg, char **arg) : if (rescale_charges_flag[myrxn]) { rescale_charges_flag[myrxn] = 0; // will now store number of updated atoms twomol = atom->molecules[reacted_mol[myrxn]]; - if (twomol->qflag) { - for (int j = 0; j < twomol->natoms; j++) { - int jj = equivalences[j][1][myrxn]-1; - if (custom_charges[jj][myrxn] == 1 && delete_atoms[jj][myrxn] == 0) { - mol_total_charge[myrxn] += twomol->q[j]; - rescale_charges_flag[myrxn]++; - } + for (int j = 0; j < twomol->natoms; j++) { + int jj = equivalences[j][1][myrxn]-1; + if (custom_charges[jj][myrxn] == 1 && delete_atoms[jj][myrxn] == 0) { + mol_total_charge[myrxn] += twomol->q[j]; + rescale_charges_flag[myrxn]++; } } } From 8984b89feb469b35acec18757f21fc30c202cfcf Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 03:18:17 -0400 Subject: [PATCH 401/448] use consistent comments, apply clang-format --- src/REPLICA/fix_pimd_langevin.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.h b/src/REPLICA/fix_pimd_langevin.h index dc48832855..d3b9d5b77e 100644 --- a/src/REPLICA/fix_pimd_langevin.h +++ b/src/REPLICA/fix_pimd_langevin.h @@ -41,7 +41,7 @@ class FixPIMDLangevin : public Fix { double compute_vector(int) override; protected: - /* System setting variables */ + // System setting variables int method; // PIMD or NMPIMD or CMD int fmmode; // physical or normal int np; // number of beads @@ -51,7 +51,7 @@ class FixPIMDLangevin : public Fix { double lj_epsilon, lj_sigma, lj_mass; // LJ unit energy, length, and mass scales double other_planck; double other_mvv2e; - double kt; // k_B * temp + double kt; // k_B * temp double beta, beta_np; // beta = 1./kBT beta_np = 1./kBT/np int thermostat; // NHC or PILE_L int barostat; // BZP @@ -62,15 +62,16 @@ class FixPIMDLangevin : public Fix { double masstotal; double fixedpoint[3]; // location of dilation fixed-point - /* ring-polymer model */ + + // ring-polymer model double omega_np, fbond, spring_energy, sp; - /* fictitious mass */ + // fictitious mass double fmass, *mass; - /* inter-partition communication */ + // inter-partition communication MPI_Comm rootworld; int me, nprocs, ireplica, nreplica, nprocs_universe; @@ -117,7 +118,8 @@ class FixPIMDLangevin : public Fix { int tstat_flag; // tstat_flat = 1 if thermostat if used void langevin_init(); void b_step(); // integrate for dt/2 according to B part (v <- v + f * dt/2) - void a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) + void + a_step(); // integrate for dt/2 according to A part (non-centroid mode, harmonic force between replicas) void qc_step(); // integrate for dt/2 for the centroid mode (x <- x + v * dt/2) void o_step(); // integrate for dt according to O part (O-U process, for thermostating) From 6f69e5ae02a8cacead4f5b76d930d2d7a4d76593 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 03:18:37 -0400 Subject: [PATCH 402/448] initialized all pointers to null in initializer list --- src/REPLICA/fix_pimd_langevin.cpp | 39 ++++++++++++------------------- 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 0af08b43b3..e4e60520d1 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -64,31 +64,23 @@ enum { SINGLE_PROC, MULTI_PROC }; /* ---------------------------------------------------------------------- */ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : - Fix(lmp, narg, arg), random(nullptr), c_pe(nullptr), c_press(nullptr) + Fix(lmp, narg, arg), mass(nullptr), plansend(nullptr), planrecv(nullptr), tagsend(nullptr), + tagrecv(nullptr), bufsend(nullptr), bufrecv(nullptr), bufbeads(nullptr), bufsorted(nullptr), + bufsortedall(nullptr), outsorted(nullptr), buftransall(nullptr), bufsendall(nullptr), + bufrecvall(nullptr), tagsendall(nullptr), tagrecvall(nullptr), counts(nullptr), + displacements(nullptr), lam(nullptr), M_x2xp(nullptr), M_xp2x(nullptr), M_f2fp(nullptr), + M_fp2f(nullptr), modeindex(nullptr), tau_k(nullptr), c1_k(nullptr), c2_k(nullptr), + _omega_k(nullptr), Lan_s(nullptr), Lan_c(nullptr), , random(nullptr), xc(nullptr), + xcall(nullptr), x_unwrap(nullptr), id_pe(nullptr), id_press(nullptr), c_pe(nullptr), + c_press(nullptr) { restart_global = 1; time_integrate = 1; - tagsend = tagrecv = nullptr; - bufsend = bufrecv = nullptr; - bufsendall = bufrecvall = nullptr; - bufsorted = bufsortedall = nullptr; - outsorted = buftransall = nullptr; ntotal = 0; maxlocal = maxunwrap = maxxc = 0; - bufbeads = nullptr; - x_unwrap = xc = nullptr; - xcall = nullptr; - counts = nullptr; sizeplan = 0; - plansend = planrecv = nullptr; - - M_x2xp = M_xp2x = M_f2fp = M_fp2f = nullptr; - lam = nullptr; - modeindex = nullptr; - - mass = nullptr; method = NMPIMD; ensemble = NVT; @@ -97,6 +89,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : barostat = BZP; fmass = 1.0; np = universe->nworlds; + inverse_np = 1.0 / np; sp = 1.0; temp = 298.15; Lan_temp = 298.15; @@ -155,8 +148,8 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : pstat_flag = 1; } else error->universe_all(FLERR, - "Unknown ensemble parameter for fix pimd/langevin. Only nve, nvt, nph, and npt " - "ensembles are supported!"); + "Unknown ensemble parameter for fix pimd/langevin. Only nve, nvt, nph, " + "and npt ensembles are supported!"); } else if (strcmp(arg[i], "fmass") == 0) { fmass = utils::numeric(FLERR, arg[i + 1], false, lmp); if (fmass < 0.0 || fmass > np) @@ -170,10 +163,9 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[i + 1], "normal") == 0) fmmode = NORMAL; else - error->universe_all( - FLERR, - "Unknown fictitious mass mode for fix pimd/langevin. Only physical mass and " - "normal mode mass are supported!"); + error->universe_all(FLERR, + "Unknown fictitious mass mode for fix pimd/langevin. Only physical " + "mass and normal mode mass are supported!"); } else if (strcmp(arg[i], "scale") == 0) { pilescale = utils::numeric(FLERR, arg[i + 1], false, lmp); if (pilescale < 0.0) @@ -409,7 +401,6 @@ void FixPIMDLangevin::init() // prepare the constants masstotal = group->mass(igroup); - inverse_np = 1.0 / np; double planck; if (strcmp(update->unit_style, "lj") == 0) { From 494341ba48df6284d86df1000d1517e828a584df Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 03:39:52 -0400 Subject: [PATCH 403/448] error out when using barostat without pressure couple or vice versa --- src/REPLICA/fix_pimd_langevin.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index e4e60520d1..58b9ec6726 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -56,11 +56,12 @@ enum { BAOAB, OBABO }; enum { ISO, ANISO, TRICLINIC }; enum { PILE_L }; enum { MTTK, BZP }; - -static std::map Barostats{{MTTK, "MTTK"}, {BZP, "BZP"}}; enum { NVE, NVT, NPH, NPT }; enum { SINGLE_PROC, MULTI_PROC }; +static std::map Barostats{{MTTK, "MTTK"}, {BZP, "BZP"}}; +static std::map Ensembles{{NVE, "NVE"}, {NVT, "NVT"}, {NPH, "NPH"}, {NPT, "NPT"}}; + /* ---------------------------------------------------------------------- */ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : @@ -235,13 +236,20 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : } } + if (pstat_flag && !pdim) + error->universe_all( + FLERR, fmt::format("Must use pressure coupling with {} ensemble", Ensembles[ensemble])); + if (!pstat_flag && pdim) + error->universe_all( + FLERR, fmt::format("Must not use pressure coupling with {} ensemble", Ensembles[ensemble])); + /* Initiation */ global_freq = 1; vector_flag = 1; - if (!pstat_flag) + if (!pstat_flag) { size_vector = 10; - else if (pstat_flag) { + } else if (pstat_flag) { if (pstyle == ISO) { size_vector = 15; } else if (pstyle == ANISO) { @@ -250,7 +258,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : } extvector = 1; kt = force->boltz * temp; - if (pstat_flag) baro_init(); + if (pstat_flag) FixPIMDLangevin::baro_init(); // some initilizations From dfd384eeffa9e78df315a7b9a58070070a2754c0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 03:40:38 -0400 Subject: [PATCH 404/448] some more formatting and programming style improvements --- src/REPLICA/fix_pimd_langevin.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/src/REPLICA/fix_pimd_langevin.cpp b/src/REPLICA/fix_pimd_langevin.cpp index 58b9ec6726..75280fd3d5 100644 --- a/src/REPLICA/fix_pimd_langevin.cpp +++ b/src/REPLICA/fix_pimd_langevin.cpp @@ -67,13 +67,12 @@ static std::map Ensembles{{NVE, "NVE"}, {NVT, "NVT"}, {NPH, "N FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : Fix(lmp, narg, arg), mass(nullptr), plansend(nullptr), planrecv(nullptr), tagsend(nullptr), tagrecv(nullptr), bufsend(nullptr), bufrecv(nullptr), bufbeads(nullptr), bufsorted(nullptr), - bufsortedall(nullptr), outsorted(nullptr), buftransall(nullptr), bufsendall(nullptr), - bufrecvall(nullptr), tagsendall(nullptr), tagrecvall(nullptr), counts(nullptr), + bufsortedall(nullptr), outsorted(nullptr), buftransall(nullptr), tagsendall(nullptr), + tagrecvall(nullptr), bufsendall(nullptr), bufrecvall(nullptr), counts(nullptr), displacements(nullptr), lam(nullptr), M_x2xp(nullptr), M_xp2x(nullptr), M_f2fp(nullptr), M_fp2f(nullptr), modeindex(nullptr), tau_k(nullptr), c1_k(nullptr), c2_k(nullptr), - _omega_k(nullptr), Lan_s(nullptr), Lan_c(nullptr), , random(nullptr), xc(nullptr), - xcall(nullptr), x_unwrap(nullptr), id_pe(nullptr), id_press(nullptr), c_pe(nullptr), - c_press(nullptr) + _omega_k(nullptr), Lan_s(nullptr), Lan_c(nullptr), random(nullptr), xc(nullptr), xcall(nullptr), + x_unwrap(nullptr), id_pe(nullptr), id_press(nullptr), c_pe(nullptr), c_press(nullptr) { restart_global = 1; time_integrate = 1; @@ -126,10 +125,9 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : else if (strcmp(arg[i + 1], "baoab") == 0) integrator = BAOAB; else - error->universe_all( - FLERR, - "Unknown integrator parameter for fix pimd/langevin. Only obabo and baoab " - "integrators are supported!"); + error->universe_all(FLERR, + "Unknown integrator parameter for fix pimd/langevin. Only obabo and " + "baoab integrators are supported!"); } else if (strcmp(arg[i], "ensemble") == 0) { if (strcmp(arg[i + 1], "nve") == 0) { ensemble = NVE; @@ -273,7 +271,7 @@ FixPIMDLangevin::FixPIMDLangevin(LAMMPS *lmp, int narg, char **arg) : fixedpoint[0] = 0.5 * (domain->boxlo[0] + domain->boxhi[0]); fixedpoint[1] = 0.5 * (domain->boxlo[1] + domain->boxhi[1]); fixedpoint[2] = 0.5 * (domain->boxlo[2] + domain->boxhi[2]); - if (pstat_flag) { p_hydro = (p_target[0] + p_target[1] + p_target[2]) / pdim; } + if (pstat_flag) p_hydro = (p_target[0] + p_target[1] + p_target[2]) / pdim; // initialize Marsaglia RNG with processor-unique seed From 2afa07655f810bea8649a20f8fa998296c67446e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 03:44:11 -0400 Subject: [PATCH 405/448] set code owner for fix pimd/langevin --- .github/CODEOWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2686011281..f99a336dbb 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -67,6 +67,7 @@ src/EXTRA-COMPUTE/compute_born_matrix.* @Bibobu @athomps src/MISC/*_tracker.* @jtclemm src/MC/fix_gcmc.* @athomps src/MC/fix_sgcmc.* @athomps +src/REPLICA/fix_pimd_langevin.* @Yi-FanLi # core LAMMPS classes src/lammps.* @sjplimp From beabb4effec6bdf62cbd3d29fa01e0021280df6c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 03:48:59 -0400 Subject: [PATCH 406/448] remove dead code --- src/npair_skip_size_off2on_oneside.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/npair_skip_size_off2on_oneside.cpp b/src/npair_skip_size_off2on_oneside.cpp index eecf293755..3300ef1526 100644 --- a/src/npair_skip_size_off2on_oneside.cpp +++ b/src/npair_skip_size_off2on_oneside.cpp @@ -36,7 +36,7 @@ NPairSkipSizeOff2onOneside::NPairSkipSizeOff2onOneside(LAMMPS *lmp) : void NPairSkipSizeOff2onOneside::build(NeighList *list) { - int i,j,ii,jj,n,itype,jnum,joriginal,flip,tmp; + int i,j,ii,jj,itype,jnum,joriginal,flip,tmp; int *surf,*jlist; int *type = atom->type; @@ -76,8 +76,6 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) itype = type[i]; if (iskip[itype]) continue; - n = 0; - // loop over parent non-skip size list jlist = firstneigh_skip[i]; @@ -108,8 +106,7 @@ void NPairSkipSizeOff2onOneside::build(NeighList *list) for (i = 0; i < nlocal; i++) { if (numneigh[i] == 0) continue; - n = numneigh[i]; - firstneigh[i] = ipage->get(n); + firstneigh[i] = ipage->get(numneigh[i]); if (ipage->status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); } From bc52d863b46876c85f67e76be572d9ce5df72e1d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 08:48:01 -0400 Subject: [PATCH 407/448] cosmetic --- src/MC/fix_gcmc.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/MC/fix_gcmc.cpp b/src/MC/fix_gcmc.cpp index 634b512936..5d1e318db2 100644 --- a/src/MC/fix_gcmc.cpp +++ b/src/MC/fix_gcmc.cpp @@ -2328,8 +2328,7 @@ double FixGCMC::energy_full() } if (overlaptest) break; } - MPI_Allreduce(&overlaptest, &overlaptestall, 1, - MPI_INT, MPI_MAX, world); + MPI_Allreduce(&overlaptest, &overlaptestall, 1, MPI_INT, MPI_MAX, world); if (overlaptestall) return MAXENERGYSIGNAL; } From 8aeb059ce867b279f1b30fe359475b6fc1b3b243 Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Wed, 14 Jun 2023 15:03:35 +0200 Subject: [PATCH 408/448] Update doc/src/compute_stress_cartesian.rst Co-authored-by: Axel Kohlmeyer --- doc/src/compute_stress_cartesian.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/src/compute_stress_cartesian.rst b/doc/src/compute_stress_cartesian.rst index f52b360aa6..b9f090ef58 100644 --- a/doc/src/compute_stress_cartesian.rst +++ b/doc/src/compute_stress_cartesian.rst @@ -41,6 +41,10 @@ split into a kinetic contribution :math:`P^k` and a virial contribution This compute obeys momentum balance through fluid interfaces. They use the Irving--Kirkwood contour, which is the straight line between particle pairs. +.. versionadded:: TBD + + Added support for bond styles + This compute only supports pair and bond (no angle, dihedral, improper, or kspace) forces. By default, if no extra keywords are specified, all supported contributions to the stress are included (ke, pair, bond). If any From e6cd79e0e928071fbff2617ac9fd172657acc5d3 Mon Sep 17 00:00:00 2001 From: Lars Veldscholte Date: Wed, 14 Jun 2023 15:04:35 +0200 Subject: [PATCH 409/448] Fix doc links --- doc/src/Commands_compute.rst | 6 +++--- doc/src/compute.rst | 6 +++--- doc/src/compute_stress_cartesian.rst | 6 +++--- doc/src/compute_stress_curvilinear.rst | 4 ++-- doc/src/compute_stress_mop.rst | 22 +++++++++++++++------- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/doc/src/Commands_compute.rst b/doc/src/Commands_compute.rst index 755000c976..9066531459 100644 --- a/doc/src/Commands_compute.rst +++ b/doc/src/Commands_compute.rst @@ -153,11 +153,11 @@ KOKKOS, o = OPENMP, t = OPT. * :doc:`sph/t/atom ` * :doc:`spin ` * :doc:`stress/atom ` - * :doc:`stress/cartesian ` - * :doc:`stress/cylinder ` + * :doc:`stress/cartesian ` + * :doc:`stress/cylinder ` * :doc:`stress/mop ` * :doc:`stress/mop/profile ` - * :doc:`stress/spherical ` + * :doc:`stress/spherical ` * :doc:`stress/tally ` * :doc:`tdpd/cc/atom ` * :doc:`temp (k) ` diff --git a/doc/src/compute.rst b/doc/src/compute.rst index 950487cb72..4e5d8e6cb4 100644 --- a/doc/src/compute.rst +++ b/doc/src/compute.rst @@ -307,11 +307,11 @@ The individual style names on the :doc:`Commands compute ` pag * :doc:`sph/t/atom ` - per-atom internal temperature of Smooth-Particle Hydrodynamics atoms * :doc:`spin ` - magnetic quantities for a system of atoms having spins * :doc:`stress/atom ` - stress tensor for each atom -* :doc:`stress/cartesian ` - stress tensor in cartesian coordinates -* :doc:`stress/cylinder ` - stress tensor in cylindrical coordinates +* :doc:`stress/cartesian ` - stress tensor in cartesian coordinates +* :doc:`stress/cylinder ` - stress tensor in cylindrical coordinates * :doc:`stress/mop ` - normal components of the local stress tensor using the method of planes * :doc:`stress/mop/profile ` - profile of the normal components of the local stress tensor using the method of planes -* :doc:`stress/spherical ` - stress tensor in spherical coordinates +* :doc:`stress/spherical ` - stress tensor in spherical coordinates * :doc:`stress/tally ` - stress between two groups of atoms via the tally callback mechanism * :doc:`tdpd/cc/atom ` - per-atom chemical concentration of a specified species for each tDPD particle * :doc:`temp ` - temperature of group of atoms diff --git a/doc/src/compute_stress_cartesian.rst b/doc/src/compute_stress_cartesian.rst index b9f090ef58..3e1e9d9a8a 100644 --- a/doc/src/compute_stress_cartesian.rst +++ b/doc/src/compute_stress_cartesian.rst @@ -83,13 +83,13 @@ command, since those are contributions to the global system pressure. NOTE 2: The local stress profiles generated by these computes are similar to those obtained by the :doc:`method-of-planes (MOP) `. -A key difference -is that compute `stress/mop/profile ` +A key difference is that compute +:doc:`stress/mop/profile ` considers particles crossing a set of planes, while *stress/cartesian* computes averages for a set of small volumes. Moreover, this compute computes the diagonal components of the stress tensor :math:`P_{xx}`, :math:`P_{yy}`, and :math:`P_{zz}`, while -`stress/mop/profile ` computes the components +*stress/mop/profile* computes the components :math:`P_{ix}`, :math:`P_{iy}`, and :math:`P_{iz}`, where :math:`i` is the direction normal to the plane. diff --git a/doc/src/compute_stress_curvilinear.rst b/doc/src/compute_stress_curvilinear.rst index f7cbf5efbe..edd1df9217 100644 --- a/doc/src/compute_stress_curvilinear.rst +++ b/doc/src/compute_stress_curvilinear.rst @@ -115,8 +115,8 @@ package ` doc page for more info. Related commands """""""""""""""" -:doc:`compute stress/atom `, :doc:`compute pressure `, :doc:`compute -stress/mop/profile `, :doc:`compute stress/cartesian ` +:doc:`compute stress/atom `, :doc:`compute pressure `, +:doc:`compute stress/mop/profile `, :doc:`compute stress/cartesian ` Default """"""" diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index 4ad2261bb0..0b31805fbf 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -76,12 +76,16 @@ command, since those are contributions to the global system pressure. NOTE 3: The local stress profile generated by compute *stress/mop/profile* is similar to that obtained by compute -:doc:`stress/cartesian `. -A key difference is that compute *stress/mop/profile* considers particles -crossing a set of planes, while compute *stress/cartesian* computes averages -for a set of small volumes. More information -on the similarities and differences can be found in -:ref:`(Ikeshoji)`. +:doc:`stress/cartesian `. +A key difference is that compute *stress/mop/profile* +considers particles crossing a set of planes, while +*stress/cartesian* computes averages for a set +of small volumes. +Moreover, *stress/cartesian* compute computes the diagonal components of the stress +tensor :math:`P_{xx}`, :math:`P_{yy}`, and :math:`P_{zz}`, while +*stress/mop/profile* computes the components +:math:`P_{ix}`, :math:`P_{iy}`, and :math:`P_{iz}`, where :math:`i` is the +direction normal to the plane. Output info """"""""""" @@ -123,7 +127,11 @@ intra-molecular interactions, and long range (kspace) interactions. Related commands """""""""""""""" -:doc:`compute stress/atom `, :doc:`compute pressure `, :doc:`compute stress/cartesian `, :doc:`compute stress/cylinder `, :doc:`compute stress/spherical ` +:doc:`compute stress/atom `, +:doc:`compute pressure `, +:doc:`compute stress/cartesian `, +:doc:`compute stress/cylinder `, +:doc:`compute stress/spherical ` Default """"""" From 3b37c92b87df94a3087cbb038ec4bcc0d8328be0 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 10:06:01 -0400 Subject: [PATCH 410/448] consistently print error when box has changed to triclinic without redefining kspace style --- src/INTEL/pppm_disp_intel.cpp | 15 ++++------- src/KOKKOS/pppm_kokkos.cpp | 6 ++++- src/KSPACE/pppm_disp.cpp | 47 +++++++++++++++++++---------------- 3 files changed, 35 insertions(+), 33 deletions(-) diff --git a/src/INTEL/pppm_disp_intel.cpp b/src/INTEL/pppm_disp_intel.cpp index fdff23fe5e..319d070e66 100644 --- a/src/INTEL/pppm_disp_intel.cpp +++ b/src/INTEL/pppm_disp_intel.cpp @@ -124,8 +124,7 @@ void PPPMDispIntel::init() _use_lrt = fix->lrt(); if (_use_lrt) - error->all(FLERR, - "LRT mode is currently not supported for pppm/disp/intel"); + error->all(FLERR, "LRT mode is currently not supported for pppm/disp/intel"); // For vectorization, we need some padding in the end @@ -142,19 +141,15 @@ void PPPMDispIntel::init() if (_use_table) { rho_points = 5000; memory->destroy(rho_lookup); - memory->create(rho_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER, - "pppmdispintel:rho_lookup"); + memory->create(rho_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER,"pppmdispintel:rho_lookup"); memory->destroy(rho6_lookup); - memory->create(rho6_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER, - "pppmdispintel:rho6_lookup"); + memory->create(rho6_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER,"pppmdispintel:rho6_lookup"); if (differentiation_flag == 1) { memory->destroy(drho_lookup); - memory->create(drho_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER, - "pppmdispintel:drho_lookup"); + memory->create(drho_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER,"pppmdispintel:drho_lookup"); memory->destroy(drho6_lookup); - memory->create(drho6_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER, - "pppmdispintel:drho6_lookup"); + memory->create(drho6_lookup, rho_points, INTEL_P3M_ALIGNED_MAXORDER,"pppmdispintel:drho6_lookup"); } precompute_rho(); } diff --git a/src/KOKKOS/pppm_kokkos.cpp b/src/KOKKOS/pppm_kokkos.cpp index f76cab6f0f..912ae36f6f 100644 --- a/src/KOKKOS/pppm_kokkos.cpp +++ b/src/KOKKOS/pppm_kokkos.cpp @@ -138,7 +138,7 @@ PPPMKokkos::~PPPMKokkos() template void PPPMKokkos::init() { - if (me == 0) utils::logmesg(lmp,"PPPM initialization ...\n"); + if (me == 0) utils::logmesg(lmp,"PPPM Kokkos initialization ...\n"); // error check @@ -146,6 +146,10 @@ void PPPMKokkos::init() error->all(FLERR,"Cannot (yet) use PPPM Kokkos with 'kspace_modify diff ad'"); triclinic_check(); + + if (triclinic != domain->triclinic) + error->all(FLERR,"Must redefine kspace_style after changing to triclinic box"); + if (domain->triclinic && slabflag) error->all(FLERR,"Cannot (yet) use PPPM with triclinic box and slab correction"); if (domain->dimension == 2) diff --git a/src/KSPACE/pppm_disp.cpp b/src/KSPACE/pppm_disp.cpp index 84a21b46e6..ffa34a7e14 100644 --- a/src/KSPACE/pppm_disp.cpp +++ b/src/KSPACE/pppm_disp.cpp @@ -242,12 +242,12 @@ void PPPMDisp::settings(int narg, char **arg) PPPMDisp::~PPPMDisp() { - delete [] factors; - delete [] B; + delete[] factors; + delete[] B; B = nullptr; - delete [] cii; + delete[] cii; cii = nullptr; - delete [] csumi; + delete[] csumi; csumi = nullptr; PPPMDisp::deallocate(); PPPMDisp::deallocate_peratom(); @@ -268,6 +268,9 @@ void PPPMDisp::init() triclinic_check(); + if (triclinic != domain->triclinic) + error->all(FLERR,"Must redefine kspace_style after changing to triclinic box"); + if (domain->dimension == 2) error->all(FLERR,"Cannot use PPPMDisp with 2d simulation"); if (comm->style != Comm::BRICK) @@ -1277,7 +1280,7 @@ void PPPMDisp::init_coeffs() int n = atom->ntypes; int converged; - delete [] B; + delete[] B; B = nullptr; // no mixing rule or arithmetic @@ -3352,10 +3355,10 @@ void PPPMDisp::calc_csum() int ntypes = atom->ntypes; int i,j,k; - delete [] cii; + delete[] cii; cii = new double[ntypes+1]; for (i = 0; i<=ntypes; i++) cii[i] = 0.0; - delete [] csumi; + delete[] csumi; csumi = new double[ntypes+1]; for (i = 0; i<=ntypes; i++) csumi[i] = 0.0; int *neach = new int[ntypes+1]; @@ -3447,8 +3450,8 @@ void PPPMDisp::calc_csum() } } - delete [] neach; - delete [] neach_all; + delete[] neach; + delete[] neach_all; } /* ---------------------------------------------------------------------- @@ -6538,9 +6541,9 @@ void PPPMDisp::fieldforce_none_ik() } } - delete [] ekx; - delete [] eky; - delete [] ekz; + delete[] ekx; + delete[] eky; + delete[] ekz; } /* ---------------------------------------------------------------------- @@ -6660,9 +6663,9 @@ void PPPMDisp::fieldforce_none_ad() } } - delete [] ekx; - delete [] eky; - delete [] ekz; + delete[] ekx; + delete[] eky; + delete[] ekz; } /* ---------------------------------------------------------------------- @@ -6756,13 +6759,13 @@ void PPPMDisp::fieldforce_none_peratom() } } - delete [] u_pa; - delete [] v0; - delete [] v1; - delete [] v2; - delete [] v3; - delete [] v4; - delete [] v5; + delete[] u_pa; + delete[] v0; + delete[] v1; + delete[] v2; + delete[] v3; + delete[] v4; + delete[] v5; } /* ---------------------------------------------------------------------- From 0314c9892cee6410349f7ae147b669384e1de937 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 10:26:38 -0400 Subject: [PATCH 411/448] silence compiler warnings --- .../fortran/test_fortran_gather_scatter.f90 | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/unittest/fortran/test_fortran_gather_scatter.f90 b/unittest/fortran/test_fortran_gather_scatter.f90 index 1f8d4f0905..8741bba485 100644 --- a/unittest/fortran/test_fortran_gather_scatter.f90 +++ b/unittest/fortran/test_fortran_gather_scatter.f90 @@ -207,7 +207,7 @@ END SUBROUTINE f_lammps_scatter_atoms_subset_mask SUBROUTINE f_lammps_setup_gather_topology() BIND(C) USE LIBLAMMPS - USE keepstuff, ONLY : lmp, cont_input, more_input, pair_input + USE keepstuff, ONLY : lmp IMPLICIT NONE CALL lmp%command('include ${input_dir}/in.fourmol') @@ -232,7 +232,7 @@ FUNCTION f_lammps_test_gather_bonds_small() BIND(C) RESULT(count) nbonds = nbonds_small ELSE nbonds_big = lmp%extract_global('nbonds') - nbonds = nbonds_big + nbonds = INT(nbonds_big) END IF CALL lmp%gather_bonds(bonds) @@ -280,7 +280,7 @@ FUNCTION f_lammps_test_gather_bonds_big() BIND(C) RESULT(count) INTEGER(c_int64_t), POINTER :: nbonds_big nbonds_big = lmp%extract_global('nbonds') - nbonds = nbonds_big + nbonds = INT(nbonds_big) CALL lmp%gather_bonds(bonds) bonds_array(1:3,1:SIZE(bonds)/3) => bonds count = 0 @@ -332,7 +332,7 @@ FUNCTION f_lammps_test_gather_angles_small() BIND(C) RESULT(count) nangles = nangles_small ELSE nangles_big = lmp%extract_global('nangles') - nangles = nangles_big + nangles = INT(nangles_big) END IF CALL lmp%gather_angles(angles) @@ -380,7 +380,7 @@ FUNCTION f_lammps_test_gather_angles_big() BIND(C) RESULT(count) INTEGER(c_int64_t), POINTER :: nangles_big nangles_big = lmp%extract_global('nangles') - nangles = nangles_big + nangles = INT(nangles_big) CALL lmp%gather_angles(angles) angles_array(1:4,1:SIZE(angles)/4) => angles count = 0 @@ -432,7 +432,7 @@ FUNCTION f_lammps_test_gather_dihedrals_small() BIND(C) RESULT(count) ndihedrals = ndihedrals_small ELSE ndihedrals_big = lmp%extract_global('ndihedrals') - ndihedrals = ndihedrals_big + ndihedrals = INT(ndihedrals_big) END IF CALL lmp%gather_dihedrals(dihedrals) @@ -478,7 +478,7 @@ FUNCTION f_lammps_test_gather_dihedrals_big() BIND(C) RESULT(count) INTEGER(c_int64_t), POINTER :: ndihedrals_big ndihedrals_big = lmp%extract_global('ndihedrals') - ndihedrals = ndihedrals_big + ndihedrals = INT(ndihedrals_big) CALL lmp%gather_dihedrals(dihedrals) dihedrals_array(1:5,1:SIZE(dihedrals)/5) => dihedrals count = 0 @@ -528,7 +528,7 @@ FUNCTION f_lammps_test_gather_impropers_small() BIND(C) RESULT(count) nimpropers = nimpropers_small ELSE nimpropers_big = lmp%extract_global('nimpropers') - nimpropers = nimpropers_big + nimpropers = INT(nimpropers_big) END IF CALL lmp%gather_impropers(impropers) @@ -566,7 +566,7 @@ FUNCTION f_lammps_test_gather_impropers_big() BIND(C) RESULT(count) INTEGER(c_int64_t), POINTER :: nimpropers_big nimpropers_big = lmp%extract_global('nimpropers') - nimpropers = nimpropers_big + nimpropers = INT(nimpropers_big) CALL lmp%gather_impropers(impropers) impropers_array(1:5,1:SIZE(impropers)/5) => impropers count = 0 From b225c94f5964f51e7220f8542666a8d8e8146718 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 12:12:04 -0400 Subject: [PATCH 412/448] remove variable shadowing instance in base class --- src/KOKKOS/pppm_kokkos.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/KOKKOS/pppm_kokkos.h b/src/KOKKOS/pppm_kokkos.h index 50b5ac0f35..2c6dcc4e15 100644 --- a/src/KOKKOS/pppm_kokkos.h +++ b/src/KOKKOS/pppm_kokkos.h @@ -430,7 +430,6 @@ class PPPMKokkos : public PPPM, public KokkosBaseFFT { // triclinic - int triclinic; // domain settings, orthog or triclinic void setup_triclinic(); void compute_gf_ik_triclinic(); void poisson_ik_triclinic(); From 8a738fabcb073ab9a0a7a0709be91079bb983e9d Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 12:12:18 -0400 Subject: [PATCH 413/448] must initialized triclinic variable in constructor --- src/KSPACE/pppm_disp.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/KSPACE/pppm_disp.cpp b/src/KSPACE/pppm_disp.cpp index ffa34a7e14..78ebad512a 100644 --- a/src/KSPACE/pppm_disp.cpp +++ b/src/KSPACE/pppm_disp.cpp @@ -110,6 +110,7 @@ PPPMDisp::PPPMDisp(LAMMPS *lmp) : KSpace(lmp), { triclinic_support = 0; pppmflag = dispersionflag = 1; + triclinic = domain->triclinic; nfactors = 3; factors = new int[nfactors]; From 0cd566a4179d123a98b288ec3c270725fc87477c Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Wed, 14 Jun 2023 10:43:30 -0600 Subject: [PATCH 414/448] Fix compile error for HIP --- src/KOKKOS/pair_eam_alloy_kokkos.cpp | 53 +++++++++++++++------------- src/KOKKOS/pair_eam_alloy_kokkos.h | 4 +-- src/KOKKOS/pair_eam_fs_kokkos.cpp | 51 ++++++++++++++------------ src/KOKKOS/pair_eam_fs_kokkos.h | 4 +-- src/KOKKOS/pair_eam_kokkos.cpp | 51 ++++++++++++++------------ src/KOKKOS/pair_eam_kokkos.h | 4 +-- 6 files changed, 91 insertions(+), 76 deletions(-) diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index f97af7bce2..2b81e21e2b 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -193,7 +193,7 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) *this,ev); else Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } @@ -246,31 +246,31 @@ void PairEAMAlloyKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } @@ -655,7 +655,7 @@ void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelB, c ////Specialisation for Neighborlist types Half, HalfThread, Full template template - +KOKKOS_INLINE_FUNCTION void PairEAMAlloyKokkos::operator()(TagPairEAMAlloyKernelAB, const int &ii, EV_FLOAT& ev) const { // rho = density at each atom @@ -1474,27 +1474,32 @@ void PairEAMAlloyKokkos::file2array_alloy() /* ---------------------------------------------------------------------- */ -template -template -auto PairEAMAlloyKokkos::policyInstance(int inum) { - #ifdef KOKKOS_ENABLE_HIP - if (execution_space != Host) { +template +template +struct PairEAMAlloyKokkos::policyInstance { + KOKKOS_INLINE_FUNCTION + static auto get(int inum) { + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + } +}; + +#ifdef KOKKOS_ENABLE_HIP +template<> +template +struct PairEAMAlloyKokkos::policyInstance { + KOKKOS_INLINE_FUNCTION + static auto get(int inum) { static_assert(t_ffloat_2d_n7::static_extent(2) == 7, "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); - auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) .set_scratch_size(0, - Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); + Kokkos::PerTeam(MAX_CACHE_ROWS*7*sizeof(double))); return policy; - } else { - auto policy = Kokkos::RangePolicy(0,inum); - return policy; - } - #else - auto policy = Kokkos::RangePolicy(0,inum); - return policy; - #endif -} + } +}; +#endif /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.h b/src/KOKKOS/pair_eam_alloy_kokkos.h index f9703ef473..2eb40189ac 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.h +++ b/src/KOKKOS/pair_eam_alloy_kokkos.h @@ -183,8 +183,8 @@ class PairEAMAlloyKokkos : public PairEAM, public KokkosBase { void array2spline() override; void read_file(char *) override; - template - auto policyInstance(int inum); + template + struct policyInstance; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d d_ilist; diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index a437527584..4572d14e48 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -193,7 +193,7 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) *this,ev); else Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } @@ -246,31 +246,31 @@ void PairEAMFSKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } @@ -1484,27 +1484,32 @@ void PairEAMFSKokkos::file2array_fs() /* ---------------------------------------------------------------------- */ -template -template -auto PairEAMFSKokkos::policyInstance(int inum) { - #ifdef KOKKOS_ENABLE_HIP - if (execution_space != Host) { +template +template +struct PairEAMFSKokkos::policyInstance { + KOKKOS_INLINE_FUNCTION + static auto get(int inum) { + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + } +}; + +#ifdef KOKKOS_ENABLE_HIP +template<> +template +struct PairEAMFSKokkos::policyInstance { + KOKKOS_INLINE_FUNCTION + static auto get(int inum) { static_assert(t_ffloat_2d_n7::static_extent(2) == 7, "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); - auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) .set_scratch_size(0, - Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); + Kokkos::PerTeam(MAX_CACHE_ROWS*7*sizeof(double))); return policy; - } else { - auto policy = Kokkos::RangePolicy(0,inum); - return policy; - } - #else - auto policy = Kokkos::RangePolicy(0,inum); - return policy; - #endif -} + } +}; +#endif /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_eam_fs_kokkos.h b/src/KOKKOS/pair_eam_fs_kokkos.h index f7513b3008..bd03ab0015 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.h +++ b/src/KOKKOS/pair_eam_fs_kokkos.h @@ -183,8 +183,8 @@ class PairEAMFSKokkos : public PairEAM, public KokkosBase { void array2spline() override; void read_file(char *) override; - template - auto policyInstance(int inum); + template + struct policyInstance; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d d_ilist; diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index 5e2ea4357f..de6d3646bf 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -188,7 +188,7 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) *this,ev); else Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } @@ -241,31 +241,31 @@ void PairEAMKokkos::compute(int eflag_in, int vflag_in) if (neighflag == HALF) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } else if (neighflag == HALFTHREAD) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } else if (neighflag == FULL) { if (newton_pair) { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } else { Kokkos::parallel_for( - policyInstance>(inum), + policyInstance>::get(inum), *this); } } @@ -1159,27 +1159,32 @@ void PairEAMKokkos::ev_tally(EV_FLOAT &ev, const int &i, const int & /* ---------------------------------------------------------------------- */ -template -template -auto PairEAMKokkos::policyInstance(int inum) { - #ifdef KOKKOS_ENABLE_HIP - if (execution_space != Host) { +template +template +struct PairEAMKokkos::policyInstance { + KOKKOS_INLINE_FUNCTION + static auto get(int inum) { + auto policy = Kokkos::RangePolicy(0,inum); + return policy; + } +}; + +#ifdef KOKKOS_ENABLE_HIP +template<> +template +struct PairEAMKokkos::policyInstance { + KOKKOS_INLINE_FUNCTION + static auto get(int inum) { static_assert(t_ffloat_2d_n7::static_extent(2) == 7, "Breaking assumption of spline dim for KernelAB and KernelC scratch caching"); - auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) + auto policy = Kokkos::TeamPolicy((inum+1023)/1024, 1024) .set_scratch_size(0, - Kokkos::PerTeam(MAX_CACHE_ROWS*t_ffloat_2d_n7::static_extent(2)*sizeof(double))); + Kokkos::PerTeam(MAX_CACHE_ROWS*7*sizeof(double))); return policy; - } else { - auto policy = Kokkos::RangePolicy(0,inum); - return policy; - } - #else - auto policy = Kokkos::RangePolicy(0,inum); - return policy; - #endif -} + } +}; +#endif /* ---------------------------------------------------------------------- */ diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index 41e02e68cc..d9765b37c0 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -179,8 +179,8 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { void file2array() override; void array2spline() override; - template - auto policyInstance(int inum); + template + struct policyInstance; typename AT::t_neighbors_2d d_neighbors; typename AT::t_int_1d d_ilist; From 0564d795700e92d527d3ce034c09071d19a57320 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Wed, 14 Jun 2023 10:52:47 -0600 Subject: [PATCH 415/448] Fix SYCL compile error with GNU make, see https://github.com/kokkos/kokkos/pull/6218 --- lib/kokkos/Makefile.kokkos | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/kokkos/Makefile.kokkos b/lib/kokkos/Makefile.kokkos index 361995d847..adcee303ba 100644 --- a/lib/kokkos/Makefile.kokkos +++ b/lib/kokkos/Makefile.kokkos @@ -1376,6 +1376,7 @@ ifneq ($(KOKKOS_INTERNAL_NEW_CONFIG), 0) ifeq ($(KOKKOS_INTERNAL_USE_SYCL), 1) tmp := $(call kokkos_append_config_header,"$H""include ","KokkosCore_Config_FwdBackend.hpp") tmp := $(call kokkos_append_config_header,"$H""include ","KokkosCore_Config_DeclareBackend.hpp") + tmp := $(call kokkos_append_config_header,"$H""include ","KokkosCore_Config_SetupBackend.hpp") endif ifeq ($(KOKKOS_INTERNAL_USE_HIP), 1) tmp := $(call kokkos_append_config_header,"$H""include ","KokkosCore_Config_FwdBackend.hpp") From c83dc1ff305f950cbc60c72c89b3cc6c85a5fd9f Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 13:52:54 -0400 Subject: [PATCH 416/448] fix STORE global -> fix STORE/GLOBAL --- src/EXTRA-FIX/fix_npt_cauchy.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EXTRA-FIX/fix_npt_cauchy.cpp b/src/EXTRA-FIX/fix_npt_cauchy.cpp index 380964f058..feb5a95c6f 100644 --- a/src/EXTRA-FIX/fix_npt_cauchy.cpp +++ b/src/EXTRA-FIX/fix_npt_cauchy.cpp @@ -2461,7 +2461,7 @@ void FixNPTCauchy::CauchyStat_init() if (!init_store) init_store = dynamic_cast( - modify->add_fix(std::string(id_store) + " all STORE global 1 6")); + modify->add_fix(std::string(id_store) + " all STORE/GLOBAL 1 6")); initRUN = 0; initPK = 1; From 27908139aeb0509550cbc84b47913524bff7135e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 14:14:47 -0400 Subject: [PATCH 417/448] whitespace --- src/KOKKOS/pair_eam_kokkos.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/KOKKOS/pair_eam_kokkos.h b/src/KOKKOS/pair_eam_kokkos.h index d9765b37c0..9d066d40a0 100644 --- a/src/KOKKOS/pair_eam_kokkos.h +++ b/src/KOKKOS/pair_eam_kokkos.h @@ -59,7 +59,7 @@ class PairEAMKokkos : public PairEAM, public KokkosBase { ~PairEAMKokkos() override; void compute(int, int) override; void init_style() override; - + KOKKOS_INLINE_FUNCTION void operator()(TagPairEAMPackForwardComm, const int&) const; From 82f664acd4613e2b103eb0c648eb48391233bdc7 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 14:43:29 -0400 Subject: [PATCH 418/448] update log files for BODY package styles --- examples/body/log.14Jun23.body.g++.1 | 180 ++++++++++++++ examples/body/log.14Jun23.body.g++.4 | 180 ++++++++++++++ ...18.cubes.g++.1 => log.14Jun23.cubes.g++.1} | 70 +++--- ...18.cubes.g++.4 => log.14Jun23.cubes.g++.4} | 72 +++--- examples/body/log.14Jun23.pour3d.g++.1 | 148 +++++++++++ examples/body/log.14Jun23.pour3d.g++.4 | 148 +++++++++++ examples/body/log.14Jun23.squares.g++.1 | 226 +++++++++++++++++ examples/body/log.14Jun23.squares.g++.4 | 226 +++++++++++++++++ examples/body/log.14Jun23.wall2d.g++.1 | 229 ++++++++++++++++++ examples/body/log.14Jun23.wall2d.g++.4 | 229 ++++++++++++++++++ examples/body/log.27Nov18.body.g++.1 | 177 -------------- examples/body/log.27Nov18.body.g++.4 | 177 -------------- examples/body/log.27Nov18.pour3d.g++.1 | 74 ------ examples/body/log.27Nov18.pour3d.g++.4 | 74 ------ examples/body/log.27Nov18.squares.g++.1 | 222 ----------------- examples/body/log.27Nov18.squares.g++.4 | 222 ----------------- examples/body/log.27Nov18.wall2d.g++.1 | 224 ----------------- examples/body/log.27Nov18.wall2d.g++.4 | 224 ----------------- 18 files changed, 1641 insertions(+), 1461 deletions(-) create mode 100644 examples/body/log.14Jun23.body.g++.1 create mode 100644 examples/body/log.14Jun23.body.g++.4 rename examples/body/{log.27Nov18.cubes.g++.1 => log.14Jun23.cubes.g++.1} (52%) rename examples/body/{log.27Nov18.cubes.g++.4 => log.14Jun23.cubes.g++.4} (50%) create mode 100644 examples/body/log.14Jun23.pour3d.g++.1 create mode 100644 examples/body/log.14Jun23.pour3d.g++.4 create mode 100644 examples/body/log.14Jun23.squares.g++.1 create mode 100644 examples/body/log.14Jun23.squares.g++.4 create mode 100644 examples/body/log.14Jun23.wall2d.g++.1 create mode 100644 examples/body/log.14Jun23.wall2d.g++.4 delete mode 100644 examples/body/log.27Nov18.body.g++.1 delete mode 100644 examples/body/log.27Nov18.body.g++.4 delete mode 100644 examples/body/log.27Nov18.pour3d.g++.1 delete mode 100644 examples/body/log.27Nov18.pour3d.g++.4 delete mode 100644 examples/body/log.27Nov18.squares.g++.1 delete mode 100644 examples/body/log.27Nov18.squares.g++.4 delete mode 100644 examples/body/log.27Nov18.wall2d.g++.1 delete mode 100644 examples/body/log.27Nov18.wall2d.g++.4 diff --git a/examples/body/log.14Jun23.body.g++.1 b/examples/body/log.14Jun23.body.g++.1 new file mode 100644 index 0000000000..e016e88b0b --- /dev/null +++ b/examples/body/log.14Jun23.body.g++.1 @@ -0,0 +1,180 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# 2d polygon nparticle bodies + +units lj +dimension 2 +atom_style body nparticle 2 6 + +read_data data.body +Reading data file ... + orthogonal box = (-15.532225 -15.532225 -0.5) to (15.532225 15.532225 0.5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 100 atoms + 100 bodies + read_data CPU = 0.002 seconds + +velocity all create 1.44 87287 loop geom + +pair_style body/nparticle 5.0 +pair_coeff * * 1.0 1.0 + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +fix 1 all nve/body +#fix 1 all nvt/body temp 1.44 1.44 1.0 +fix 2 all enforce2d + +#compute 1 all body/local type 1 2 3 +#dump 1 all local 100 dump.body index c_1[1] c_1[2] c_1[3] c_1[4] + +#dump 2 all image 1000 image.*.jpg type type # zoom 1.6 adiam 1.5 body type 1.0 0 +#dump_modify 2 pad 5 + +thermo 100 +run 10000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 5.5 + ghost atom cutoff = 5.5 + binsize = 2.75, bins = 12 12 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/nparticle, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 5.279 | 5.279 | 5.279 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 1.44 -0.63799525 0 0.78760475 -0.15028724 + 100 1.6423694 -1.0001516 0 0.62579417 0.16116443 + 200 1.4802187 -1.2479519 0 0.21746458 0.35445329 + 300 1.4734223 -1.3213583 0 0.1373298 0.45266192 + 400 1.5118818 -1.5924889 0 -0.095725867 0.13296961 + 500 1.5471951 -1.630886 0 -0.099162814 0.12439793 + 600 1.6264248 -1.6468162 0 -0.03665568 0.43392484 + 700 1.597475 -1.6539821 0 -0.072481849 0.13128147 + 800 1.6841531 -1.775776 0 -0.10846445 -0.032960346 + 900 1.556262 -1.6750139 0 -0.1343146 0.53484605 + 1000 1.6272373 -1.7572956 0 -0.14633067 0.18431831 + 1100 1.6448235 -1.7176556 0 -0.089280316 0.25900065 + 1200 1.5486928 -1.6481004 0 -0.11489454 0.036934194 + 1300 1.7449183 -1.6039068 0 0.12356231 -0.071099427 + 1400 1.668581 -1.5939776 0 0.057917584 0.02239666 + 1500 1.6514223 -1.7086624 0 -0.073754397 0.39021328 + 1600 1.8367415 -1.808017 0 0.010357066 0.1405097 + 1700 1.6439993 -1.7711084 0 -0.14354908 0.37488252 + 1800 1.8105437 -1.7312044 0 0.061233893 0.033817829 + 1900 1.7745557 -1.7184539 0 0.038356243 0.26826112 + 2000 1.4919032 -1.7635799 0 -0.28659575 0.32901186 + 2100 1.5086111 -1.5151192 0 -0.021594146 0.37082072 + 2200 1.4464813 -1.5702682 0 -0.13825163 -0.043079808 + 2300 1.398236 -1.5359564 0 -0.15170277 0.14467017 + 2400 1.5050139 -1.6002694 0 -0.11030569 0.30358205 + 2500 1.5549789 -1.652805 0 -0.11337589 0.2916046 + 2600 1.4774593 -1.5406116 0 -0.077926888 0.020921323 + 2700 1.3700851 -1.5855698 0 -0.22918557 0.22226615 + 2800 1.4656869 -1.629742 0 -0.17871195 -0.0090503155 + 2900 1.4355808 -1.6486992 0 -0.22747424 0.12741636 + 3000 1.5859288 -1.5467092 0 0.023360382 0.23081334 + 3100 1.6099287 -1.4917881 0 0.10204129 0.22085916 + 3200 1.6814814 -1.554998 0 0.10966853 0.10312492 + 3300 1.5319494 -1.4723195 0 0.044310484 0.18583117 + 3400 1.5124418 -1.499312 0 -0.0019945387 0.15564425 + 3500 1.6106798 -1.5568215 0 0.037751529 0.27433785 + 3600 1.460087 -1.5530078 0 -0.10752165 0.0073889211 + 3700 1.5744452 -1.5720821 0 -0.013381308 0.27735962 + 3800 1.7290106 -1.6504739 0 0.061246632 0.48173619 + 3900 1.611197 -1.6452216 0 -0.05013663 0.4286963 + 4000 1.6715425 -1.6409258 0 0.013901267 0.017020657 + 4100 1.6913694 -1.5885259 0 0.085929717 0.13679669 + 4200 1.5347633 -1.6316222 0 -0.11220653 0.024396005 + 4300 1.5221369 -1.5924627 0 -0.085547139 0.29634927 + 4400 1.7020273 -1.7069204 0 -0.021913362 0.12700619 + 4500 1.7176336 -1.7439335 0 -0.043476251 0.14745343 + 4600 1.4409943 -1.6121558 0 -0.18557152 0.018887675 + 4700 1.7868207 -1.6707762 0 0.098176247 0.20004565 + 4800 1.8720226 -1.7000206 0 0.15328178 0.25661867 + 4900 1.7128343 -1.7289913 0 -0.033285317 0.24698662 + 5000 1.7242114 -1.6662075 0 0.040761785 0.18935677 + 5100 1.7589418 -1.7267393 0 0.014613086 0.40918365 + 5200 1.7138074 -1.778402 0 -0.081732715 0.39679805 + 5300 1.8149032 -1.7708654 0 0.025888786 0.29874434 + 5400 1.7140097 -1.6444743 0 0.052395323 0.62588743 + 5500 1.8076873 -1.7276245 0 0.061985946 0.25434646 + 5600 1.7137948 -1.678778 0 0.017878859 0.21062182 + 5700 1.8625614 -1.7114074 0 0.1325284 0.14365823 + 5800 1.667941 -1.6462142 0 0.0050473638 0.36134037 + 5900 1.7080521 -1.6919526 0 -0.00098107526 0.27472252 + 6000 1.7180315 -1.6677683 0 0.033082909 0.29905397 + 6100 1.8264687 -1.6837934 0 0.12441065 0.033504487 + 6200 1.757998 -1.634503 0 0.10591508 0.14360478 + 6300 1.6444838 -1.5734502 0 0.05458881 0.50314779 + 6400 1.7213235 -1.705482 0 -0.0013717454 -0.063375271 + 6500 1.5454026 -1.7236013 0 -0.19365272 0.21355367 + 6600 1.7550617 -1.7304462 0 0.0070648556 0.1782743 + 6700 1.6931304 -1.7005361 0 -0.024337029 0.31165135 + 6800 1.7953505 -1.7377126 0 0.039684354 0.27052592 + 6900 1.6547086 -1.6971987 0 -0.059037125 0.26390513 + 7000 1.678321 -1.6343689 0 0.027168906 0.23632145 + 7100 1.6389472 -1.690589 0 -0.068031265 0.26471258 + 7200 1.6772509 -1.7305397 0 -0.070061301 0.16013956 + 7300 1.7401473 -1.7461921 0 -0.023446315 0.14462402 + 7400 1.7381776 -1.6586839 0 0.06211186 0.47746891 + 7500 1.7184021 -1.8309755 0 -0.1297574 0.27706616 + 7600 1.8404039 -1.7957552 0 0.026244663 0.12898128 + 7700 1.8474196 -1.7118818 0 0.11706359 0.1959609 + 7800 1.7635506 -1.6119363 0 0.1339788 0.086260229 + 7900 1.5873929 -1.5651473 0 0.0063716922 0.0010935251 + 8000 1.6394989 -1.5900851 0 0.033018817 0.41301427 + 8100 1.6731865 -1.6981463 0 -0.041691712 0.46624156 + 8200 1.7728067 -1.7515658 0 0.0035128109 0.16520115 + 8300 1.6142221 -1.8030321 0 -0.20495225 0.039485737 + 8400 1.6775678 -1.8266472 0 -0.16585509 0.074514313 + 8500 1.8399403 -1.8100014 0 0.011539538 0.38126754 + 8600 1.8259529 -1.6641902 0 0.14350318 0.80219793 + 8700 1.8454807 -1.68448 0 0.14254593 0.18855669 + 8800 1.7017088 -1.7219601 0 -0.037268433 0.36465692 + 8900 1.612135 -1.5813013 0 0.014712431 0.21657263 + 9000 1.5992353 -1.7093785 0 -0.12613559 0.038933966 + 9100 1.7486466 -1.7024749 0 0.028685202 0.28688996 + 9200 1.546781 -1.6512407 0 -0.1199275 0.16188207 + 9300 1.8424683 -1.7304781 0 0.093565478 0.35295164 + 9400 1.7646311 -1.7795324 0 -0.032547636 0.39114207 + 9500 1.8061763 -1.8458669 0 -0.057752329 0.18930255 + 9600 1.6953348 -1.7144901 0 -0.036108734 0.18392219 + 9700 1.693168 -1.5860306 0 0.090205689 0.18749665 + 9800 1.6057784 -1.6478049 0 -0.05808426 0.28339031 + 9900 1.712654 -1.6566387 0 0.038888773 0.52108885 + 10000 1.7102385 -1.6670768 0 0.026059337 0.073458218 +Loop time of 1.09582 on 1 procs for 10000 steps with 100 atoms + +Performance: 3942257.351 tau/day, 9125.596 timesteps/s, 912.560 katom-step/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.95651 | 0.95651 | 0.95651 | 0.0 | 87.29 +Neigh | 0.0064365 | 0.0064365 | 0.0064365 | 0.0 | 0.59 +Comm | 0.015238 | 0.015238 | 0.015238 | 0.0 | 1.39 +Output | 0.00059554 | 0.00059554 | 0.00059554 | 0.0 | 0.05 +Modify | 0.10993 | 0.10993 | 0.10993 | 0.0 | 10.03 +Other | | 0.007113 | | | 0.65 + +Nlocal: 100 ave 100 max 100 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 80 ave 80 max 80 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 448 ave 448 max 448 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 448 +Ave neighs/atom = 4.48 +Neighbor list builds = 463 +Dangerous builds = 0 +Total wall time: 0:00:01 diff --git a/examples/body/log.14Jun23.body.g++.4 b/examples/body/log.14Jun23.body.g++.4 new file mode 100644 index 0000000000..54ae630872 --- /dev/null +++ b/examples/body/log.14Jun23.body.g++.4 @@ -0,0 +1,180 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# 2d polygon nparticle bodies + +units lj +dimension 2 +atom_style body nparticle 2 6 + +read_data data.body +Reading data file ... + orthogonal box = (-15.532225 -15.532225 -0.5) to (15.532225 15.532225 0.5) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 100 atoms + 100 bodies + read_data CPU = 0.001 seconds + +velocity all create 1.44 87287 loop geom + +pair_style body/nparticle 5.0 +pair_coeff * * 1.0 1.0 + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +fix 1 all nve/body +#fix 1 all nvt/body temp 1.44 1.44 1.0 +fix 2 all enforce2d + +#compute 1 all body/local type 1 2 3 +#dump 1 all local 100 dump.body index c_1[1] c_1[2] c_1[3] c_1[4] + +#dump 2 all image 1000 image.*.jpg type type # zoom 1.6 adiam 1.5 body type 1.0 0 +#dump_modify 2 pad 5 + +thermo 100 +run 10000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 5.5 + ghost atom cutoff = 5.5 + binsize = 2.75, bins = 12 12 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/nparticle, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 5.268 | 5.268 | 5.268 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 1.44 -0.63799525 0 0.78760475 -0.15028724 + 100 1.6423663 -1.000111 0 0.62583161 0.16116978 + 200 1.4802732 -1.2478364 0 0.21763407 0.35464152 + 300 1.4735433 -1.3211072 0 0.13770068 0.45307413 + 400 1.5119491 -1.5930779 0 -0.096248286 0.13119532 + 500 1.5449834 -1.6300143 0 -0.10048065 0.12635421 + 600 1.621105 -1.6459036 0 -0.041009639 0.43837884 + 700 1.5959719 -1.6348501 0 -0.054837867 0.13233006 + 800 1.6862723 -1.6902254 0 -0.020815854 0.20072937 + 900 1.6771131 -1.6544493 0 0.0058926625 0.34898089 + 1000 1.5867 -1.6797024 0 -0.10886943 0.33511593 + 1100 1.7842277 -1.6814985 0 0.084886913 0.23634574 + 1200 1.7089241 -1.6766866 0 0.015148192 0.40440454 + 1300 1.6195529 -1.6078381 0 -0.004480726 0.12193834 + 1400 1.5967912 -1.563198 0 0.017625291 0.2233618 + 1500 1.6131091 -1.5731367 0 0.023841282 0.13856054 + 1600 1.6096972 -1.5741595 0 0.01944073 0.096081201 + 1700 1.6099281 -1.5875363 0 0.0062924683 0.28628509 + 1800 1.7328539 -1.5696894 0 0.14583598 0.2202503 + 1900 1.6433157 -1.6659757 0 -0.039093124 0.12006746 + 2000 1.8262234 -1.778379 0 0.029582122 0.17815935 + 2100 1.7441298 -1.704871 0 0.021817442 0.30772022 + 2200 1.7933363 -1.7246149 0 0.050788098 0.11323852 + 2300 1.7458809 -1.7186101 0 0.0098120012 0.0034260299 + 2400 1.8202324 -1.7777769 0 0.024253178 0.089077551 + 2500 1.691512 -1.6976236 0 -0.023026761 0.23901369 + 2600 1.6221153 -1.639172 0 -0.033277785 0.36881214 + 2700 1.5532388 -1.7286197 0 -0.19091334 0.1714534 + 2800 1.6648128 -1.7298542 0 -0.081689467 0.0077427265 + 2900 1.6548465 -1.7126766 0 -0.074378524 0.096972027 + 3000 1.604345 -1.7210036 0 -0.13270205 0.25227471 + 3100 1.67823 -1.6537385 0 0.0077092269 0.13198555 + 3200 1.4695581 -1.5609142 0 -0.10605159 0.28909806 + 3300 1.6778332 -1.7396206 0 -0.078565681 0.25069132 + 3400 1.7588934 -1.680043 0 0.061261505 0.28609454 + 3500 1.6699117 -1.7762865 0 -0.12307397 0.2584648 + 3600 1.5951406 -1.6611845 0 -0.081995282 0.35801267 + 3700 1.5267137 -1.6371603 0 -0.12571366 0.6116418 + 3800 1.6792717 -1.638182 0 0.024296953 0.43447072 + 3900 1.5857658 -1.6607833 0 -0.09087513 0.19479457 + 4000 1.6062152 -1.5436014 0 0.046551586 0.55118141 + 4100 1.5505892 -1.5259333 0 0.0091500726 0.49075107 + 4200 1.6933 -1.6314975 0 0.044869524 0.032970187 + 4300 1.6498743 -1.7298746 0 -0.096499053 0.14837573 + 4400 1.6535324 -1.7095911 0 -0.072593998 0.24207879 + 4500 1.835466 -1.7677327 0 0.049378652 0.18168744 + 4600 1.7346556 -1.6379956 0 0.07931344 0.49973778 + 4700 1.8050359 -1.8354358 0 -0.048450223 -0.037354111 + 4800 1.6361661 -1.7741414 0 -0.15433697 0.36409064 + 4900 1.6511224 -1.7703808 0 -0.13576956 0.23794467 + 5000 1.6249047 -1.6516641 0 -0.043008453 0.15155643 + 5100 1.6842561 -1.7128485 0 -0.045434914 0.30999124 + 5200 1.6153583 -1.630441 0 -0.031236245 -0.0083460068 + 5300 1.6806066 -1.6907533 0 -0.026952801 0.16886559 + 5400 1.7541932 -1.7161908 0 0.020460503 0.16560614 + 5500 1.8643473 -1.7810235 0 0.064680293 0.061200837 + 5600 1.5963536 -1.6145484 0 -0.034158307 0.47888104 + 5700 1.7385482 -1.7214092 0 -0.00024648083 0.22078849 + 5800 1.6726308 -1.6987799 0 -0.042875376 0.46131938 + 5900 1.7830081 -1.7766484 0 -0.011470422 0.12597212 + 6000 1.9057941 -1.719849 0 0.16688715 0.37367068 + 6100 1.6882353 -1.6888488 0 -0.0174959 0.33635307 + 6200 1.8644261 -1.7435021 0 0.10227973 0.54157135 + 6300 1.8043895 -1.8169618 0 -0.030616242 0.20596562 + 6400 1.8745855 -1.7752732 0 0.080566434 0.18365661 + 6500 1.8330698 -1.6984304 0 0.11630864 0.058109254 + 6600 1.8006644 -1.7398524 0 0.042805376 0.17509961 + 6700 1.7471279 -1.7009995 0 0.0286571 0.13439557 + 6800 1.7077006 -1.7462928 0 -0.055669263 0.16474264 + 6900 1.7602738 -1.8336138 0 -0.090942793 0.37533762 + 7000 1.6962037 -1.7746381 0 -0.095396485 0.28764793 + 7100 1.6040275 -1.652448 0 -0.064460796 0.47621288 + 7200 1.7595892 -1.6260406 0 0.11595278 0.55174207 + 7300 1.8031743 -1.7436876 0 0.041454978 0.35699364 + 7400 1.6575485 -1.5994276 0 0.041545422 0.38389368 + 7500 1.8539985 -1.6888181 0 0.14664046 0.25524239 + 7600 1.6721617 -1.6819419 0 -0.026501825 0.18077253 + 7700 1.4696976 -1.5368001 0 -0.081799475 0.37392274 + 7800 1.6532125 -1.6604679 0 -0.023787555 0.25683053 + 7900 1.5890818 -1.711541 0 -0.13834993 0.28943398 + 8000 1.6729844 -1.674981 0 -0.01872644 0.1725141 + 8100 1.6041427 -1.7188678 0 -0.13076654 0.22948004 + 8200 1.7000012 -1.5584259 0 0.12457532 0.82913741 + 8300 1.6662649 -1.8411986 0 -0.19159634 0.40893581 + 8400 1.6031593 -1.8225478 0 -0.23542004 0.21287004 + 8500 1.6615542 -1.685667 0 -0.040728376 0.40063656 + 8600 1.6094262 -1.7942547 0 -0.20092282 0.28738874 + 8700 1.6040855 -1.6483081 0 -0.060263486 0.22614876 + 8800 1.6658931 -1.6751256 0 -0.025891437 0.027723314 + 8900 1.7989105 -1.7318497 0 0.049071648 0.27645866 + 9000 1.8242262 -1.6879124 0 0.11807158 0.21701732 + 9100 1.6795701 -1.6926952 0 -0.029920813 0.28702517 + 9200 1.8093352 -1.8430841 0 -0.051842329 0.04182244 + 9300 1.7654746 -1.7580453 0 -0.010225436 0.41460279 + 9400 1.9494599 -1.7162713 0 0.21369396 0.22445951 + 9500 1.8650839 -1.6517629 0 0.19467014 0.34042974 + 9600 1.8080088 -1.651068 0 0.13886064 0.38597156 + 9700 1.757349 -1.6397227 0 0.10005277 0.12075072 + 9800 1.8111959 -1.7155458 0 0.077538075 0.023545696 + 9900 1.7255423 -1.7364511 0 -0.02816423 0.24284116 + 10000 1.794001 -1.7545014 0 0.021559597 0.15092078 +Loop time of 0.461554 on 4 procs for 10000 steps with 100 atoms + +Performance: 9359693.727 tau/day, 21665.958 timesteps/s, 2.167 Matom-step/s +93.5% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.21335 | 0.24947 | 0.30554 | 7.2 | 54.05 +Neigh | 0.0016861 | 0.0018238 | 0.0019357 | 0.2 | 0.40 +Comm | 0.078727 | 0.14542 | 0.19247 | 10.9 | 31.51 +Output | 0.00086191 | 0.0026451 | 0.0079866 | 6.0 | 0.57 +Modify | 0.028228 | 0.029642 | 0.030811 | 0.5 | 6.42 +Other | | 0.03255 | | | 7.05 + +Nlocal: 25 ave 28 max 21 min +Histogram: 1 0 0 0 0 1 0 1 0 1 +Nghost: 47.5 ave 50 max 46 min +Histogram: 2 0 0 0 0 1 0 0 0 1 +Neighs: 117.25 ave 144 max 91 min +Histogram: 1 0 0 1 0 0 1 0 0 1 + +Total # of neighbors = 469 +Ave neighs/atom = 4.69 +Neighbor list builds = 494 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/body/log.27Nov18.cubes.g++.1 b/examples/body/log.14Jun23.cubes.g++.1 similarity index 52% rename from examples/body/log.27Nov18.cubes.g++.1 rename to examples/body/log.14Jun23.cubes.g++.1 index 588f95f69d..4010d1013b 100644 --- a/examples/body/log.27Nov18.cubes.g++.1 +++ b/examples/body/log.14Jun23.cubes.g++.1 @@ -1,4 +1,4 @@ -LAMMPS (27 Nov 2018) +LAMMPS (28 Mar 2023 - Development) using 1 OpenMP thread(s) per MPI task # 3d rounded cubes @@ -11,20 +11,23 @@ dimension 3 atom_style body rounded/polyhedron 1 10 read_data data.cubes +Reading data file ... orthogonal box = (0 0 0) to (6 6 6) 1 by 1 by 1 MPI processor grid reading atoms ... 2 atoms 2 bodies + read_data CPU = 0.001 seconds replicate $r $r $r replicate 3 $r $r replicate 3 3 $r replicate 3 3 3 +Replication is creating a 3x3x3 = 27 times larger system... orthogonal box = (0 0 0) to (18 18 18) 1 by 1 by 1 MPI processor grid 54 atoms - Time spent = 0.000426769 secs + replicate CPU = 0.001 seconds velocity all create 1.2 187287 dist gaussian mom yes rot yes @@ -71,56 +74,57 @@ thermo 1000 run ${steps} run 10000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule Neighbor list info ... - update every 1 steps, delay 0 steps, check yes + update: every = 1 steps, delay = 0 steps, check = yes max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 3.9641 - ghost atom cutoff = 3.9641 - binsize = 1.98205, bins = 10 10 10 + master list distance cutoff = 3.9641016 + ghost atom cutoff = 3.9641016 + binsize = 1.9820508, bins = 10 10 10 1 neighbor lists, perpetual/occasional/extra = 1 0 0 (1) pair body/rounded/polyhedron, perpetual attributes: half, newton on pair build: half/bin/atomonly/newton - stencil: half/bin/3d/newton + stencil: half/bin/3d bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.953 | 4.953 | 4.953 Mbytes -Step KinEng PotEng TotEng c_p2 c_1_temp - 0 1.7666667 0 1.7666667 0.01090535 0.59439252 - 1000 3.1462962 0.17392649 3.3202227 0.02361912 1.1654694 - 2000 2.9311648 0.13836102 3.0695258 0.021748224 1.1950624 - 3000 3.090491 0.16511199 3.255603 0.018691142 1.23672 - 4000 2.7401565 0.17792155 2.9180781 0.015093853 1.1180839 - 5000 3.0880849 0.17587085 3.2639557 0.030563042 1.2831154 - 6000 3.2180776 0.19732251 3.4154001 0.028338151 1.258839 - 7000 2.9514882 0.25088882 3.202377 0.025296925 1.1746326 - 8000 3.0101226 0.28825968 3.2983823 0.027273454 1.2138056 - 9000 3.0164253 0.1901733 3.2065986 0.033228915 1.3095914 - 10000 2.3780401 0.34082434 2.7188644 0.031838531 1.0208679 -Loop time of 51.5779 on 1 procs for 10000 steps with 54 atoms +Per MPI rank memory allocation (min/avg/max) = 5.973 | 5.973 | 5.973 Mbytes + Step KinEng PotEng TotEng c_p2 c_1_temp + 0 1.7666667 0 1.7666667 0.01090535 0.59439252 + 1000 3.1462962 0.17392649 3.3202227 0.02361912 1.1654694 + 2000 2.9311648 0.13836102 3.0695258 0.021748224 1.1950624 + 3000 3.090491 0.16511199 3.255603 0.018691142 1.23672 + 4000 2.7401565 0.17792155 2.9180781 0.015093853 1.1180839 + 5000 3.0880849 0.17587085 3.2639557 0.030563042 1.2831154 + 6000 3.2180776 0.19732251 3.4154001 0.028338151 1.258839 + 7000 2.9514882 0.25088882 3.202377 0.025296925 1.1746326 + 8000 3.0101226 0.28825968 3.2983823 0.027273454 1.2138056 + 9000 3.0164253 0.1901733 3.2065986 0.033228915 1.3095914 + 10000 2.3780401 0.34082434 2.7188644 0.031838531 1.0208679 +Loop time of 33.0201 on 1 procs for 10000 steps with 54 atoms -Performance: 16751.376 tau/day, 193.882 timesteps/s +Performance: 26165.890 tau/day, 302.846 timesteps/s, 16.354 katom-step/s 99.8% CPU use with 1 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 51.377 | 51.377 | 51.377 | 0.0 | 99.61 -Neigh | 0.0063686 | 0.0063686 | 0.0063686 | 0.0 | 0.01 -Comm | 0.072127 | 0.072127 | 0.072127 | 0.0 | 0.14 -Output | 0.0002768 | 0.0002768 | 0.0002768 | 0.0 | 0.00 -Modify | 0.10849 | 0.10849 | 0.10849 | 0.0 | 0.21 -Other | | 0.01404 | | | 0.03 +Pair | 32.897 | 32.897 | 32.897 | 0.0 | 99.63 +Neigh | 0.0028124 | 0.0028124 | 0.0028124 | 0.0 | 0.01 +Comm | 0.034404 | 0.034404 | 0.034404 | 0.0 | 0.10 +Output | 0.00017643 | 0.00017643 | 0.00017643 | 0.0 | 0.00 +Modify | 0.078202 | 0.078202 | 0.078202 | 0.0 | 0.24 +Other | | 0.00767 | | | 0.02 -Nlocal: 54 ave 54 max 54 min +Nlocal: 54 ave 54 max 54 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 96 ave 96 max 96 min +Nghost: 96 ave 96 max 96 min Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 100 ave 100 max 100 min +Neighs: 100 ave 100 max 100 min Histogram: 1 0 0 0 0 0 0 0 0 0 Total # of neighbors = 100 -Ave neighs/atom = 1.85185 +Ave neighs/atom = 1.8518519 Neighbor list builds = 268 Dangerous builds = 0 -Total wall time: 0:00:51 +Total wall time: 0:00:33 diff --git a/examples/body/log.27Nov18.cubes.g++.4 b/examples/body/log.14Jun23.cubes.g++.4 similarity index 50% rename from examples/body/log.27Nov18.cubes.g++.4 rename to examples/body/log.14Jun23.cubes.g++.4 index f10a4c8a0a..1439af95a0 100644 --- a/examples/body/log.27Nov18.cubes.g++.4 +++ b/examples/body/log.14Jun23.cubes.g++.4 @@ -1,4 +1,4 @@ -LAMMPS (27 Nov 2018) +LAMMPS (28 Mar 2023 - Development) using 1 OpenMP thread(s) per MPI task # 3d rounded cubes @@ -11,20 +11,23 @@ dimension 3 atom_style body rounded/polyhedron 1 10 read_data data.cubes +Reading data file ... orthogonal box = (0 0 0) to (6 6 6) 1 by 2 by 2 MPI processor grid reading atoms ... 2 atoms 2 bodies + read_data CPU = 0.001 seconds replicate $r $r $r replicate 3 $r $r replicate 3 3 $r replicate 3 3 3 +Replication is creating a 3x3x3 = 27 times larger system... orthogonal box = (0 0 0) to (18 18 18) 1 by 2 by 2 MPI processor grid 54 atoms - Time spent = 0.000776052 secs + replicate CPU = 0.001 seconds velocity all create 1.2 187287 dist gaussian mom yes rot yes @@ -71,56 +74,57 @@ thermo 1000 run ${steps} run 10000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule Neighbor list info ... - update every 1 steps, delay 0 steps, check yes + update: every = 1 steps, delay = 0 steps, check = yes max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 3.9641 - ghost atom cutoff = 3.9641 - binsize = 1.98205, bins = 10 10 10 + master list distance cutoff = 3.9641016 + ghost atom cutoff = 3.9641016 + binsize = 1.9820508, bins = 10 10 10 1 neighbor lists, perpetual/occasional/extra = 1 0 0 (1) pair body/rounded/polyhedron, perpetual attributes: half, newton on pair build: half/bin/atomonly/newton - stencil: half/bin/3d/newton + stencil: half/bin/3d bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.879 | 5.068 | 5.256 Mbytes -Step KinEng PotEng TotEng c_p2 c_1_temp - 0 1.7666667 0 1.7666667 0.01090535 0.59439252 - 1000 3.1462962 0.17392649 3.3202227 0.02361912 1.1654694 - 2000 2.9311648 0.13836102 3.0695258 0.021748224 1.1950624 - 3000 3.090491 0.16511199 3.255603 0.018691142 1.23672 - 4000 2.7401565 0.17792155 2.9180781 0.015093853 1.1180839 - 5000 3.0880849 0.17587085 3.2639557 0.030563042 1.2831154 - 6000 3.2180776 0.19732251 3.4154001 0.028338151 1.258839 - 7000 2.9514882 0.25088882 3.202377 0.025296925 1.1746326 - 8000 3.0101226 0.28825968 3.2983823 0.027273454 1.2138056 - 9000 3.0164253 0.1901733 3.2065986 0.033228915 1.3095914 - 10000 2.3780401 0.34082434 2.7188644 0.031838531 1.0208679 -Loop time of 25.5798 on 4 procs for 10000 steps with 54 atoms +Per MPI rank memory allocation (min/avg/max) = 5.901 | 5.902 | 5.904 Mbytes + Step KinEng PotEng TotEng c_p2 c_1_temp + 0 1.7666667 0 1.7666667 0.01090535 0.59439252 + 1000 3.1462962 0.17392649 3.3202227 0.02361912 1.1654694 + 2000 2.9311648 0.13836102 3.0695258 0.021748224 1.1950624 + 3000 3.090491 0.16511199 3.255603 0.018691142 1.23672 + 4000 2.7401565 0.17792155 2.9180781 0.015093853 1.1180839 + 5000 3.0880849 0.17587085 3.2639557 0.030563042 1.2831154 + 6000 3.2180776 0.19732251 3.4154001 0.028338151 1.258839 + 7000 2.9514882 0.25088882 3.202377 0.025296925 1.1746326 + 8000 3.0101226 0.28825968 3.2983823 0.027273454 1.2138056 + 9000 3.0164253 0.1901733 3.2065986 0.033228915 1.3095914 + 10000 2.3780401 0.34082434 2.7188644 0.031838531 1.0208679 +Loop time of 16.4904 on 4 procs for 10000 steps with 54 atoms -Performance: 33776.718 tau/day, 390.934 timesteps/s -97.1% CPU use with 4 MPI tasks x 1 OpenMP threads +Performance: 52394.037 tau/day, 606.412 timesteps/s, 32.746 katom-step/s +95.4% CPU use with 4 MPI tasks x 1 OpenMP threads MPI task timing breakdown: Section | min time | avg time | max time |%varavg| %total --------------------------------------------------------------- -Pair | 9.256 | 13.423 | 24.653 | 177.1 | 52.47 -Neigh | 0.0021949 | 0.0024942 | 0.0031152 | 0.7 | 0.01 -Comm | 0.73678 | 11.948 | 16.096 | 187.4 | 46.71 -Output | 0.00023246 | 0.00041932 | 0.0009768 | 0.0 | 0.00 -Modify | 0.12505 | 0.15661 | 0.18165 | 6.0 | 0.61 -Other | | 0.04968 | | | 0.19 +Pair | 5.8583 | 8.5985 | 15.966 | 145.2 | 52.14 +Neigh | 0.00098311 | 0.0011219 | 0.0014163 | 0.5 | 0.01 +Comm | 0.39088 | 7.7607 | 10.504 | 152.9 | 47.06 +Output | 0.00016175 | 0.00044056 | 0.0012766 | 0.0 | 0.00 +Modify | 0.084729 | 0.094756 | 0.10558 | 2.8 | 0.57 +Other | | 0.0349 | | | 0.21 -Nlocal: 13.5 ave 17 max 9 min +Nlocal: 13.5 ave 17 max 9 min Histogram: 1 0 0 1 0 0 0 0 1 1 -Nghost: 63.5 ave 68 max 58 min +Nghost: 63.5 ave 68 max 58 min Histogram: 1 0 0 1 0 0 0 0 0 2 -Neighs: 25 ave 38 max 6 min +Neighs: 25 ave 38 max 6 min Histogram: 1 0 0 0 0 1 0 0 1 1 Total # of neighbors = 100 -Ave neighs/atom = 1.85185 +Ave neighs/atom = 1.8518519 Neighbor list builds = 268 Dangerous builds = 0 -Total wall time: 0:00:25 +Total wall time: 0:00:16 diff --git a/examples/body/log.14Jun23.pour3d.g++.1 b/examples/body/log.14Jun23.pour3d.g++.1 new file mode 100644 index 0000000000..3bca25ee6b --- /dev/null +++ b/examples/body/log.14Jun23.pour3d.g++.1 @@ -0,0 +1,148 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# pouring 3d rounded polyhedron bodies + +variable steps index 6000 + +units lj +boundary p p fm +comm_modify vel yes + +atom_style body rounded/polyhedron 1 8 +atom_modify map array + +region reg block 0 50 0 50 0 50 units box +create_box 4 reg +Created orthogonal box = (0 0 0) to (50 50 50) + 1 by 1 by 1 MPI processor grid + +variable cut_inner equal 0.5 +variable k_n equal 100 +variable k_na equal 5 +variable c_n equal 20 +variable c_t equal 5 +variable mu equal 0 +variable A_ua equal 1 + +pair_style body/rounded/polyhedron ${c_n} ${c_t} ${mu} ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 ${c_t} ${mu} ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 5 ${mu} ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 5 0 ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 5 0 1 ${cut_inner} +pair_style body/rounded/polyhedron 20 5 0 1 0.5 +pair_coeff * * ${k_n} ${k_na} +pair_coeff * * 100 ${k_na} +pair_coeff * * 100 5 + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +timestep 0.001 + +fix 1 all nve/body +fix 2 all gravity 1.0 spherical 0.0 -180.0 + +molecule object molecule.cube molecule.tetra toff 1 molecule.rod3d toff 2 molecule.point3d toff 3 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 1 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 2 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 3 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 4 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 + +region slab block 5 45 5 45 25 35 units box +fix ins all pour 500 0 4767548 vol 0.4 10 region slab mol object molfrac 0.25 0.25 0.25 0.25 +Particle insertion: 134 every 4472 steps, 500 by step 13417 + +fix 4 all wall/body/polyhedron 2000 50 50 zplane 0.0 NULL + +#compute 1 all body/local type 1 2 3 +#dump 1 all local 1000 dump.polyhedron index c_1[1] c_1[2] c_1[3] c_1[4] +#dump 10 all custom 1000 tmp.dump id type x y z radius + +thermo_style custom step atoms ke pe etotal press + +thermo 1000 + +#dump 2 all image 500 image.*.jpg type type # zoom 1.5 adiam 1.5 body type 0 0 view 75 15 +#dump_modify 2 pad 6 + +run ${steps} +run 6000 +Generated 0 of 6 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 5 + ghost atom cutoff = 5 + binsize = 2.5, bins = 20 20 20 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/rounded/polyhedron, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 0.508 | 0.508 | 0.508 Mbytes + Step Atoms KinEng PotEng TotEng Press + 0 0 -0 0 0 0 + 1000 134 -0 0.0038737172 0.0038737172 -3.395325e-06 + 2000 134 -0 -0.0009235483 -0.0009235483 -6.5977025e-07 + 3000 134 -0 0.004338364 0.004338364 -1.4565607e-05 + 4000 134 -0 0.0028464278 0.0028464278 -7.6723299e-06 + 5000 268 -0 0.017425002 0.017425002 0.000175191 + 6000 268 -0 0.035730061 0.035730061 0.00019697961 +Loop time of 0.432886 on 1 procs for 6000 steps with 268 atoms + +Performance: 1197543.331 tau/day, 13860.455 timesteps/s, 3.715 Matom-step/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.29261 | 0.29261 | 0.29261 | 0.0 | 67.59 +Neigh | 0.0040123 | 0.0040123 | 0.0040123 | 0.0 | 0.93 +Comm | 0.0019937 | 0.0019937 | 0.0019937 | 0.0 | 0.46 +Output | 5.8179e-05 | 5.8179e-05 | 5.8179e-05 | 0.0 | 0.01 +Modify | 0.12864 | 0.12864 | 0.12864 | 0.0 | 29.72 +Other | | 0.005574 | | | 1.29 + +Nlocal: 268 ave 268 max 268 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 2 ave 2 max 2 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 95 ave 95 max 95 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 95 +Ave neighs/atom = 0.35447761 +Neighbor list builds = 167 +Dangerous builds = 0 + + +Total wall time: 0:00:00 diff --git a/examples/body/log.14Jun23.pour3d.g++.4 b/examples/body/log.14Jun23.pour3d.g++.4 new file mode 100644 index 0000000000..5a8206b95a --- /dev/null +++ b/examples/body/log.14Jun23.pour3d.g++.4 @@ -0,0 +1,148 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# pouring 3d rounded polyhedron bodies + +variable steps index 6000 + +units lj +boundary p p fm +comm_modify vel yes + +atom_style body rounded/polyhedron 1 8 +atom_modify map array + +region reg block 0 50 0 50 0 50 units box +create_box 4 reg +Created orthogonal box = (0 0 0) to (50 50 50) + 1 by 2 by 2 MPI processor grid + +variable cut_inner equal 0.5 +variable k_n equal 100 +variable k_na equal 5 +variable c_n equal 20 +variable c_t equal 5 +variable mu equal 0 +variable A_ua equal 1 + +pair_style body/rounded/polyhedron ${c_n} ${c_t} ${mu} ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 ${c_t} ${mu} ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 5 ${mu} ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 5 0 ${A_ua} ${cut_inner} +pair_style body/rounded/polyhedron 20 5 0 1 ${cut_inner} +pair_style body/rounded/polyhedron 20 5 0 1 0.5 +pair_coeff * * ${k_n} ${k_na} +pair_coeff * * 100 ${k_na} +pair_coeff * * 100 5 + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +timestep 0.001 + +fix 1 all nve/body +fix 2 all gravity 1.0 spherical 0.0 -180.0 + +molecule object molecule.cube molecule.tetra toff 1 molecule.rod3d toff 2 molecule.point3d toff 3 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 1 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 2 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 3 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 +Read molecule template object: + 1 molecules + 0 fragments + 1 atoms with max type 4 + 0 bonds with max type 0 + 0 angles with max type 0 + 0 dihedrals with max type 0 + 0 impropers with max type 0 + +region slab block 5 45 5 45 25 35 units box +fix ins all pour 500 0 4767548 vol 0.4 10 region slab mol object molfrac 0.25 0.25 0.25 0.25 +Particle insertion: 134 every 4472 steps, 500 by step 13417 + +fix 4 all wall/body/polyhedron 2000 50 50 zplane 0.0 NULL + +#compute 1 all body/local type 1 2 3 +#dump 1 all local 1000 dump.polyhedron index c_1[1] c_1[2] c_1[3] c_1[4] +#dump 10 all custom 1000 tmp.dump id type x y z radius + +thermo_style custom step atoms ke pe etotal press + +thermo 1000 + +#dump 2 all image 500 image.*.jpg type type # zoom 1.5 adiam 1.5 body type 0 0 view 75 15 +#dump_modify 2 pad 6 + +run ${steps} +run 6000 +Generated 0 of 6 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 5 + ghost atom cutoff = 5 + binsize = 2.5, bins = 20 20 20 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/rounded/polyhedron, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 0.4666 | 0.4666 | 0.4666 Mbytes + Step Atoms KinEng PotEng TotEng Press + 0 0 -0 0 0 0 + 1000 134 -0 0.0038737172 0.0038737172 -3.395325e-06 + 2000 134 -0 -0.0009235483 -0.0009235483 -6.5977025e-07 + 3000 134 -0 0.004338364 0.004338364 -1.4565607e-05 + 4000 134 -0 0.0028464278 0.0028464278 -7.6723299e-06 + 5000 268 -0 0.017425002 0.017425002 0.000175191 + 6000 268 -0 0.035730061 0.035730061 0.00019697961 +Loop time of 0.266391 on 4 procs for 6000 steps with 268 atoms + +Performance: 1946012.521 tau/day, 22523.293 timesteps/s, 6.036 Matom-step/s +92.6% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.024599 | 0.072944 | 0.14627 | 18.6 | 27.38 +Neigh | 0.0011942 | 0.0013474 | 0.0014323 | 0.3 | 0.51 +Comm | 0.047438 | 0.11992 | 0.17106 | 14.8 | 45.02 +Output | 7.6297e-05 | 0.00017637 | 0.00044875 | 0.0 | 0.07 +Modify | 0.029377 | 0.035972 | 0.040396 | 2.4 | 13.50 +Other | | 0.03603 | | | 13.52 + +Nlocal: 67 ave 89 max 43 min +Histogram: 1 1 0 0 0 0 0 0 1 1 +Nghost: 38 ave 53 max 25 min +Histogram: 1 1 0 0 0 0 0 1 0 1 +Neighs: 23.75 ave 42 max 7 min +Histogram: 1 0 1 0 0 0 0 1 0 1 + +Total # of neighbors = 95 +Ave neighs/atom = 0.35447761 +Neighbor list builds = 167 +Dangerous builds = 0 + + +Total wall time: 0:00:00 diff --git a/examples/body/log.14Jun23.squares.g++.1 b/examples/body/log.14Jun23.squares.g++.1 new file mode 100644 index 0000000000..4588481dc6 --- /dev/null +++ b/examples/body/log.14Jun23.squares.g++.1 @@ -0,0 +1,226 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# 2d rounded polygon bodies + +variable r index 4 +variable steps index 100000 +variable T index 0.5 +variable P index 0.1 +variable seed index 980411 + +units lj +dimension 2 + +atom_style body rounded/polygon 1 6 +atom_modify map array +read_data data.squares +Reading data file ... + orthogonal box = (0 0 -0.5) to (12 12 0.5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 2 atoms + 2 bodies + read_data CPU = 0.001 seconds + +replicate $r $r 1 +replicate 4 $r 1 +replicate 4 4 1 +Replication is creating a 4x4x1 = 16 times larger system... + orthogonal box = (0 0 -0.5) to (48 48 0.5) + 1 by 1 by 1 MPI processor grid + 32 atoms + replicate CPU = 0.001 seconds + +velocity all create $T ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 980411 dist gaussian mom yes rot yes + +variable cut_inner equal 0.5 +variable k_n equal 100 +variable k_na equal 2 +variable c_n equal 1 +variable c_t equal 1 +variable mu equal 0.1 +variable delta_ua equal 0.5 + +pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 1 ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 1 0.1 ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 1 0.1 0.5 ${cut_inner} +pair_style body/rounded/polygon 1 1 0.1 0.5 0.5 +pair_coeff * * ${k_n} ${k_na} +pair_coeff * * 100 ${k_na} +pair_coeff * * 100 2 + +comm_modify vel yes + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +timestep 0.001 + +#fix 1 all nve/body +#fix 1 all nvt/body temp $T $T 1.0 +fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 0.1 1.0 couple xy fixedpoint 0 0 0 + +fix 2 all enforce2d + +#compute 1 all body/local id 1 2 3 +#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] + +thermo_style custom step ke pe etotal press +thermo 1000 + +#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 +#dump_modify 2 pad 6 + +run ${steps} +run 100000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.1568542 + ghost atom cutoff = 6.1568542 + binsize = 3.0784271, bins = 16 16 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/rounded/polygon, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 5.386 | 5.386 | 5.386 Mbytes + Step KinEng PotEng TotEng Press + 0 0.484375 0.25 0.734375 0.0067274306 + 1000 0.39720235 0.0015845731 0.39878692 0.00223489 + 2000 0.42893425 0.011718891 0.44065314 0.0027413224 + 3000 0.57823511 0.012407489 0.5906426 0.0025306081 + 4000 0.71610647 0.028149437 0.74425591 0.0016504948 + 5000 0.84027279 0.018917017 0.8591898 0.0037451875 + 6000 0.72410001 0.073495378 0.79759539 0.00018672875 + 7000 0.53886484 0.077723366 0.61658821 0.004729216 + 8000 0.66196054 0.05502242 0.71698296 0.0054997323 + 9000 0.93104065 0.071628784 1.0026694 0.011330629 + 10000 0.75494389 0.15204106 0.90698495 0.021702117 + 11000 0.72349154 0.11102332 0.83451486 0.019264158 + 12000 0.56216531 0.117059 0.67922431 -0.028295891 + 13000 0.63793498 0.11701868 0.75495366 0.029470631 + 14000 0.62996509 0.020871971 0.65083706 0.0086224023 + 15000 0.6403927 0.0091092209 0.64950192 0.016897685 + 16000 0.70288045 0.046856749 0.7497372 0.02312871 + 17000 0.6820593 0.038994474 0.72105377 0.0068705173 + 18000 0.75623543 0.0069908315 0.76322626 0.025170959 + 19000 0.85962145 0.059005169 0.91862661 0.012725758 + 20000 0.73334823 0.033043489 0.76639172 0.023661433 + 21000 0.60850654 0.081277767 0.68978431 0.021031136 + 22000 0.38251144 0.27624263 0.65875407 0.047336318 + 23000 0.4288127 0.30632792 0.73514062 0.034108416 + 24000 0.4452138 0.13179024 0.57700404 0.010303821 + 25000 0.48091107 0.1816109 0.66252197 0.021201342 + 26000 0.67970784 0.088616708 0.76832455 0.034997245 + 27000 0.8223642 0.08699442 0.90935862 0.023508839 + 28000 0.60062179 0.1119578 0.71257959 -0.0010008016 + 29000 0.54629437 0.1202995 0.66659387 0.040613547 + 30000 0.28102412 0.38657163 0.66759575 -0.0086538064 + 31000 0.12433474 0.18824131 0.31257605 0.049899211 + 32000 0.089510322 0.20890679 0.29841711 0.045555094 + 33000 0.12657665 0.17720119 0.30377784 0.028306214 + 34000 0.18400652 0.17677189 0.36077841 0.034628531 + 35000 0.24048631 0.11010844 0.35059475 0.029848365 + 36000 0.33435006 0.077341882 0.41169194 0.055963098 + 37000 0.46088842 0.1210638 0.58195222 0.072006022 + 38000 0.76551752 0.07037755 0.83589507 0.018204686 + 39000 0.89388464 0.080990198 0.97487484 0.038361105 + 40000 0.65618718 0.078644754 0.73483193 0.040567246 + 41000 0.47284043 0.16391389 0.63675432 0.027523843 + 42000 0.52454668 0.057988616 0.58253529 0.03122996 + 43000 0.78769394 0.08405077 0.87174471 0.044743697 + 44000 0.92932837 0.093922981 1.0232514 0.042510479 + 45000 0.5722596 0.17607834 0.74833794 0.034646914 + 46000 0.54352389 0.085652886 0.62917677 0.033203865 + 47000 0.45608912 0.25183842 0.70792754 0.08370224 + 48000 0.47530886 0.10106466 0.57637352 0.046113986 + 49000 0.67945305 0.0065249477 0.68597799 0.054743491 + 50000 0.49661922 0.097381596 0.59400082 0.006998965 + 51000 0.60992235 0.059017331 0.66893968 0.09445106 + 52000 0.69563455 0.18702969 0.88266424 0.034154598 + 53000 0.87598532 0.18260917 1.0585945 0.065734536 + 54000 0.58822846 0.27562038 0.86384884 0.0764045 + 55000 0.43454899 0.17174441 0.6062934 0.026434052 + 56000 0.4004495 0.12778644 0.52823594 0.065986005 + 57000 0.36272102 0.09849578 0.4612168 0.064217596 + 58000 0.40987214 0.21777618 0.62764832 0.058625636 + 59000 0.64813089 0.1479689 0.79609979 0.033378701 + 60000 0.90328265 0.11049926 1.0137819 0.055828397 + 61000 0.82921839 0.074638688 0.90385707 0.062488824 + 62000 0.63223087 0.094386302 0.72661718 0.054784559 + 63000 0.62946839 0.087807829 0.71727622 0.058398323 + 64000 0.79784108 0.094756776 0.89259786 0.065765914 + 65000 0.87500942 0.13514078 1.0101502 0.068123475 + 66000 0.66961949 0.19942965 0.86904914 0.065587832 + 67000 0.61612396 0.11436282 0.73048678 0.061233427 + 68000 0.74149449 0.03129016 0.77278465 0.072517897 + 69000 0.84060202 0.027261803 0.86786382 0.063374451 + 70000 0.78182528 0.023528774 0.80535405 0.07431822 + 71000 0.71611101 0.023512727 0.73962374 0.069575276 + 72000 0.68437263 0.023941199 0.70831382 0.069821154 + 73000 0.75652323 0.023580324 0.78010355 0.075046425 + 74000 0.92077658 0.023272419 0.944049 0.070992373 + 75000 0.75277766 0.023186631 0.77596429 0.074859227 + 76000 0.59333539 0.024276648 0.61761204 0.076132037 + 77000 0.68243436 0.024600726 0.70703508 0.075525977 + 78000 0.79699751 0.024238959 0.82123647 0.078255526 + 79000 0.77318109 0.024249895 0.79743099 0.078223339 + 80000 0.72004911 0.024522473 0.74457159 0.079009398 + 81000 0.71732947 0.024702988 0.74203245 0.080902007 + 82000 0.73395391 0.024817681 0.75877159 0.081203115 + 83000 0.74389794 0.02487774 0.76877568 0.082273058 + 84000 0.73219737 0.024967311 0.75716468 0.08359401 + 85000 0.66523255 0.025299293 0.69053184 0.084260931 + 86000 0.67031201 0.02564609 0.6959581 0.085495986 + 87000 0.81345283 0.025297963 0.8387508 0.086292085 + 88000 0.85008513 0.024879647 0.87496478 0.087116741 + 89000 0.62893149 0.025674927 0.65460642 0.088514693 + 90000 0.58336052 0.026632218 0.60999274 0.089459637 + 91000 0.72615388 0.026181899 0.75233578 0.090289473 + 92000 0.76593408 0.025893082 0.79182717 0.091294308 + 93000 0.73475998 0.026113022 0.76087301 0.092256366 + 94000 0.68995562 0.026409704 0.71636532 0.093332419 + 95000 0.69491284 0.026726159 0.721639 0.094314615 + 96000 0.83274635 0.026420125 0.85916648 0.09513317 + 97000 0.85486073 0.025941089 0.88080181 0.096122793 + 98000 0.63095894 0.027021709 0.65798064 0.097348373 + 99000 0.60847495 0.027908563 0.63638351 0.098362493 + 100000 0.75867487 0.027331375 0.78600625 0.099184572 +Loop time of 3.87848 on 1 procs for 100000 steps with 32 atoms + +Performance: 2227674.150 tau/day, 25783.266 timesteps/s, 825.065 katom-step/s +97.7% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 2.9048 | 2.9048 | 2.9048 | 0.0 | 74.90 +Neigh | 0.0027304 | 0.0027304 | 0.0027304 | 0.0 | 0.07 +Comm | 0.071653 | 0.071653 | 0.071653 | 0.0 | 1.85 +Output | 0.00069287 | 0.00069287 | 0.00069287 | 0.0 | 0.02 +Modify | 0.85771 | 0.85771 | 0.85771 | 0.0 | 22.11 +Other | | 0.04088 | | | 1.05 + +Nlocal: 32 ave 32 max 32 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 32 ave 32 max 32 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 57 ave 57 max 57 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 57 +Ave neighs/atom = 1.78125 +Neighbor list builds = 1379 +Dangerous builds = 0 +Total wall time: 0:00:03 diff --git a/examples/body/log.14Jun23.squares.g++.4 b/examples/body/log.14Jun23.squares.g++.4 new file mode 100644 index 0000000000..51f1a0c7e9 --- /dev/null +++ b/examples/body/log.14Jun23.squares.g++.4 @@ -0,0 +1,226 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# 2d rounded polygon bodies + +variable r index 4 +variable steps index 100000 +variable T index 0.5 +variable P index 0.1 +variable seed index 980411 + +units lj +dimension 2 + +atom_style body rounded/polygon 1 6 +atom_modify map array +read_data data.squares +Reading data file ... + orthogonal box = (0 0 -0.5) to (12 12 0.5) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 2 atoms + 2 bodies + read_data CPU = 0.001 seconds + +replicate $r $r 1 +replicate 4 $r 1 +replicate 4 4 1 +Replication is creating a 4x4x1 = 16 times larger system... + orthogonal box = (0 0 -0.5) to (48 48 0.5) + 2 by 2 by 1 MPI processor grid + 32 atoms + replicate CPU = 0.001 seconds + +velocity all create $T ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 980411 dist gaussian mom yes rot yes + +variable cut_inner equal 0.5 +variable k_n equal 100 +variable k_na equal 2 +variable c_n equal 1 +variable c_t equal 1 +variable mu equal 0.1 +variable delta_ua equal 0.5 + +pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 1 ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 1 0.1 ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 1 1 0.1 0.5 ${cut_inner} +pair_style body/rounded/polygon 1 1 0.1 0.5 0.5 +pair_coeff * * ${k_n} ${k_na} +pair_coeff * * 100 ${k_na} +pair_coeff * * 100 2 + +comm_modify vel yes + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +timestep 0.001 + +#fix 1 all nve/body +#fix 1 all nvt/body temp $T $T 1.0 +fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 0.1 1.0 couple xy fixedpoint 0 0 0 + +fix 2 all enforce2d + +#compute 1 all body/local id 1 2 3 +#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] + +thermo_style custom step ke pe etotal press +thermo 1000 + +#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 +#dump_modify 2 pad 6 + +run ${steps} +run 100000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.1568542 + ghost atom cutoff = 6.1568542 + binsize = 3.0784271, bins = 16 16 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/rounded/polygon, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 5.379 | 5.379 | 5.379 Mbytes + Step KinEng PotEng TotEng Press + 0 0.484375 0.25 0.734375 0.0067274306 + 1000 0.39720235 0.0015845731 0.39878692 0.00223489 + 2000 0.42893425 0.011718891 0.44065314 0.0027413224 + 3000 0.57823511 0.012407489 0.5906426 0.0025306081 + 4000 0.71610647 0.028149437 0.74425591 0.0016504948 + 5000 0.84027279 0.018917017 0.8591898 0.0037451875 + 6000 0.72410001 0.073495378 0.79759539 0.00018672875 + 7000 0.53886484 0.077723366 0.61658821 0.004729216 + 8000 0.66196054 0.05502242 0.71698296 0.0054997327 + 9000 0.93104065 0.071628784 1.0026694 0.011330629 + 10000 0.75494389 0.15204106 0.90698496 0.021702127 + 11000 0.72349155 0.11102332 0.83451487 0.019264192 + 12000 0.56216536 0.11705898 0.67922434 -0.028296196 + 13000 0.63793556 0.11701866 0.75495421 0.029469295 + 14000 0.62999448 0.020866813 0.65086129 0.008609569 + 15000 0.6404504 0.0090011224 0.64945152 0.01706906 + 16000 0.70195749 0.044735201 0.74669269 0.0179597 + 17000 0.69097976 0.03894214 0.72992191 0.015704476 + 18000 0.75303457 0.0019263825 0.75496095 0.021536711 + 19000 0.6459718 0.10419136 0.75016317 0.033861092 + 20000 0.73026363 0.13023974 0.86050337 0.022207497 + 21000 0.77107035 0.30464112 1.0757115 0.013967631 + 22000 0.44134768 0.22883887 0.67018655 0.014202518 + 23000 0.53410601 0.16702381 0.70112983 0.009305779 + 24000 0.5144312 0.19041122 0.70484242 -0.0059836303 + 25000 0.60922681 0.15475207 0.76397888 0.016370526 + 26000 0.70922367 0.25374443 0.9629681 0.027301754 + 27000 0.67289133 0.39287626 1.0657676 0.025562031 + 28000 0.62112601 0.017177715 0.63830372 0.018556767 + 29000 0.56492546 0.087573524 0.65249898 0.025132036 + 30000 0.62612507 -0.01835118 0.60777389 0.050139664 + 31000 0.69157641 0.064849873 0.75642628 0.033954585 + 32000 0.72648211 0.08597545 0.81245756 0.038082388 + 33000 0.58608821 0.13013111 0.71621932 0.054766043 + 34000 0.49330983 0.080490598 0.57380043 0.034154681 + 35000 0.54570666 0.075020466 0.62072713 0.03879264 + 36000 0.60305736 0.10717781 0.71023516 0.030701059 + 37000 0.52801767 0.12516316 0.65318083 0.007411688 + 38000 0.5838277 0.12569072 0.70951842 0.03272916 + 39000 0.53999819 0.043261294 0.58325949 0.084115917 + 40000 0.64957099 0.040023268 0.68959426 0.027021958 + 41000 0.59235949 0.10449793 0.69685742 0.045773377 + 42000 0.71752786 0.043289363 0.76081722 0.040926021 + 43000 0.78581005 0.024363927 0.81017398 0.034694164 + 44000 0.6396541 0.06004252 0.69969662 0.037227348 + 45000 0.35753293 0.11456039 0.47209332 0.033569048 + 46000 0.11031158 0.11831834 0.22862991 0.076545681 + 47000 0.11720754 0.035471414 0.15267896 0.022093929 + 48000 0.13370328 0.031802339 0.16550562 0.053298269 + 49000 0.2700883 0.15584422 0.42593252 0.057108168 + 50000 0.53837779 0.13398219 0.67235998 0.047704986 + 51000 0.38133073 0.011372933 0.39270366 0.04696367 + 52000 0.32448241 0.009137008 0.33361942 0.033573259 + 53000 0.25798301 -0.016530605 0.2414524 0.04623663 + 54000 0.2842707 0.054504088 0.33877479 0.03751156 + 55000 0.28895106 0.025307766 0.31425882 0.03935955 + 56000 0.19130753 0.099678989 0.29098652 0.051888728 + 57000 0.12237303 0.057536458 0.17990949 0.09984021 + 58000 0.17962003 0.012450682 0.19207072 0.028644351 + 59000 0.21667262 -0.013693164 0.20297945 0.048086277 + 60000 0.4298123 -0.012970819 0.41684148 0.019347498 + 61000 0.69591654 -0.027048452 0.66886809 0.069793861 + 62000 1.0040382 -0.044228622 0.95980957 0.056563167 + 63000 0.78189663 -0.053045577 0.72885106 0.059491526 + 64000 0.57051419 -0.050757181 0.51975701 0.061863162 + 65000 0.62584243 -0.050616328 0.5752261 0.068924362 + 66000 0.85558894 -0.051396155 0.80419278 0.059309337 + 67000 0.86314978 -0.052635701 0.81051408 0.071855924 + 68000 0.65427495 -0.05147951 0.60279544 0.064001735 + 69000 0.60658011 -0.050623824 0.55595629 0.0715805 + 70000 0.76353932 -0.050863795 0.71267553 0.06771349 + 71000 0.87559332 -0.051720153 0.82387317 0.071884106 + 72000 0.71924774 -0.051167456 0.66808029 0.071010747 + 73000 0.6100998 -0.050025233 0.56007457 0.073319802 + 74000 0.71838075 -0.049907287 0.66847346 0.07314982 + 75000 0.91863251 -0.051069435 0.86756308 0.07493433 + 76000 0.78459189 -0.050803207 0.73378868 0.075397431 + 77000 0.70827012 -0.049701237 0.65856888 0.076901086 + 78000 0.72333497 -0.04940986 0.67392511 0.077456938 + 79000 0.76543474 -0.049588137 0.7158466 0.078792278 + 80000 0.77759003 -0.049596899 0.72799313 0.079470668 + 81000 0.67474562 -0.048929658 0.62581596 0.080740407 + 82000 0.60162355 -0.047698966 0.55392459 0.081758686 + 83000 0.7602675 -0.047827179 0.71244032 0.082547083 + 84000 0.9061851 -0.049481366 0.85670374 0.083443845 + 85000 0.74071256 -0.048645397 0.69206717 0.084605474 + 86000 0.67634638 -0.046894309 0.62945207 0.085608904 + 87000 0.71669859 -0.046524067 0.67017453 0.086561551 + 88000 0.77025498 -0.047090994 0.72316398 0.087515495 + 89000 0.76590655 -0.047083362 0.71882319 0.088522842 + 90000 0.61372503 -0.045529779 0.56819526 0.08963777 + 91000 0.58583927 -0.043777544 0.54206173 0.093090208 + 92000 0.80507421 -0.04423346 0.76084075 0.093861418 + 93000 0.84631942 -0.046878171 0.79944125 0.093279847 + 94000 0.70915593 -0.04570489 0.66345104 0.092425564 + 95000 0.66813988 -0.043460537 0.62467934 0.093467021 + 96000 0.71739316 -0.042402374 0.67499079 0.095183179 + 97000 0.74132854 -0.042457291 0.69887124 0.096665917 + 98000 0.74033914 -0.042269007 0.69807013 0.097869908 + 99000 0.72447372 -0.041519159 0.68295457 0.098825459 + 100000 0.6968193 -0.040321034 0.65649827 0.099797629 +Loop time of 2.55809 on 4 procs for 100000 steps with 32 atoms + +Performance: 3377521.712 tau/day, 39091.686 timesteps/s, 1.251 Matom-step/s +91.9% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.53547 | 0.78258 | 1.0169 | 21.0 | 30.59 +Neigh | 0.0010868 | 0.0011973 | 0.0013608 | 0.3 | 0.05 +Comm | 0.57019 | 0.78963 | 1.0091 | 19.2 | 30.87 +Output | 0.00075581 | 0.0030547 | 0.0098741 | 7.1 | 0.12 +Modify | 0.80723 | 0.81855 | 0.83849 | 1.3 | 32.00 +Other | | 0.1631 | | | 6.37 + +Nlocal: 8 ave 12 max 2 min +Histogram: 1 0 0 0 0 0 1 0 1 1 +Nghost: 15.25 ave 19 max 13 min +Histogram: 1 1 0 1 0 0 0 0 0 1 +Neighs: 12 ave 18 max 1 min +Histogram: 1 0 0 0 0 0 0 1 1 1 + +Total # of neighbors = 48 +Ave neighs/atom = 1.5 +Neighbor list builds = 1420 +Dangerous builds = 0 +Total wall time: 0:00:02 diff --git a/examples/body/log.14Jun23.wall2d.g++.1 b/examples/body/log.14Jun23.wall2d.g++.1 new file mode 100644 index 0000000000..dd54f37c03 --- /dev/null +++ b/examples/body/log.14Jun23.wall2d.g++.1 @@ -0,0 +1,229 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# 2d rounded polygon bodies + +variable r index 4 +variable steps index 100000 +variable T index 0.5 +variable P index 0.1 +variable seed index 980411 + +units lj +dimension 2 + +atom_style body rounded/polygon 1 6 +atom_modify map array +read_data data.squares +Reading data file ... + orthogonal box = (0 0 -0.5) to (12 12 0.5) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 2 atoms + 2 bodies + read_data CPU = 0.001 seconds + +replicate $r $r 1 +replicate 4 $r 1 +replicate 4 4 1 +Replication is creating a 4x4x1 = 16 times larger system... + orthogonal box = (0 0 -0.5) to (48 48 0.5) + 1 by 1 by 1 MPI processor grid + 32 atoms + replicate CPU = 0.001 seconds + +velocity all create $T ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 980411 dist gaussian mom yes rot yes + +change_box all boundary p f p +Changing box ... + +variable cut_inner equal 0.5 +variable k_n equal 100 +variable k_na equal 2 +variable c_n equal 0.1 +variable c_t equal 0.1 +variable mu equal 0.1 +variable delta_ua equal 0.5 + +pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 0.1 ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 0.5 +pair_coeff * * ${k_n} ${k_na} +pair_coeff * * 100 ${k_na} +pair_coeff * * 100 2 + +comm_modify vel yes + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +timestep 0.001 + +#fix 1 all nve/body +#fix 1 all nvt/body temp $T $T 1.0 +fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 fixedpoint 0 0 0 + +fix 2 all enforce2d +fix 3 all wall/body/polygon 2000 50 50 yplane 0.0 48.0 + +#compute 1 all body/local id 1 2 3 +#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] + +thermo_style custom step ke pe etotal press +thermo 1000 + +#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 +#dump_modify 2 pad 6 + +run ${steps} +run 100000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.1568542 + ghost atom cutoff = 6.1568542 + binsize = 3.0784271, bins = 16 16 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/rounded/polygon, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 5.376 | 5.376 | 5.376 Mbytes + Step KinEng PotEng TotEng Press + 0 0.484375 0.25 0.734375 0.0067274306 + 1000 0.51464289 0.00099012638 0.51563301 0.013444625 + 2000 0.55653313 0.0040982283 0.56063136 0.0034505512 + 3000 0.75323998 0.023578898 0.77681887 0.0036652891 + 4000 0.70044978 0.092406287 0.79285607 0.0089262842 + 5000 0.54548803 0.096501313 0.64198934 0.0051379523 + 6000 0.48208829 0.097798861 0.57988715 0.015298049 + 7000 0.68219182 0.038843941 0.72103576 0.016842202 + 8000 0.53792445 0.012983807 0.55090825 0.0066797902 + 9000 0.49980359 0.029397948 0.52920154 0.0046731993 + 10000 0.48705779 0.10138799 0.58844578 -1.9696743e-05 + 11000 0.52151792 0.065893508 0.58741142 0.0049365175 + 12000 0.59066419 0.039261015 0.62992521 0.001420608 + 13000 0.46059009 0.07386532 0.53445541 0.005654565 + 14000 0.37899234 0.13421331 0.51320565 0.0097199047 + 15000 0.49566894 0.052006844 0.54767578 0.00053157628 + 16000 0.59294062 0.028393451 0.62133407 0.0057809461 + 17000 0.51260882 0.1266054 0.63921422 0.0021637817 + 18000 0.45603179 0.15710959 0.61314138 0.017707488 + 19000 0.52137969 0.1123825 0.63376219 0.015894031 + 20000 0.64553686 0.11579772 0.76133459 0.013239309 + 21000 0.38581837 0.17867419 0.56449256 0.0048572535 + 22000 0.42776514 0.12979071 0.55755585 0.008093469 + 23000 0.490055 0.14197765 0.63203265 -0.003575896 + 24000 0.57689881 0.10164831 0.67854712 0.022418321 + 25000 0.45630031 0.057905852 0.51420616 0.007959034 + 26000 0.59497685 0.193113 0.78808985 0.0076331679 + 27000 0.40943362 0.098595954 0.50802958 0.0016863757 + 28000 0.34512273 0.15696637 0.50208909 0.037435926 + 29000 0.59187862 0.1845377 0.77641632 0.014563665 + 30000 0.69204623 0.16392147 0.8559677 0.031708423 + 31000 0.40436029 0.34429435 0.74865464 0.073818847 + 32000 0.47580383 0.22708448 0.70288831 0.015795198 + 33000 0.48923447 0.23636413 0.72559861 0.025932606 + 34000 0.51960128 0.15145893 0.67106021 -0.00079607564 + 35000 0.44792834 0.19927109 0.64719943 -0.0063461505 + 36000 0.54265821 0.17924788 0.72190609 0.017916439 + 37000 0.56020344 0.24977507 0.80997851 0.057844411 + 38000 0.28874871 0.21399353 0.50274224 0.022675277 + 39000 0.39030236 0.30170176 0.69200411 0.037482614 + 40000 0.4699469 0.20663643 0.67658333 -0.014082215 + 41000 0.50202447 0.21510708 0.71713155 -0.0063284222 + 42000 0.43029593 0.23511818 0.6654141 0.046478372 + 43000 0.41628842 0.21031596 0.62660438 -0.0053073644 + 44000 0.51101573 0.15862165 0.66963738 0.010251868 + 45000 0.56984114 0.18071709 0.75055823 0.021333409 + 46000 0.45510513 0.15385488 0.60896001 0.048441048 + 47000 0.41229547 0.20577222 0.61806769 0.027485704 + 48000 0.64114797 0.33672519 0.97787315 0.13522091 + 49000 0.44298056 0.27708867 0.72006923 0.026660315 + 50000 0.43250082 0.17778506 0.61028588 0.02714938 + 51000 0.59697891 0.25460003 0.85157894 0.026959715 + 52000 0.63110331 0.21528376 0.84638707 0.023157155 + 53000 0.46085491 0.25375607 0.71461099 0.024933391 + 54000 0.50772891 0.29280628 0.80053519 0.010621547 + 55000 0.67213557 0.2071375 0.87927307 0.061770903 + 56000 0.61184167 0.34686662 0.95870829 0.095262009 + 57000 0.42364554 0.29899934 0.72264488 -0.0080865129 + 58000 0.5033641 0.39810693 0.90147103 0.081474225 + 59000 0.61363438 0.25296035 0.86659472 0.041921315 + 60000 0.64600872 0.36997737 1.0159861 0.053833686 + 61000 0.43392277 0.29276613 0.7266889 0.054911225 + 62000 0.38910577 0.27714798 0.66625375 -0.0141031 + 63000 0.42343097 0.21637816 0.63980913 -1.6862315e-05 + 64000 0.52512516 0.38797726 0.91310242 0.03170217 + 65000 0.48930994 0.4863269 0.97563684 0.025108671 + 66000 0.68354817 0.3629732 1.0465214 0.066714362 + 67000 0.5361863 0.44003399 0.97622029 0.1063525 + 68000 0.3605148 0.40138904 0.76190383 0.03287684 + 69000 0.62747502 0.49229352 1.1197685 0.053648724 + 70000 0.51326037 0.36561885 0.87887922 0.070871008 + 71000 0.45429341 0.38458357 0.83887698 0.010485881 + 72000 0.55377877 0.36434231 0.91812107 0.10507819 + 73000 0.6857324 0.45242968 1.1381621 0.022470322 + 74000 0.46349397 0.39082798 0.85432196 0.067650912 + 75000 0.59216869 0.32893138 0.92110008 0.0196582 + 76000 0.42985327 0.40674342 0.83659669 0.025700762 + 77000 0.54319568 0.55627833 1.099474 0.067233159 + 78000 0.59244798 0.5121155 1.1045635 0.12063624 + 79000 0.61140864 0.45505083 1.0664595 0.088578795 + 80000 0.64308346 0.4143502 1.0574337 0.038537249 + 81000 0.55053046 0.43357659 0.98410705 0.053930256 + 82000 0.54049882 0.41354335 0.95404217 -0.036458392 + 83000 0.47517728 0.30128468 0.77646196 0.0019488841 + 84000 0.57452781 0.1949493 0.76947711 0.039244382 + 85000 0.7907368 0.51406164 1.3047984 0.12766082 + 86000 0.59488507 0.50084726 1.0957323 0.080232158 + 87000 0.43071262 0.4682738 0.89898642 0.1266876 + 88000 0.53305256 0.55941308 1.0924656 0.17062068 + 89000 0.60672487 0.64951209 1.256237 0.17194524 + 90000 0.7134227 0.57323404 1.2866567 0.074617282 + 91000 0.65670871 0.58567381 1.2423825 0.025281565 + 92000 0.72364891 0.59755693 1.3212058 0.092201188 + 93000 0.69254418 0.75766186 1.450206 0.16036111 + 94000 0.56326058 0.6398442 1.2031048 0.26280736 + 95000 0.47480145 0.57734551 1.052147 0.039940021 + 96000 0.56909151 0.73081903 1.2999105 0.030223516 + 97000 0.53198039 0.71808155 1.2500619 0.033191485 + 98000 0.63572731 0.86931519 1.5050425 0.20901135 + 99000 0.64477038 0.76771721 1.4124876 0.059732095 + 100000 0.71275398 0.66613673 1.3788907 0.020038364 +Loop time of 2.21223 on 1 procs for 100000 steps with 32 atoms + +Performance: 3905566.671 tau/day, 45203.318 timesteps/s, 1.447 Matom-step/s +96.4% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 1.1162 | 1.1162 | 1.1162 | 0.0 | 50.45 +Neigh | 0.0049629 | 0.0049629 | 0.0049629 | 0.0 | 0.22 +Comm | 0.045069 | 0.045069 | 0.045069 | 0.0 | 2.04 +Output | 0.00060169 | 0.00060169 | 0.00060169 | 0.0 | 0.03 +Modify | 1.0017 | 1.0017 | 1.0017 | 0.0 | 45.28 +Other | | 0.04368 | | | 1.97 + +Nlocal: 32 ave 32 max 32 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 19 ave 19 max 19 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 59 ave 59 max 59 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 59 +Ave neighs/atom = 1.84375 +Neighbor list builds = 3214 +Dangerous builds = 0 +Total wall time: 0:00:02 diff --git a/examples/body/log.14Jun23.wall2d.g++.4 b/examples/body/log.14Jun23.wall2d.g++.4 new file mode 100644 index 0000000000..0d0005c6ef --- /dev/null +++ b/examples/body/log.14Jun23.wall2d.g++.4 @@ -0,0 +1,229 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# 2d rounded polygon bodies + +variable r index 4 +variable steps index 100000 +variable T index 0.5 +variable P index 0.1 +variable seed index 980411 + +units lj +dimension 2 + +atom_style body rounded/polygon 1 6 +atom_modify map array +read_data data.squares +Reading data file ... + orthogonal box = (0 0 -0.5) to (12 12 0.5) + 2 by 2 by 1 MPI processor grid + reading atoms ... + 2 atoms + 2 bodies + read_data CPU = 0.001 seconds + +replicate $r $r 1 +replicate 4 $r 1 +replicate 4 4 1 +Replication is creating a 4x4x1 = 16 times larger system... + orthogonal box = (0 0 -0.5) to (48 48 0.5) + 2 by 2 by 1 MPI processor grid + 32 atoms + replicate CPU = 0.001 seconds + +velocity all create $T ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 ${seed} dist gaussian mom yes rot yes +velocity all create 0.5 980411 dist gaussian mom yes rot yes + +change_box all boundary p f p +Changing box ... + +variable cut_inner equal 0.5 +variable k_n equal 100 +variable k_na equal 2 +variable c_n equal 0.1 +variable c_t equal 0.1 +variable mu equal 0.1 +variable delta_ua equal 0.5 + +pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 ${c_t} ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 ${mu} ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 0.1 ${delta_ua} ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 ${cut_inner} +pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 0.5 +pair_coeff * * ${k_n} ${k_na} +pair_coeff * * 100 ${k_na} +pair_coeff * * 100 2 + +comm_modify vel yes + +neighbor 0.5 bin +neigh_modify every 1 delay 0 check yes + +timestep 0.001 + +#fix 1 all nve/body +#fix 1 all nvt/body temp $T $T 1.0 +fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 +fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 fixedpoint 0 0 0 + +fix 2 all enforce2d +fix 3 all wall/body/polygon 2000 50 50 yplane 0.0 48.0 + +#compute 1 all body/local id 1 2 3 +#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] + +thermo_style custom step ke pe etotal press +thermo 1000 + +#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 +#dump_modify 2 pad 6 + +run ${steps} +run 100000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 6.1568542 + ghost atom cutoff = 6.1568542 + binsize = 3.0784271, bins = 16 16 1 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair body/rounded/polygon, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/2d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 5.378 | 5.378 | 5.379 Mbytes + Step KinEng PotEng TotEng Press + 0 0.484375 0.25 0.734375 0.0067274306 + 1000 0.51464289 0.00099012638 0.51563301 0.013444625 + 2000 0.55653313 0.0040982283 0.56063136 0.0034505512 + 3000 0.75323998 0.023578898 0.77681887 0.0036652891 + 4000 0.70044978 0.092406287 0.79285607 0.0089262842 + 5000 0.54548803 0.096501313 0.64198934 0.0051379522 + 6000 0.48208828 0.097798868 0.57988715 0.01529805 + 7000 0.68219182 0.038843949 0.72103577 0.016842202 + 8000 0.53792445 0.01298383 0.55090828 0.0066797984 + 9000 0.49980358 0.029397965 0.52920155 0.0046731992 + 10000 0.48705755 0.10138831 0.58844586 -1.9690665e-05 + 11000 0.52151879 0.065897951 0.58741674 0.0049324908 + 12000 0.59065198 0.03929683 0.62994881 0.0014198454 + 13000 0.46076897 0.073363984 0.53413295 0.0057849056 + 14000 0.38058168 0.16336914 0.54395082 0.0099910111 + 15000 0.58924494 0.13219579 0.72144074 0.012781632 + 16000 0.65163924 0.10979538 0.76143462 0.015088945 + 17000 0.51431594 0.036344433 0.55066037 0.001446035 + 18000 0.42677394 0.093297234 0.52007117 0.00093775852 + 19000 0.62399853 0.13309136 0.75708989 0.0095351169 + 20000 0.52835966 0.085936455 0.61429611 0.013158115 + 21000 0.42999051 0.12857394 0.55856445 0.024369485 + 22000 0.56770038 0.19738636 0.76508675 0.024211788 + 23000 0.55137392 0.18212359 0.7334975 0.024095463 + 24000 0.6225794 0.13091248 0.75349189 0.032707954 + 25000 0.47106345 0.10241626 0.57347971 0.0059731265 + 26000 0.60567231 0.055894222 0.66156653 0.010614697 + 27000 0.49075416 0.13914345 0.62989761 0.00048442735 + 28000 0.48902573 0.21423204 0.70325777 0.021295043 + 29000 0.42728391 0.24136135 0.66864527 0.031633766 + 30000 0.64658635 0.15368867 0.80027502 0.0084616839 + 31000 0.71370199 0.18014549 0.89384748 0.02367184 + 32000 0.40141173 0.1833294 0.58474113 0.034918949 + 33000 0.55780706 0.14130843 0.69911549 0.012266172 + 34000 0.36544303 0.15788143 0.52332446 0.0084938225 + 35000 0.56844142 0.17507842 0.74351984 0.061506713 + 36000 0.5048707 0.15834563 0.66321633 0.0286909 + 37000 0.4371274 0.087735559 0.52486296 -0.0016289252 + 38000 0.49941117 0.22576207 0.72517324 0.059233327 + 39000 0.69480051 0.15465372 0.84945423 0.039061293 + 40000 0.52881719 0.29110071 0.8199179 0.032439208 + 41000 0.56931201 0.38596881 0.95528082 0.045284803 + 42000 0.46759969 0.21337568 0.68097537 0.086759715 + 43000 0.63416318 0.44687151 1.0810347 0.072272415 + 44000 0.43914666 0.20832735 0.64747401 0.026280272 + 45000 0.38329718 0.25407815 0.63737533 0.017356403 + 46000 0.59511045 0.32148788 0.91659833 -0.0076184601 + 47000 0.50635988 0.37243112 0.878791 0.025435347 + 48000 0.42316224 0.29368731 0.71684954 0.00067040329 + 49000 0.40194259 0.26659105 0.66853364 0.069225504 + 50000 0.4740342 0.305674 0.77970819 0.014813566 + 51000 0.57279011 0.32080139 0.8935915 0.0091332017 + 52000 0.54543481 0.34482955 0.89026435 -0.021131696 + 53000 0.39241519 0.36432403 0.75673922 0.0077163816 + 54000 0.62021406 0.32010094 0.940315 0.044477965 + 55000 0.45160485 0.29442122 0.74602607 0.02563201 + 56000 0.41737028 0.31207675 0.72944704 0.050342936 + 57000 0.53454189 0.29192181 0.8264637 0.068452573 + 58000 0.65449932 0.33567481 0.99017413 0.055352019 + 59000 0.58742699 0.37317432 0.96060131 0.012805462 + 60000 0.42430458 0.33744246 0.76174704 0.018744436 + 61000 0.65433333 0.40723506 1.0615684 0.019757611 + 62000 0.64472397 0.34658649 0.99131047 0.090688735 + 63000 0.65381774 0.47452792 1.1283457 0.2090513 + 64000 0.44107995 0.60507044 1.0461504 0.03144844 + 65000 0.38159186 0.45527276 0.83686462 0.090856608 + 66000 0.48842595 0.49445721 0.98288316 0.08753844 + 67000 0.65088575 0.4611542 1.11204 0.066602605 + 68000 0.5155131 0.38693864 0.90245174 0.0062596909 + 69000 0.41477899 0.45120406 0.86598306 0.037396561 + 70000 0.60305022 0.47624271 1.0792929 0.040607751 + 71000 0.67077877 0.51044906 1.1812278 0.029084971 + 72000 0.50912034 0.34340114 0.85252148 0.055767674 + 73000 0.55167778 0.43795801 0.98963579 0.083371911 + 74000 0.53603549 0.37357862 0.90961411 0.058762722 + 75000 0.47521522 0.529749 1.0049642 0.12419171 + 76000 0.48952134 0.63953611 1.1290574 0.09709472 + 77000 0.63445283 0.57542295 1.2098758 0.11868116 + 78000 0.62184463 0.60025138 1.222096 0.079417229 + 79000 0.52715665 0.54847579 1.0756324 0.033981154 + 80000 0.6264593 0.39323366 1.019693 0.05627332 + 81000 0.78582235 0.47541992 1.2612423 0.031287815 + 82000 0.69665491 0.58355423 1.2802091 -0.04433392 + 83000 0.4994351 0.40089694 0.90033204 -0.0019687817 + 84000 0.50932093 0.62716285 1.1364838 0.095177695 + 85000 0.56251638 0.56010929 1.1226257 0.013989132 + 86000 0.67155822 0.51326814 1.1848264 0.10616402 + 87000 0.61317511 0.52704394 1.140219 0.076578899 + 88000 0.57436568 0.60641096 1.1807766 0.042050421 + 89000 0.62350614 0.65896923 1.2824754 0.15949038 + 90000 0.57445242 0.65085438 1.2253068 0.034123951 + 91000 0.50043488 0.69213026 1.1925651 -0.076403957 + 92000 0.57345231 0.74801993 1.3214722 0.033715387 + 93000 0.63056204 0.64474627 1.2753083 0.051205732 + 94000 0.70948937 0.61081243 1.3203018 -0.0069457836 + 95000 0.66048722 0.61001641 1.2705036 0.16072266 + 96000 0.48720026 0.64888522 1.1360855 0.12573765 + 97000 0.41570988 0.68810987 1.1038198 -0.033070846 + 98000 0.53689925 0.83787736 1.3747766 0.098173219 + 99000 0.5147061 0.92360546 1.4383116 0.12155736 + 100000 0.5793939 0.63393822 1.2133321 0.090967465 +Loop time of 2.08698 on 4 procs for 100000 steps with 32 atoms + +Performance: 4139957.491 tau/day, 47916.175 timesteps/s, 1.533 Matom-step/s +92.1% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.31 | 0.33594 | 0.35254 | 2.8 | 16.10 +Neigh | 0.001991 | 0.0021241 | 0.0022581 | 0.2 | 0.10 +Comm | 0.40717 | 0.43106 | 0.46731 | 3.4 | 20.65 +Output | 0.00076842 | 0.002908 | 0.0092082 | 6.7 | 0.14 +Modify | 1.1389 | 1.1624 | 1.1753 | 1.3 | 55.70 +Other | | 0.1525 | | | 7.31 + +Nlocal: 8 ave 9 max 7 min +Histogram: 2 0 0 0 0 0 0 0 0 2 +Nghost: 14 ave 16 max 12 min +Histogram: 1 0 1 0 0 0 0 1 0 1 +Neighs: 13.25 ave 17 max 11 min +Histogram: 1 1 0 1 0 0 0 0 0 1 + +Total # of neighbors = 53 +Ave neighs/atom = 1.65625 +Neighbor list builds = 3000 +Dangerous builds = 0 +Total wall time: 0:00:02 diff --git a/examples/body/log.27Nov18.body.g++.1 b/examples/body/log.27Nov18.body.g++.1 deleted file mode 100644 index adb2c5dd6f..0000000000 --- a/examples/body/log.27Nov18.body.g++.1 +++ /dev/null @@ -1,177 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# 2d polygon nparticle bodies - -units lj -dimension 2 -atom_style body nparticle 2 6 - -read_data data.body - orthogonal box = (-15.5322 -15.5322 -0.5) to (15.5322 15.5322 0.5) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 100 atoms - 100 bodies - -velocity all create 1.44 87287 loop geom - -pair_style body/nparticle 5.0 -pair_coeff * * 1.0 1.0 - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -fix 1 all nve/body -#fix 1 all nvt/body temp 1.44 1.44 1.0 -fix 2 all enforce2d - -#compute 1 all body/local type 1 2 3 -#dump 1 all local 100 dump.body index c_1[1] c_1[2] c_1[3] c_1[4] - -#dump 2 all image 1000 image.*.jpg type type # zoom 1.6 adiam 1.5 body type 1.0 0 -#dump_modify 2 pad 5 - -thermo 100 -run 10000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 5.5 - ghost atom cutoff = 5.5 - binsize = 2.75, bins = 12 12 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair body/nparticle, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.772 | 4.772 | 4.772 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 1.44 -0.63799525 0 0.78760475 -0.15028724 - 100 1.642337 -1.0003869 0 0.62552682 0.16140818 - 200 1.470473 -1.2465469 0 0.20922135 0.35146925 - 300 1.4834687 -1.3464946 0 0.12213946 0.40783535 - 400 1.5075814 -1.6170041 0 -0.12449852 0.11302717 - 500 1.5681124 -1.6060641 0 -0.053632801 0.23819933 - 600 1.7129405 -1.6939468 0 0.0018642497 0.46490776 - 700 1.5803869 -1.6182998 0 -0.053716823 0.36807869 - 800 1.6454324 -1.6537709 0 -0.024792836 0.21305673 - 900 1.5454528 -1.6310447 0 -0.10104644 0.22323772 - 1000 1.7596217 -1.7290976 0 0.012927885 0.12600944 - 1100 1.3845533 -1.635035 0 -0.26432721 0.31778997 - 1200 1.6448321 -1.6985254 0 -0.070141617 0.14347958 - 1300 1.6158541 -1.581817 0 0.017878542 0.16186588 - 1400 1.4702758 -1.5210898 0 -0.065516797 0.35241206 - 1500 1.5746718 -1.5427933 0 0.016131764 0.21832857 - 1600 1.5276572 -1.6755951 0 -0.16321447 -0.046196207 - 1700 1.8182153 -1.7471337 0 0.052899504 0.14576284 - 1800 1.8054446 -1.8814075 0 -0.094017352 0.11678153 - 1900 1.6318148 -1.636557 0 -0.021060353 0.29300401 - 2000 1.6187604 -1.5563087 0 0.046264125 0.35910875 - 2100 1.8270056 -1.9189599 0 -0.11022441 -0.031374982 - 2200 1.8203075 -1.8672658 0 -0.065161309 0.38667462 - 2300 2.1336292 -1.8962621 0 0.2160309 0.13286893 - 2400 1.79223 -1.7128682 0 0.061439536 0.30570635 - 2500 1.7208941 -1.6955053 0 0.0081798834 0.24562038 - 2600 1.7755824 -1.7744614 0 -0.016634836 0.11148721 - 2700 1.7308273 -1.744062 0 -0.030542972 0.17938105 - 2800 1.7059134 -1.6131603 0 0.075694024 0.06746694 - 2900 1.7152544 -1.665102 0 0.032999854 0.14918116 - 3000 1.7917767 -1.6654545 0 0.10840436 0.22990289 - 3100 1.7153899 -1.8140872 0 -0.11585128 0.1070804 - 3200 1.5704305 -1.5645642 0 -0.0098380461 0.30331339 - 3300 1.6707504 -1.6224865 0 0.03155641 0.21402203 - 3400 1.7390711 -1.6969145 0 0.024765924 0.25633302 - 3500 1.7601895 -1.7159833 0 0.026604288 0.10350991 - 3600 1.7796243 -1.6848496 0 0.076978483 0.24287746 - 3700 1.8883198 -1.7216992 0 0.14773748 0.071179538 - 3800 1.5757461 -1.6445584 0 -0.084569808 0.23580968 - 3900 1.5509957 -1.6221122 0 -0.086626425 0.2208604 - 4000 1.7403415 -1.6515882 0 0.071349901 0.171317 - 4100 1.6394046 -1.69549 0 -0.072479406 0.18077211 - 4200 1.788413 -1.6410039 0 0.12952501 0.41737981 - 4300 1.7211754 -1.6535323 0 0.050431306 0.1688929 - 4400 1.6034779 -1.7771275 0 -0.18968442 0.091947982 - 4500 1.5692666 -1.6176359 0 -0.064061965 0.31716418 - 4600 1.6454802 -1.5764942 0 0.052531194 0.021026463 - 4700 1.4715049 -1.582096 0 -0.12530612 0.17687943 - 4800 1.5615071 -1.6276031 0 -0.081711137 0.077798682 - 4900 1.6407636 -1.622773 0 0.0015829265 0.28751203 - 5000 1.6390013 -1.7257036 0 -0.10309236 0.35133795 - 5100 1.6540912 -1.7056399 0 -0.068089648 0.52254354 - 5200 1.6438013 -1.7568895 0 -0.12952624 0.16423828 - 5300 1.6791806 -1.756297 0 -0.093908192 0.3151943 - 5400 1.7527095 -1.729977 0 0.0052053655 0.29874227 - 5500 1.7604924 -1.6920395 0 0.050847912 0.2062502 - 5600 1.8225025 -1.6746221 0 0.12965535 0.29423091 - 5700 1.6896356 -1.6591445 0 0.013594822 0.41582329 - 5800 1.575776 -1.6605307 0 -0.10051246 0.17434812 - 5900 1.6893771 -1.6046258 0 0.067857462 0.188486 - 6000 1.6506959 -1.6295482 0 0.0046407782 0.18737656 - 6100 1.8137143 -1.6634096 0 0.13216758 0.22425414 - 6200 1.6337368 -1.6016206 0 0.015778794 0.17026591 - 6300 1.6232904 -1.7102709 0 -0.10321339 0.22621086 - 6400 1.8146767 -1.7354533 0 0.061076657 0.25907309 - 6500 1.5565608 -1.8652953 0 -0.32430015 0.096916202 - 6600 1.6366532 -1.65732 0 -0.037033272 0.30276466 - 6700 1.6612051 -1.6621545 0 -0.017561423 0.16685109 - 6800 1.5574268 -1.6082827 0 -0.066430166 0.37630931 - 6900 1.6556225 -1.6744213 0 -0.035355078 0.11599545 - 7000 1.5078585 -1.6049482 0 -0.11216833 0.37716682 - 7100 1.6147622 -1.7044793 0 -0.10586467 0.48915924 - 7200 1.8022216 -1.7117836 0 0.072415791 0.24007939 - 7300 1.6302834 -1.8522784 0 -0.23829784 0.19326557 - 7400 1.7108472 -1.8993043 0 -0.20556558 0.34554364 - 7500 1.8570536 -1.7135598 0 0.12492326 0.53728185 - 7600 1.7812105 -1.7239897 0 0.039408716 0.44348124 - 7700 1.8724942 -1.7871204 0 0.066648837 0.2529344 - 7800 1.8237412 -1.6467621 0 0.15874169 0.2354529 - 7900 1.7222899 -1.7254585 0 -0.02039155 0.13271481 - 8000 1.6839 -1.5913695 0 0.075691547 0.011932379 - 8100 1.599835 -1.672507 0 -0.088670351 0.11203274 - 8200 1.8369376 -1.7464532 0 0.072115105 0.21380276 - 8300 1.9603301 -1.9121791 0 0.02854768 0.18178367 - 8400 1.7903688 -1.8798475 0 -0.10738231 0.37173469 - 8500 1.687183 -1.760587 0 -0.090275846 0.23751647 - 8600 1.6515772 -1.7918091 0 -0.15674775 0.099895142 - 8700 1.7083909 -1.7297068 0 -0.038399775 0.57093506 - 8800 1.6150569 -1.6976608 0 -0.098754502 0.15348519 - 8900 1.5452011 -1.7517421 0 -0.22199306 0.22143091 - 9000 1.7498686 -1.8569695 0 -0.12459962 0.1989093 - 9100 1.6287336 -1.7505293 0 -0.13808305 0.23881397 - 9200 1.5431194 -1.6845999 0 -0.15691169 0.10646288 - 9300 1.4900229 -1.5671955 0 -0.092072887 0.31588548 - 9400 1.523362 -1.5531592 0 -0.045030785 0.21546483 - 9500 1.5783775 -1.65292 0 -0.090326215 0.25980559 - 9600 1.9192786 -1.9303222 0 -0.030236392 -0.0046632743 - 9700 1.747544 -1.7886479 0 -0.058579385 0.38543046 - 9800 1.6713187 -1.6842507 0 -0.029645137 0.17982115 - 9900 1.7707351 -1.6638268 0 0.089200949 0.2983883 - 10000 1.6466807 -1.592436 0 0.037777866 0.12761693 -Loop time of 1.76365 on 1 procs for 10000 steps with 100 atoms - -Performance: 2449465.017 tau/day, 5670.058 timesteps/s -98.9% CPU use with 1 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 1.5533 | 1.5533 | 1.5533 | 0.0 | 88.08 -Neigh | 0.01155 | 0.01155 | 0.01155 | 0.0 | 0.65 -Comm | 0.042146 | 0.042146 | 0.042146 | 0.0 | 2.39 -Output | 0.00089574 | 0.00089574 | 0.00089574 | 0.0 | 0.05 -Modify | 0.14124 | 0.14124 | 0.14124 | 0.0 | 8.01 -Other | | 0.01448 | | | 0.82 - -Nlocal: 100 ave 100 max 100 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 82 ave 82 max 82 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 467 ave 467 max 467 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 467 -Ave neighs/atom = 4.67 -Neighbor list builds = 468 -Dangerous builds = 0 -Total wall time: 0:00:01 diff --git a/examples/body/log.27Nov18.body.g++.4 b/examples/body/log.27Nov18.body.g++.4 deleted file mode 100644 index 24ed0a5436..0000000000 --- a/examples/body/log.27Nov18.body.g++.4 +++ /dev/null @@ -1,177 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# 2d polygon nparticle bodies - -units lj -dimension 2 -atom_style body nparticle 2 6 - -read_data data.body - orthogonal box = (-15.5322 -15.5322 -0.5) to (15.5322 15.5322 0.5) - 2 by 2 by 1 MPI processor grid - reading atoms ... - 100 atoms - 100 bodies - -velocity all create 1.44 87287 loop geom - -pair_style body/nparticle 5.0 -pair_coeff * * 1.0 1.0 - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -fix 1 all nve/body -#fix 1 all nvt/body temp 1.44 1.44 1.0 -fix 2 all enforce2d - -#compute 1 all body/local type 1 2 3 -#dump 1 all local 100 dump.body index c_1[1] c_1[2] c_1[3] c_1[4] - -#dump 2 all image 1000 image.*.jpg type type # zoom 1.6 adiam 1.5 body type 1.0 0 -#dump_modify 2 pad 5 - -thermo 100 -run 10000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 5.5 - ghost atom cutoff = 5.5 - binsize = 2.75, bins = 12 12 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair body/nparticle, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.759 | 4.759 | 4.759 Mbytes -Step Temp E_pair E_mol TotEng Press - 0 1.44 -0.63799525 0 0.78760475 -0.15028724 - 100 1.642337 -1.0003869 0 0.62552682 0.16140818 - 200 1.470473 -1.2465469 0 0.20922135 0.35146925 - 300 1.4834687 -1.3464946 0 0.12213946 0.40783535 - 400 1.5075814 -1.6170041 0 -0.12449852 0.11302717 - 500 1.5681124 -1.6060641 0 -0.053632801 0.23819933 - 600 1.7129405 -1.6939468 0 0.0018642497 0.46490776 - 700 1.5803869 -1.6182998 0 -0.053716823 0.36807869 - 800 1.6454324 -1.6537709 0 -0.024792836 0.21305673 - 900 1.5454528 -1.6310447 0 -0.10104644 0.22323772 - 1000 1.7596217 -1.7290976 0 0.012927885 0.12600944 - 1100 1.3845533 -1.635035 0 -0.26432721 0.31778997 - 1200 1.6448321 -1.6985254 0 -0.070141617 0.14347958 - 1300 1.6158541 -1.581817 0 0.017878542 0.16186588 - 1400 1.4702758 -1.5210898 0 -0.065516796 0.35241206 - 1500 1.5746718 -1.5427933 0 0.016131765 0.21832856 - 1600 1.5276572 -1.6755951 0 -0.16321446 -0.046196204 - 1700 1.8182153 -1.7471336 0 0.052899516 0.14576285 - 1800 1.8054446 -1.8814074 0 -0.094017286 0.11678173 - 1900 1.6318146 -1.636557 0 -0.021060549 0.2930043 - 2000 1.6187614 -1.5563095 0 0.046264283 0.3591072 - 2100 1.8270046 -1.9189568 0 -0.11022215 -0.031366859 - 2200 1.8203171 -1.8672823 0 -0.065168391 0.38665482 - 2300 2.1336582 -1.8962717 0 0.21604988 0.13283887 - 2400 1.7923604 -1.7129915 0 0.061445317 0.30554793 - 2500 1.7207328 -1.694912 0 0.008613452 0.24608272 - 2600 1.7761079 -1.7743463 0 -0.015999568 0.11128836 - 2700 1.7327782 -1.7433093 0 -0.027858862 0.17923355 - 2800 1.6869096 -1.6050313 0 0.065009255 0.082020625 - 2900 1.723365 -1.6453122 0 0.06081914 0.11381101 - 3000 1.759037 -1.7499957 0 -0.008549105 0.12711249 - 3100 1.7608876 -1.8502753 0 -0.10699653 0.10597269 - 3200 1.6030658 -1.6772861 0 -0.090250949 0.16058698 - 3300 1.6136204 -1.6247049 0 -0.027220627 0.27194341 - 3400 1.7126562 -1.6002267 0 0.095302885 0.034174254 - 3500 1.5286242 -1.5693205 0 -0.055982557 -0.028526272 - 3600 1.5529814 -1.6309948 0 -0.093543248 0.25627254 - 3700 1.4066962 -1.4583439 0 -0.06571463 0.36890582 - 3800 1.5736098 -1.5849626 0 -0.027088852 0.19376983 - 3900 1.5819362 -1.6452885 0 -0.07917158 0.17494451 - 4000 1.806905 -1.7114262 0 0.077409698 0.059568431 - 4100 1.7116803 -1.7160461 0 -0.02148265 0.12178783 - 4200 1.8262315 -1.6682893 0 0.13967987 0.25082769 - 4300 1.7548351 -1.6835554 0 0.053731392 0.39252317 - 4400 1.7564816 -1.8020325 0 -0.063115749 0.18973764 - 4500 1.727529 -1.771176 0 -0.06092227 0.51752631 - 4600 1.633861 -1.7554104 0 -0.13788808 0.43310585 - 4700 1.6678523 -1.8066719 0 -0.15549814 -0.086702533 - 4800 1.5903598 -1.7410621 0 -0.1666059 0.064914366 - 4900 1.4894085 -1.5982645 0 -0.12375007 0.23124626 - 5000 1.5422574 -1.6830449 0 -0.15621011 0.12943511 - 5100 1.6123243 -1.6577202 0 -0.061519159 0.26031057 - 5200 1.6815554 -1.6889534 0 -0.024213484 0.1747903 - 5300 1.6502994 -1.5929462 0 0.040850243 0.25623758 - 5400 1.5900521 -1.8240806 0 -0.24992903 0.17822148 - 5500 1.6976803 -1.8370034 0 -0.15629992 0.30793026 - 5600 1.737085 -1.6873775 0 0.032336607 0.32235718 - 5700 1.6995769 -1.6328398 0 0.04974131 0.22932613 - 5800 1.6299367 -1.6582188 0 -0.044581533 0.33036589 - 5900 1.6232041 -1.6456588 0 -0.038686805 0.20701623 - 6000 1.6912228 -1.6401907 0 0.034119867 0.091519693 - 6100 1.6314651 -1.6045998 0 0.010550658 0.32331621 - 6200 1.7575091 -1.7271281 0 0.012805903 0.14214943 - 6300 1.6830653 -1.7955472 0 -0.12931258 0.38730996 - 6400 1.6323392 -1.7470603 0 -0.13104448 0.16724215 - 6500 1.537874 -1.7277794 0 -0.20528423 0.28976791 - 6600 1.8375539 -1.8388229 0 -0.019644528 0.31704541 - 6700 1.7519102 -1.7739002 0 -0.039509043 0.19065098 - 6800 1.4602447 -1.6902787 0 -0.24463645 0.20244553 - 6900 1.6734836 -1.72224 0 -0.065491224 0.27092829 - 7000 1.8166001 -1.7288037 0 0.069630392 0.43514063 - 7100 1.9080746 -1.7849767 0 0.10401717 0.086258744 - 7200 1.6346559 -1.602179 0 0.016130393 0.37208486 - 7300 1.669382 -1.594527 0 0.058161153 0.12543161 - 7400 1.5858819 -1.447937 0 0.12208615 0.42666321 - 7500 1.6947983 -1.637715 0 0.040135322 -0.020875259 - 7600 1.7085903 -1.6810854 0 0.010419044 0.1341074 - 7700 1.5780919 -1.6213683 0 -0.059057356 0.3826822 - 7800 1.8079476 -1.761193 0 0.028675183 0.034143718 - 7900 1.836977 -1.8401332 0 -0.021525986 0.21458105 - 8000 1.9135057 -1.8302694 0 0.064101272 0.23217665 - 8100 1.8606829 -1.6984146 0 0.14366143 0.18168582 - 8200 1.7474236 -1.7574166 0 -0.027467252 0.26529178 - 8300 1.7637155 -1.7861969 0 -0.040118627 0.12298468 - 8400 1.6564242 -1.477104 0 0.16275596 0.14143164 - 8500 1.5868929 -1.6520125 0 -0.080988476 0.22461508 - 8600 1.7556628 -1.7647169 0 -0.026610688 0.19913257 - 8700 1.804704 -1.7892113 0 -0.0025543811 0.2825016 - 8800 1.6511248 -1.8632147 0 -0.22860119 0.041019097 - 8900 1.8323591 -1.7923506 0 0.021684941 0.21335945 - 9000 1.9100569 -1.955559 0 -0.064602644 0.158775 - 9100 1.7562572 -1.8720716 0 -0.13337695 0.19662119 - 9200 1.6566561 -1.9406507 0 -0.30056122 0.12296597 - 9300 1.8367792 -1.9060138 0 -0.087602325 0.19447518 - 9400 1.8420592 -1.6318148 0 0.19182383 0.50726082 - 9500 1.7773475 -1.6973532 0 0.062220818 0.2487172 - 9600 1.6545313 -1.701977 0 -0.063991036 0.20549434 - 9700 1.7463358 -1.8329845 0 -0.10411212 0.15498427 - 9800 1.7799071 -1.7889616 0 -0.026853542 0.3169291 - 9900 1.5838158 -1.718909 0 -0.15093133 0.46050618 - 10000 1.6100625 -1.7018091 0 -0.10784725 0.10312591 -Loop time of 0.715445 on 4 procs for 10000 steps with 100 atoms - -Performance: 6038199.147 tau/day, 13977.313 timesteps/s -95.9% CPU use with 4 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0.35395 | 0.40307 | 0.45588 | 5.9 | 56.34 -Neigh | 0.0033705 | 0.0036112 | 0.0039394 | 0.4 | 0.50 -Comm | 0.17564 | 0.22399 | 0.26912 | 7.8 | 31.31 -Output | 0.0014601 | 0.0024824 | 0.0054784 | 3.5 | 0.35 -Modify | 0.038037 | 0.039219 | 0.04163 | 0.7 | 5.48 -Other | | 0.04308 | | | 6.02 - -Nlocal: 25 ave 28 max 23 min -Histogram: 1 0 1 0 1 0 0 0 0 1 -Nghost: 47.25 ave 49 max 42 min -Histogram: 1 0 0 0 0 0 0 0 0 3 -Neighs: 113.25 ave 132 max 104 min -Histogram: 2 0 1 0 0 0 0 0 0 1 - -Total # of neighbors = 453 -Ave neighs/atom = 4.53 -Neighbor list builds = 483 -Dangerous builds = 0 -Total wall time: 0:00:00 diff --git a/examples/body/log.27Nov18.pour3d.g++.1 b/examples/body/log.27Nov18.pour3d.g++.1 deleted file mode 100644 index 10a4999d14..0000000000 --- a/examples/body/log.27Nov18.pour3d.g++.1 +++ /dev/null @@ -1,74 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# pouring 3d rounded polyhedron bodies - -variable steps index 6000 - -units lj -boundary p p fm -comm_modify vel yes - -atom_style body rounded/polyhedron 1 8 -atom_modify map array - -region reg block 0 50 0 50 0 50 units box -create_box 4 reg -Created orthogonal box = (0 0 0) to (50 50 50) - 1 by 1 by 1 MPI processor grid - -variable cut_inner equal 0.5 -variable k_n equal 100 -variable k_na equal 5 -variable c_n equal 20 -variable c_t equal 5 -variable mu equal 0 -variable A_ua equal 1 - -pair_style body/rounded/polyhedron ${c_n} ${c_t} ${mu} ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 ${c_t} ${mu} ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 5 ${mu} ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 5 0 ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 5 0 1 ${cut_inner} -pair_style body/rounded/polyhedron 20 5 0 1 0.5 -pair_coeff * * ${k_n} ${k_na} -pair_coeff * * 100 ${k_na} -pair_coeff * * 100 5 - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -timestep 0.001 - -fix 1 all nve/body -fix 2 all gravity 1.0 spherical 0.0 -180.0 - -molecule object molecule.cube molecule.tetra toff 1 molecule.rod3d toff 2 molecule.point3d toff 3 -Read molecule object: - 1 atoms with max type 1 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 -Read molecule object: - 1 atoms with max type 2 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 -Read molecule object: - 1 atoms with max type 3 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 -Read molecule object: - 1 atoms with max type 4 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 - -region slab block 5 45 5 45 25 35 units box -fix ins all pour 500 0 4767548 vol 0.4 10 region slab mol object molfrac 0.25 0.25 0.25 0.25 -ERROR: Unknown fix style pour (src/modify.cpp:898) -Last command: fix ins all pour 500 0 4767548 vol 0.4 10 region slab mol object molfrac 0.25 0.25 0.25 0.25 diff --git a/examples/body/log.27Nov18.pour3d.g++.4 b/examples/body/log.27Nov18.pour3d.g++.4 deleted file mode 100644 index eb65f99bc2..0000000000 --- a/examples/body/log.27Nov18.pour3d.g++.4 +++ /dev/null @@ -1,74 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# pouring 3d rounded polyhedron bodies - -variable steps index 6000 - -units lj -boundary p p fm -comm_modify vel yes - -atom_style body rounded/polyhedron 1 8 -atom_modify map array - -region reg block 0 50 0 50 0 50 units box -create_box 4 reg -Created orthogonal box = (0 0 0) to (50 50 50) - 1 by 2 by 2 MPI processor grid - -variable cut_inner equal 0.5 -variable k_n equal 100 -variable k_na equal 5 -variable c_n equal 20 -variable c_t equal 5 -variable mu equal 0 -variable A_ua equal 1 - -pair_style body/rounded/polyhedron ${c_n} ${c_t} ${mu} ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 ${c_t} ${mu} ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 5 ${mu} ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 5 0 ${A_ua} ${cut_inner} -pair_style body/rounded/polyhedron 20 5 0 1 ${cut_inner} -pair_style body/rounded/polyhedron 20 5 0 1 0.5 -pair_coeff * * ${k_n} ${k_na} -pair_coeff * * 100 ${k_na} -pair_coeff * * 100 5 - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -timestep 0.001 - -fix 1 all nve/body -fix 2 all gravity 1.0 spherical 0.0 -180.0 - -molecule object molecule.cube molecule.tetra toff 1 molecule.rod3d toff 2 molecule.point3d toff 3 -Read molecule object: - 1 atoms with max type 1 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 -Read molecule object: - 1 atoms with max type 2 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 -Read molecule object: - 1 atoms with max type 3 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 -Read molecule object: - 1 atoms with max type 4 - 0 bonds with max type 0 - 0 angles with max type 0 - 0 dihedrals with max type 0 - 0 impropers with max type 0 - -region slab block 5 45 5 45 25 35 units box -fix ins all pour 500 0 4767548 vol 0.4 10 region slab mol object molfrac 0.25 0.25 0.25 0.25 -ERROR: Unknown fix style pour (src/modify.cpp:898) -Last command: fix ins all pour 500 0 4767548 vol 0.4 10 region slab mol object molfrac 0.25 0.25 0.25 0.25 diff --git a/examples/body/log.27Nov18.squares.g++.1 b/examples/body/log.27Nov18.squares.g++.1 deleted file mode 100644 index cc334b416c..0000000000 --- a/examples/body/log.27Nov18.squares.g++.1 +++ /dev/null @@ -1,222 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# 2d rounded polygon bodies - -variable r index 4 -variable steps index 100000 -variable T index 0.5 -variable P index 0.1 -variable seed index 980411 - -units lj -dimension 2 - -atom_style body rounded/polygon 1 6 -atom_modify map array -read_data data.squares - orthogonal box = (0 0 -0.5) to (12 12 0.5) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 2 atoms - 2 bodies - -replicate $r $r 1 -replicate 4 $r 1 -replicate 4 4 1 - orthogonal box = (0 0 -0.5) to (48 48 0.5) - 1 by 1 by 1 MPI processor grid - 32 atoms - Time spent = 0.000279665 secs - -velocity all create $T ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 980411 dist gaussian mom yes rot yes - -variable cut_inner equal 0.5 -variable k_n equal 100 -variable k_na equal 2 -variable c_n equal 1 -variable c_t equal 1 -variable mu equal 0.1 -variable delta_ua equal 0.5 - -pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 1 ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 1 0.1 ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 1 0.1 0.5 ${cut_inner} -pair_style body/rounded/polygon 1 1 0.1 0.5 0.5 -pair_coeff * * ${k_n} ${k_na} -pair_coeff * * 100 ${k_na} -pair_coeff * * 100 2 - -comm_modify vel yes - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -timestep 0.001 - -#fix 1 all nve/body -#fix 1 all nvt/body temp $T $T 1.0 -fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 0.1 1.0 couple xy fixedpoint 0 0 0 - -fix 2 all enforce2d - -#compute 1 all body/local id 1 2 3 -#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] - -thermo_style custom step ke pe etotal press -thermo 1000 - -#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 -#dump_modify 2 pad 6 - -run ${steps} -run 100000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 6.15685 - ghost atom cutoff = 6.15685 - binsize = 3.07843, bins = 16 16 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair body/rounded/polygon, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.781 | 4.781 | 4.781 Mbytes -Step KinEng PotEng TotEng Press - 0 0.484375 0.25 0.734375 0.0067274306 - 1000 0.38428256 0.0014168922 0.38569945 0.0020468171 - 2000 0.41372193 0.015263236 0.42898517 0.0029343462 - 3000 0.54844547 0.014870378 0.56331585 0.001978353 - 4000 0.73816048 0.031668204 0.76982869 0.0025939718 - 5000 0.84536165 0.011504649 0.8568663 0.0037990517 - 6000 0.73776478 0.14445932 0.8822241 0.0086538113 - 7000 0.52022565 0.069507637 0.58973329 0.0072098694 - 8000 0.72653213 0.12783368 0.85436581 0.023907183 - 9000 0.87685727 0.1239819 1.0008392 0.0064590959 - 10000 0.7250918 0.097243508 0.82233531 0.0012448267 - 11000 0.62302234 0.05597557 0.67899791 0.00080239872 - 12000 0.57159363 0.18199602 0.75358965 0.01033626 - 13000 0.7505295 0.071545266 0.82207477 0.011480236 - 14000 0.84703598 0.15914379 1.0061798 0.032814039 - 15000 0.41905013 0.090552572 0.5096027 0.015717153 - 16000 0.41805189 0.042916881 0.46096877 0.020702707 - 17000 0.59966233 0.05285043 0.65251275 0.016526024 - 18000 0.54282285 0.20835047 0.75117332 0.036414059 - 19000 0.777922 0.034754101 0.8126761 0.036467537 - 20000 0.54703924 0.14633506 0.6933743 0.012917248 - 21000 0.49337931 0.1858754 0.67925471 0.037890735 - 22000 0.64916623 0.19281344 0.84197967 0.011996773 - 23000 0.66958738 0.20459682 0.8741842 0.023639466 - 24000 0.63729755 0.1111959 0.74849345 0.025049919 - 25000 0.60094316 0.13375799 0.73470115 0.035286376 - 26000 0.35419589 0.22049451 0.5746904 0.0024215291 - 27000 0.33789786 0.18494942 0.52284728 0.0066457643 - 28000 0.32376056 0.13151726 0.45527782 0.010773856 - 29000 0.36198203 0.11044834 0.47243037 0.063012638 - 30000 0.22624436 0.19690087 0.42314523 0.037422734 - 31000 0.32284312 0.059623656 0.38246677 0.0287682 - 32000 0.4457193 0.042396136 0.48811544 0.022025252 - 33000 0.61078662 0.059447221 0.67023384 0.030335089 - 34000 0.63157762 0.062056279 0.6936339 0.044624352 - 35000 0.69577644 0.086216204 0.78199264 0.0319995 - 36000 0.76814336 0.062105963 0.83024933 0.044316891 - 37000 0.58641664 0.095034548 0.68145119 0.03234133 - 38000 0.48772813 0.12911854 0.61684667 0.038732146 - 39000 0.74957742 0.09823432 0.84781174 0.053181162 - 40000 0.57881374 0.2932491 0.87206284 0.065740126 - 41000 0.4415176 0.22899179 0.67050939 0.026159841 - 42000 0.5260339 0.2048105 0.7308444 0.046294432 - 43000 0.33493572 0.32500572 0.65994144 -0.01250241 - 44000 0.46467243 0.07907132 0.54374375 0.13386238 - 45000 0.48135518 0.2618908 0.74324598 -0.016767159 - 46000 0.27223209 0.24562643 0.51785852 0.052118439 - 47000 0.26402739 0.1838767 0.44790409 -0.0015878764 - 48000 0.10229166 0.25519169 0.35748335 -0.033927088 - 49000 0.24313495 0.16578185 0.40891679 0.12414926 - 50000 0.27400066 0.27688032 0.55088098 0.10421157 - 51000 0.43081855 0.18111733 0.61193587 0.16373371 - 52000 0.81969298 0.060995894 0.88068887 0.057285357 - 53000 0.99936159 0.029137886 1.0284995 0.19425015 - 54000 0.69750047 0.038079774 0.73558024 -0.089236384 - 55000 0.54823746 0.056369886 0.60460734 -0.021320579 - 56000 0.6752322 0.050322917 0.72555512 0.25303548 - 57000 0.90328009 0.061107142 0.96438723 -0.1962713 - 58000 0.81463148 0.050387847 0.86501933 0.35952157 - 59000 0.61636455 0.064910223 0.68127478 -0.27208497 - 60000 0.62573918 0.052264617 0.67800379 0.4493407 - 61000 0.81065726 0.071269668 0.88192693 -0.34643283 - 62000 0.86420318 0.052799365 0.91700254 0.48308047 - 63000 0.67848508 0.069087342 0.74757242 -0.31814526 - 64000 0.61430417 0.052109373 0.66641354 0.38336646 - 65000 0.75782937 0.063488206 0.82131757 -0.19113322 - 66000 0.88735857 0.051779306 0.93913787 0.29410996 - 67000 0.70684373 0.061786313 0.76863005 -0.16503578 - 68000 0.58571951 0.052402151 0.63812166 0.30173228 - 69000 0.64997491 0.064435462 0.71441037 -0.1920633 - 70000 0.75071821 0.053416991 0.8041352 0.3846747 - 71000 0.8124718 0.06877986 0.88125166 -0.26852566 - 72000 0.71352066 0.05358784 0.7671085 0.41321806 - 73000 0.55151827 0.066470642 0.61798891 -0.2211738 - 74000 0.65473635 0.061946814 0.71668316 0.29536873 - 75000 0.88704613 0.059476353 0.94652248 -0.0312656 - 76000 0.76899803 0.057351665 0.8263497 0.017885214 - 77000 0.65149455 0.05407174 0.70556629 0.25192449 - 78000 0.68614394 0.074251169 0.76039511 -0.19369404 - 79000 0.97451567 0.06262739 1.0371431 0.4217182 - 80000 0.88207775 0.070157004 0.95223476 -0.27318477 - 81000 0.69294455 0.062623957 0.75556851 0.40150141 - 82000 0.70748016 0.073924331 0.78140449 -0.17128794 - 83000 0.78180774 0.063513978 0.84532172 0.22033652 - 84000 0.80170993 0.065812223 0.86752216 0.083202913 - 85000 0.64788122 0.070348079 0.7182293 -0.066913668 - 86000 0.56575431 0.064865112 0.63061942 0.33905786 - 87000 0.78205358 0.07983702 0.8618906 -0.22844912 - 88000 0.87426443 0.065703482 0.93996791 0.448573 - 89000 0.73269893 0.079827385 0.81252632 -0.24183162 - 90000 0.66703106 0.065630146 0.73266121 0.35410109 - 91000 0.73107154 0.07402702 0.80509856 -0.085492997 - 92000 1.043635 0.067156523 1.1107915 0.14311135 - 93000 0.86063344 0.065607238 0.92624068 0.20750649 - 94000 0.68304235 0.075962239 0.75900459 -0.14594625 - 95000 0.7069191 0.067125732 0.77404483 0.39459759 - 96000 0.79860046 0.090957588 0.88955805 -0.24202125 - 97000 0.81366777 0.071387081 0.88505485 0.32217266 - 98000 0.61885746 0.041524228 0.66038169 0.31635364 - 99000 0.57007759 0.055438456 0.62551604 -0.21172902 - 100000 0.80462394 0.045542313 0.85016626 0.099207503 -Loop time of 6.34495 on 1 procs for 100000 steps with 32 atoms - -Performance: 1361713.788 tau/day, 15760.576 timesteps/s -99.7% CPU use with 1 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 5.0158 | 5.0158 | 5.0158 | 0.0 | 79.05 -Neigh | 0.0072868 | 0.0072868 | 0.0072868 | 0.0 | 0.11 -Comm | 0.18669 | 0.18669 | 0.18669 | 0.0 | 2.94 -Output | 0.00098681 | 0.00098681 | 0.00098681 | 0.0 | 0.02 -Modify | 1.0417 | 1.0417 | 1.0417 | 0.0 | 16.42 -Other | | 0.09245 | | | 1.46 - -Nlocal: 32 ave 32 max 32 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 35 ave 35 max 35 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 61 ave 61 max 61 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 61 -Ave neighs/atom = 1.90625 -Neighbor list builds = 1545 -Dangerous builds = 0 -Total wall time: 0:00:06 diff --git a/examples/body/log.27Nov18.squares.g++.4 b/examples/body/log.27Nov18.squares.g++.4 deleted file mode 100644 index 62c6206677..0000000000 --- a/examples/body/log.27Nov18.squares.g++.4 +++ /dev/null @@ -1,222 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# 2d rounded polygon bodies - -variable r index 4 -variable steps index 100000 -variable T index 0.5 -variable P index 0.1 -variable seed index 980411 - -units lj -dimension 2 - -atom_style body rounded/polygon 1 6 -atom_modify map array -read_data data.squares - orthogonal box = (0 0 -0.5) to (12 12 0.5) - 2 by 2 by 1 MPI processor grid - reading atoms ... - 2 atoms - 2 bodies - -replicate $r $r 1 -replicate 4 $r 1 -replicate 4 4 1 - orthogonal box = (0 0 -0.5) to (48 48 0.5) - 2 by 2 by 1 MPI processor grid - 32 atoms - Time spent = 0.000400782 secs - -velocity all create $T ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 980411 dist gaussian mom yes rot yes - -variable cut_inner equal 0.5 -variable k_n equal 100 -variable k_na equal 2 -variable c_n equal 1 -variable c_t equal 1 -variable mu equal 0.1 -variable delta_ua equal 0.5 - -pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 1 ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 1 0.1 ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 1 1 0.1 0.5 ${cut_inner} -pair_style body/rounded/polygon 1 1 0.1 0.5 0.5 -pair_coeff * * ${k_n} ${k_na} -pair_coeff * * 100 ${k_na} -pair_coeff * * 100 2 - -comm_modify vel yes - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -timestep 0.001 - -#fix 1 all nve/body -#fix 1 all nvt/body temp $T $T 1.0 -fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 $P 1.0 couple xy fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 y 0.001 0.1 1.0 couple xy fixedpoint 0 0 0 - -fix 2 all enforce2d - -#compute 1 all body/local id 1 2 3 -#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] - -thermo_style custom step ke pe etotal press -thermo 1000 - -#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 -#dump_modify 2 pad 6 - -run ${steps} -run 100000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 6.15685 - ghost atom cutoff = 6.15685 - binsize = 3.07843, bins = 16 16 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair body/rounded/polygon, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.774 | 4.774 | 4.774 Mbytes -Step KinEng PotEng TotEng Press - 0 0.484375 0.25 0.734375 0.0067274306 - 1000 0.38428256 0.0014168922 0.38569945 0.0020468171 - 2000 0.41372193 0.015263236 0.42898517 0.0029343462 - 3000 0.54844547 0.014870378 0.56331585 0.001978353 - 4000 0.73816048 0.031668204 0.76982869 0.0025939718 - 5000 0.84536165 0.011504649 0.8568663 0.0037990517 - 6000 0.73776478 0.14445932 0.8822241 0.0086538113 - 7000 0.52022565 0.069507637 0.58973329 0.0072098694 - 8000 0.72653213 0.12783367 0.85436581 0.023907185 - 9000 0.87685728 0.12398193 1.0008392 0.0064591005 - 10000 0.72509641 0.097241969 0.82233837 0.0012418726 - 11000 0.62314955 0.056042914 0.67919247 0.0018880786 - 12000 0.57157436 0.18187429 0.75344865 0.0096135623 - 13000 0.7489742 0.08262775 0.83160195 0.009183917 - 14000 0.78835138 0.18761048 0.97596186 0.023684357 - 15000 0.40408761 0.079431327 0.48351893 0.025285348 - 16000 0.4071013 0.13207058 0.53917188 0.02015488 - 17000 0.48417067 0.16699781 0.65116848 0.059188189 - 18000 0.60038567 0.18317457 0.78356024 -0.046456387 - 19000 0.73796958 0.064271521 0.8022411 0.090257204 - 20000 0.62508659 0.14486336 0.76994994 0.04948543 - 21000 0.5596837 0.10018831 0.65987201 0.044961962 - 22000 0.30731517 0.1386103 0.44592547 0.015096596 - 23000 0.34371843 0.1486761 0.49239453 0.026100892 - 24000 0.33484204 0.25428479 0.58912683 0.01974393 - 25000 0.48714744 0.32743616 0.8145836 0.037925893 - 26000 0.33255994 0.29851422 0.63107417 0.049419529 - 27000 0.21735889 0.18816203 0.40552093 0.050622152 - 28000 0.31911317 0.12559898 0.44471215 -0.0036236361 - 29000 0.53280161 0.055185441 0.58798705 0.083856225 - 30000 0.52916941 0.28697284 0.81614225 0.055873213 - 31000 0.47861645 0.21932568 0.69794214 0.02762301 - 32000 0.46786314 0.041856438 0.50971958 0.029923804 - 33000 0.69944716 0.039356744 0.7388039 0.028174645 - 34000 0.39964317 0.1027175 0.50236068 0.039495865 - 35000 0.70199237 0.10421859 0.80621095 0.015943417 - 36000 0.45053533 0.078626602 0.52916193 0.0073950287 - 37000 0.41587918 0.056551665 0.47243084 0.034091318 - 38000 0.58663473 0.039228671 0.6258634 0.033093641 - 39000 0.72480658 0.14792564 0.87273222 0.030903741 - 40000 0.51163285 0.13445292 0.64608577 -0.03114559 - 41000 0.56273761 0.16720374 0.72994135 0.027968528 - 42000 0.61850184 0.10584389 0.72434573 -0.036301799 - 43000 0.60039772 0.11984289 0.72024062 0.080894236 - 44000 0.57499839 0.068211092 0.64320948 0.049726122 - 45000 0.69937239 0.16287141 0.8622438 0.044921114 - 46000 0.23303785 0.2391726 0.47221045 0.021668935 - 47000 0.27051781 0.10690378 0.37742159 0.11963476 - 48000 0.408895 0.079919688 0.48881469 0.087484004 - 49000 0.74363181 0.040819422 0.78445123 0.011937456 - 50000 0.84482316 0.10205256 0.94687572 0.064133262 - 51000 0.84923574 0.089882984 0.93911872 0.062696388 - 52000 0.66278324 0.0331554 0.69593864 0.035150337 - 53000 0.64737251 0.039608076 0.68698058 0.057687461 - 54000 0.68931435 0.042661403 0.73197576 0.069664795 - 55000 0.84523308 0.10293275 0.94816583 0.047343755 - 56000 0.80033937 0.1534797 0.95381907 0.070206074 - 57000 0.6214799 0.1174575 0.7389374 0.078530452 - 58000 0.64228495 0.088089896 0.73037485 0.060245994 - 59000 0.89376363 0.065171887 0.95893552 0.071658895 - 60000 0.90162992 0.016564761 0.91819468 0.089245946 - 61000 0.72439995 0.0076508835 0.73205083 0.031430213 - 62000 0.71590702 0.0046728326 0.72057986 0.10153514 - 63000 0.74491219 0.0046757926 0.74958798 0.077145851 - 64000 0.77173614 0.008265632 0.78000178 -0.049932265 - 65000 0.72789092 0.0053605745 0.73325149 0.27060389 - 66000 0.63001101 0.013871945 0.64388296 -0.17766692 - 67000 0.65887071 0.0069105692 0.66578128 0.31632918 - 68000 0.89042862 0.0026334652 0.89306209 -0.050495873 - 69000 0.83442374 0.0059232957 0.84034703 -0.21871692 - 70000 0.65149642 0.004885383 0.65638181 0.50428108 - 71000 0.66888808 0.01125057 0.68013865 -0.29575772 - 72000 0.74941609 0.0026616299 0.75207772 0.34800716 - 73000 0.7898844 0.0048982026 0.7947826 -0.096872644 - 74000 0.68823538 0.0021467794 0.69038216 0.12272852 - 75000 0.5238808 0.0046112795 0.52849208 0.25760316 - 76000 0.65512889 0.014567969 0.66969686 -0.24622674 - 77000 0.82292373 0.0092471048 0.83217083 0.4002304 - 78000 0.76305221 0.01101937 0.77407158 -0.10704945 - 79000 0.66279814 0.0090486405 0.67184678 0.037466134 - 80000 0.65808885 0.010000569 0.66808942 0.31742291 - 81000 0.91357798 0.046226814 0.95980479 -0.20945693 - 82000 0.87611859 -0.016794871 0.85932372 0.31759733 - 83000 0.66285455 -0.017921021 0.64493353 0.27065273 - 84000 0.67460715 -0.0076174891 0.66698966 -0.024772659 - 85000 0.77786135 0.0014316505 0.779293 -0.21635327 - 86000 0.83246393 0.087489797 0.91995372 -0.13431455 - 87000 0.62935573 0.045088823 0.67444455 0.037766395 - 88000 0.55264538 -0.024625272 0.52802011 0.18121213 - 89000 0.74171392 -0.012629926 0.729084 -0.27666424 - 90000 0.82542165 -0.02296567 0.80245598 -0.30497174 - 91000 0.72958657 -0.026275093 0.70331147 -0.27624518 - 92000 0.6319558 0.022568297 0.65452409 -0.33539318 - 93000 0.66685301 0.021889807 0.68874282 -0.39890762 - 94000 0.91243243 0.0078218509 0.92025428 -0.27213648 - 95000 0.81125179 -0.0096756295 0.80157616 -0.099802335 - 96000 0.63354907 -0.018329423 0.61521965 0.18199604 - 97000 0.66812347 -0.016650228 0.65147324 0.49878257 - 98000 0.81490013 -0.0049164866 0.80998365 -0.13473106 - 99000 0.82131147 0.0043198846 0.82563136 -0.3083957 - 100000 0.50880983 -0.010467027 0.4983428 0.060606332 -Loop time of 4.3169 on 4 procs for 100000 steps with 32 atoms - -Performance: 2001435.573 tau/day, 23164.764 timesteps/s -95.1% CPU use with 4 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 1.2078 | 1.3972 | 1.6653 | 15.1 | 32.36 -Neigh | 0.0030954 | 0.003284 | 0.0034814 | 0.3 | 0.08 -Comm | 1.074 | 1.3595 | 1.6003 | 16.2 | 31.49 -Output | 0.001703 | 0.0030067 | 0.0068843 | 4.1 | 0.07 -Modify | 1.2071 | 1.2647 | 1.3062 | 3.6 | 29.30 -Other | | 0.2893 | | | 6.70 - -Nlocal: 8 ave 9 max 6 min -Histogram: 1 0 0 0 0 0 1 0 0 2 -Nghost: 17.75 ave 20 max 16 min -Histogram: 1 0 1 0 0 1 0 0 0 1 -Neighs: 14 ave 18 max 7 min -Histogram: 1 0 0 0 0 0 0 1 1 1 - -Total # of neighbors = 56 -Ave neighs/atom = 1.75 -Neighbor list builds = 1566 -Dangerous builds = 0 -Total wall time: 0:00:04 diff --git a/examples/body/log.27Nov18.wall2d.g++.1 b/examples/body/log.27Nov18.wall2d.g++.1 deleted file mode 100644 index 1987280bee..0000000000 --- a/examples/body/log.27Nov18.wall2d.g++.1 +++ /dev/null @@ -1,224 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# 2d rounded polygon bodies - -variable r index 4 -variable steps index 100000 -variable T index 0.5 -variable P index 0.1 -variable seed index 980411 - -units lj -dimension 2 - -atom_style body rounded/polygon 1 6 -atom_modify map array -read_data data.squares - orthogonal box = (0 0 -0.5) to (12 12 0.5) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 2 atoms - 2 bodies - -replicate $r $r 1 -replicate 4 $r 1 -replicate 4 4 1 - orthogonal box = (0 0 -0.5) to (48 48 0.5) - 1 by 1 by 1 MPI processor grid - 32 atoms - Time spent = 0.000318766 secs - -velocity all create $T ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 980411 dist gaussian mom yes rot yes - -change_box all boundary p f p - -variable cut_inner equal 0.5 -variable k_n equal 100 -variable k_na equal 2 -variable c_n equal 0.1 -variable c_t equal 0.1 -variable mu equal 0.1 -variable delta_ua equal 0.5 - -pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 0.1 ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 0.5 -pair_coeff * * ${k_n} ${k_na} -pair_coeff * * 100 ${k_na} -pair_coeff * * 100 2 - -comm_modify vel yes - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -timestep 0.001 - -#fix 1 all nve/body -#fix 1 all nvt/body temp $T $T 1.0 -fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 fixedpoint 0 0 0 - -fix 2 all enforce2d -fix 3 all wall/body/polygon 2000 50 50 yplane 0.0 48.0 - -#compute 1 all body/local id 1 2 3 -#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] - -thermo_style custom step ke pe etotal press -thermo 1000 - -#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 -#dump_modify 2 pad 6 - -run ${steps} -run 100000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 6.15685 - ghost atom cutoff = 6.15685 - binsize = 3.07843, bins = 16 16 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair body/rounded/polygon, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.771 | 4.771 | 4.771 Mbytes -Step KinEng PotEng TotEng Press - 0 0.484375 0.25 0.734375 0.0067274306 - 1000 0.51467204 0.00099202506 0.51566407 0.013452386 - 2000 0.55674899 0.0040762275 0.56082522 0.0034529066 - 3000 0.7546177 0.02259362 0.77721132 0.003650781 - 4000 0.72710218 0.10284108 0.82994326 0.0059629371 - 5000 0.5771012 0.069052145 0.64615335 0.00053937622 - 6000 0.53848154 0.041891239 0.58037277 0.0018693312 - 7000 0.61777556 0.033379829 0.65115538 0.0027584418 - 8000 0.47427227 0.059558934 0.5338312 0.017087187 - 9000 0.46822364 0.064382578 0.53260622 0.023258465 - 10000 0.46511051 0.027799371 0.49290988 0.015319493 - 11000 0.58686703 0.088016891 0.67488392 0.0088428936 - 12000 0.49962603 0.09879099 0.59841702 0.00074311497 - 13000 0.53160049 0.069625775 0.60122626 0.017019775 - 14000 0.49574902 0.041214164 0.53696318 0.0060355978 - 15000 0.56620415 0.13621516 0.70241931 0.045583297 - 16000 0.40942564 0.11469877 0.52412441 0.029905784 - 17000 0.608066 0.096938921 0.70500493 0.018509814 - 18000 0.45622168 0.057018077 0.51323975 0.0034035281 - 19000 0.48763322 0.057832224 0.54546545 0.0022972169 - 20000 0.41577025 0.14480819 0.56057844 0.023882542 - 21000 0.58565738 0.1601676 0.74582498 0.01702799 - 22000 0.60430354 0.16740706 0.7717106 -0.0047632836 - 23000 0.45659601 0.13740896 0.59400497 0.0191143 - 24000 0.42741367 0.25490516 0.68231884 0.051459175 - 25000 0.40851048 0.077823072 0.48633355 0.024392284 - 26000 0.53392894 0.14504323 0.67897217 0.028964572 - 27000 0.39775205 0.13101153 0.52876358 0.0080564916 - 28000 0.63138106 0.17706612 0.80844718 0.017594524 - 29000 0.57897788 0.26855503 0.84753292 0.019310624 - 30000 0.37401002 0.2274666 0.60147663 0.0044804008 - 31000 0.60924323 0.23142663 0.84066986 0.088271242 - 32000 0.60310397 0.35719837 0.96030234 0.0096762289 - 33000 0.47468105 0.17727177 0.65195282 0.0078486602 - 34000 0.42270829 0.20131235 0.62402064 0.090216203 - 35000 0.49578606 0.1697981 0.66558416 0.079099134 - 36000 0.50744538 0.29600416 0.80344954 0.018819487 - 37000 0.66728184 0.28166655 0.94894838 -0.01679437 - 38000 0.38972905 0.25798163 0.64771068 0.040442456 - 39000 0.38292839 0.21774389 0.60067228 0.016754932 - 40000 0.61770336 0.34202184 0.9597252 0.10986262 - 41000 0.42252651 0.13424708 0.5567736 0.040987711 - 42000 0.67513868 0.29515562 0.9702943 0.0013757417 - 43000 0.36768915 0.20349753 0.57118668 0.031443504 - 44000 0.49371025 0.095615653 0.5893259 0.032289477 - 45000 0.42144079 0.28894639 0.71038718 0.040302569 - 46000 0.36360136 0.33117431 0.69477567 0.010881881 - 47000 0.4206309 0.19557595 0.61620685 0.051137535 - 48000 0.4131465 0.37027912 0.78342561 0.11903042 - 49000 0.544703 0.38013565 0.92483865 0.054939742 - 50000 0.47394272 0.32384493 0.79778764 0.088363602 - 51000 0.55377533 0.38103395 0.93480927 0.097981664 - 52000 0.60648433 0.30877364 0.91525797 0.088877781 - 53000 0.62933509 0.33187159 0.96120668 0.10275954 - 54000 0.55077522 0.39050008 0.94127529 0.066721412 - 55000 0.41646397 0.34545572 0.76191969 0.011056796 - 56000 0.44244954 0.39274744 0.83519698 0.039963853 - 57000 0.41963092 0.33483982 0.75447073 0.032555938 - 58000 0.37941475 0.36905323 0.74846798 0.043952263 - 59000 0.53008564 0.32843795 0.85852359 0.080787301 - 60000 0.43408908 0.19840268 0.63249176 0.06421165 - 61000 0.56287814 0.31500577 0.87788391 0.12031895 - 62000 0.5185192 0.18275672 0.70127592 -0.0086212356 - 63000 0.57275413 0.45147395 1.0242281 0.054617465 - 64000 0.28322907 0.33687722 0.62010629 0.07268947 - 65000 0.40230876 0.37989067 0.78219943 -0.029604066 - 66000 0.58601209 0.52721274 1.1132248 -0.00037054404 - 67000 0.52669356 0.44276199 0.96945554 0.18969356 - 68000 0.41566831 0.47320489 0.8888732 0.040635264 - 69000 0.52140574 0.4261935 0.94759923 0.016566201 - 70000 0.42034133 0.55867009 0.97901142 0.047465899 - 71000 0.48720036 0.43749264 0.924693 0.15984789 - 72000 0.5244238 0.55854139 1.0829652 0.10155994 - 73000 0.69990219 0.57313852 1.2730407 0.11108648 - 74000 0.38274347 0.23359664 0.61634011 0.027968087 - 75000 0.47493369 0.49472607 0.96965976 0.10961568 - 76000 0.57064727 0.37996383 0.9506111 0.034746271 - 77000 0.50401727 0.34437588 0.84839315 0.015116686 - 78000 0.59504118 0.44154772 1.0365889 0.059341875 - 79000 0.4920801 0.58935767 1.0814378 0.12139906 - 80000 0.56992818 0.38916606 0.95909424 0.073618074 - 81000 0.38446945 0.77314417 1.1576136 0.12173381 - 82000 0.48734531 0.56198203 1.0493273 0.1080115 - 83000 0.5516933 0.56743096 1.1191243 0.13936805 - 84000 0.53336893 0.62914863 1.1625176 0.0084970895 - 85000 0.46456977 0.77446084 1.2390306 0.18024688 - 86000 0.58067599 0.53109608 1.1117721 0.012492021 - 87000 0.55096446 0.61715622 1.1681207 0.13264723 - 88000 0.56548774 0.74463701 1.3101247 0.14491188 - 89000 0.52492634 0.58482194 1.1097483 0.21155245 - 90000 0.64973565 0.85514474 1.5048804 0.036911953 - 91000 0.55367722 0.74046971 1.2941469 0.23918851 - 92000 0.44863249 0.56773761 1.0163701 0.00042860088 - 93000 0.64728356 0.66594086 1.3132244 0.0022850006 - 94000 0.65255497 0.82136644 1.4739214 0.10037643 - 95000 0.62266654 0.82642147 1.449088 0.11964602 - 96000 0.50656004 0.83312844 1.3396885 0.078491084 - 97000 0.47126712 0.70469684 1.175964 0.12956056 - 98000 0.48661103 1.0121726 1.4987837 0.043537851 - 99000 0.48379797 0.9520931 1.4358911 0.082047522 - 100000 0.54266361 1.0959698 1.6386334 -0.13092175 -Loop time of 3.8532 on 1 procs for 100000 steps with 32 atoms - -Performance: 2242290.202 tau/day, 25952.433 timesteps/s -98.8% CPU use with 1 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 2.3917 | 2.3917 | 2.3917 | 0.0 | 62.07 -Neigh | 0.012386 | 0.012386 | 0.012386 | 0.0 | 0.32 -Comm | 0.11307 | 0.11307 | 0.11307 | 0.0 | 2.93 -Output | 0.0010369 | 0.0010369 | 0.0010369 | 0.0 | 0.03 -Modify | 1.246 | 1.246 | 1.246 | 0.0 | 32.34 -Other | | 0.08895 | | | 2.31 - -Nlocal: 32 ave 32 max 32 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 21 ave 21 max 21 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 55 ave 55 max 55 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 55 -Ave neighs/atom = 1.71875 -Neighbor list builds = 2886 -Dangerous builds = 0 -Total wall time: 0:00:03 diff --git a/examples/body/log.27Nov18.wall2d.g++.4 b/examples/body/log.27Nov18.wall2d.g++.4 deleted file mode 100644 index d9a27cb1e4..0000000000 --- a/examples/body/log.27Nov18.wall2d.g++.4 +++ /dev/null @@ -1,224 +0,0 @@ -LAMMPS (27 Nov 2018) - using 1 OpenMP thread(s) per MPI task -# 2d rounded polygon bodies - -variable r index 4 -variable steps index 100000 -variable T index 0.5 -variable P index 0.1 -variable seed index 980411 - -units lj -dimension 2 - -atom_style body rounded/polygon 1 6 -atom_modify map array -read_data data.squares - orthogonal box = (0 0 -0.5) to (12 12 0.5) - 2 by 2 by 1 MPI processor grid - reading atoms ... - 2 atoms - 2 bodies - -replicate $r $r 1 -replicate 4 $r 1 -replicate 4 4 1 - orthogonal box = (0 0 -0.5) to (48 48 0.5) - 2 by 2 by 1 MPI processor grid - 32 atoms - Time spent = 0.000329733 secs - -velocity all create $T ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 ${seed} dist gaussian mom yes rot yes -velocity all create 0.5 980411 dist gaussian mom yes rot yes - -change_box all boundary p f p - -variable cut_inner equal 0.5 -variable k_n equal 100 -variable k_na equal 2 -variable c_n equal 0.1 -variable c_t equal 0.1 -variable mu equal 0.1 -variable delta_ua equal 0.5 - -pair_style body/rounded/polygon ${c_n} ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 ${c_t} ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 ${mu} ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 0.1 ${delta_ua} ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 ${cut_inner} -pair_style body/rounded/polygon 0.1 0.1 0.1 0.5 0.5 -pair_coeff * * ${k_n} ${k_na} -pair_coeff * * 100 ${k_na} -pair_coeff * * 100 2 - -comm_modify vel yes - -neighbor 0.5 bin -neigh_modify every 1 delay 0 check yes - -timestep 0.001 - -#fix 1 all nve/body -#fix 1 all nvt/body temp $T $T 1.0 -fix 1 all npt/body temp $T $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 $T 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 $P 1.0 fixedpoint 0 0 0 -fix 1 all npt/body temp 0.5 0.5 1.0 x 0.001 0.1 1.0 fixedpoint 0 0 0 - -fix 2 all enforce2d -fix 3 all wall/body/polygon 2000 50 50 yplane 0.0 48.0 - -#compute 1 all body/local id 1 2 3 -#dump 1 all local 100000 dump.polygon.* index c_1[1] c_1[2] c_1[3] c_1[4] - -thermo_style custom step ke pe etotal press -thermo 1000 - -#dump 2 all image 10000 image.*.jpg type type zoom 2.0 # adiam 1.5 body type 0 0 -#dump_modify 2 pad 6 - -run ${steps} -run 100000 -Neighbor list info ... - update every 1 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 6.15685 - ghost atom cutoff = 6.15685 - binsize = 3.07843, bins = 16 16 1 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair body/rounded/polygon, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/2d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 4.773 | 4.773 | 4.773 Mbytes -Step KinEng PotEng TotEng Press - 0 0.484375 0.25 0.734375 0.0067274306 - 1000 0.51467204 0.00099202506 0.51566407 0.013452386 - 2000 0.55674899 0.0040762275 0.56082522 0.0034529066 - 3000 0.7546177 0.02259362 0.77721132 0.003650781 - 4000 0.72710218 0.10284108 0.82994326 0.0059629371 - 5000 0.57710119 0.069052154 0.64615335 0.00053937664 - 6000 0.53848104 0.041891152 0.58037219 0.0018693259 - 7000 0.61777485 0.033380825 0.65115568 0.0027584782 - 8000 0.47427732 0.059553658 0.53383098 0.017087698 - 9000 0.46820943 0.064379697 0.53258913 0.02325702 - 10000 0.46605511 0.02332689 0.489382 0.013699209 - 11000 0.57547516 0.090133398 0.66560855 0.0083913962 - 12000 0.465348 0.084853345 0.55020135 0.006231552 - 13000 0.55340889 0.07116165 0.62457054 0.030622563 - 14000 0.58866362 0.052281859 0.64094548 0.0079106838 - 15000 0.51757672 0.12255618 0.6401329 0.014005369 - 16000 0.42696011 0.086987541 0.51394765 -0.0017128649 - 17000 0.37612579 0.13054778 0.50667357 0.0046284992 - 18000 0.47659682 0.14670523 0.62330205 0.02206928 - 19000 0.47897909 0.15540332 0.63438241 0.02544138 - 20000 0.59377323 0.15357757 0.7473508 0.030262926 - 21000 0.52781204 0.22074491 0.74855695 -0.0022170167 - 22000 0.44843285 0.12779345 0.5762263 0.0097268482 - 23000 0.60400735 0.18098124 0.78498858 0.05778325 - 24000 0.58254338 0.1570243 0.73956769 0.022530491 - 25000 0.60524318 0.23660272 0.8418459 0.062530421 - 26000 0.45892702 0.34294121 0.80186823 0.038657393 - 27000 0.58418023 0.19551937 0.7796996 -0.0055396645 - 28000 0.45655369 0.26718934 0.72374303 0.006593108 - 29000 0.50277299 0.1747088 0.67748179 0.016059369 - 30000 0.38640717 0.1631573 0.54956447 0.036055723 - 31000 0.46944541 0.22076826 0.69021367 0.014334038 - 32000 0.53862858 0.26867594 0.80730452 0.057406282 - 33000 0.45666352 0.21796554 0.67462906 0.056555205 - 34000 0.51644038 0.21866786 0.73510824 0.015713 - 35000 0.50489584 0.1596236 0.66451945 0.040400644 - 36000 0.41723489 0.16227853 0.57951342 0.02863261 - 37000 0.481638 0.28830624 0.76994424 0.038381986 - 38000 0.6036094 0.33479287 0.93840227 0.0032059452 - 39000 0.47822122 0.18876355 0.66698476 0.029252649 - 40000 0.54949607 0.35011086 0.89960693 0.093909148 - 41000 0.54876522 0.27501735 0.82378257 -0.0084167014 - 42000 0.67801592 0.18102522 0.85904114 -0.0058395209 - 43000 0.54342066 0.34322081 0.88664146 0.12263806 - 44000 0.46672513 0.29749157 0.76421671 0.051073701 - 45000 0.4679867 0.25820875 0.72619545 0.069790993 - 46000 0.59598501 0.22285276 0.81883777 0.050578807 - 47000 0.48858341 0.29811577 0.78669917 0.080971431 - 48000 0.41238073 0.29362937 0.7060101 0.031893588 - 49000 0.61516435 0.33082609 0.94599044 -0.010710982 - 50000 0.57576635 0.37137185 0.94713819 0.062160249 - 51000 0.54614001 0.36960628 0.91574629 -0.0083424769 - 52000 0.42232354 0.25214442 0.67446796 0.028666126 - 53000 0.43025129 0.24479385 0.67504514 0.030342054 - 54000 0.54614922 0.29602426 0.84217348 0.083070642 - 55000 0.60719748 0.3577285 0.96492598 0.053799744 - 56000 0.47073149 0.31070429 0.78143579 0.083895368 - 57000 0.56861582 0.33249784 0.90111366 0.032324233 - 58000 0.75061035 0.33313728 1.0837476 0.031039937 - 59000 0.59473893 0.48870773 1.0834467 0.039503585 - 60000 0.55252481 0.38350562 0.93603043 0.0027643882 - 61000 0.45010855 0.43945065 0.8895592 0.028168222 - 62000 0.63942467 0.53372899 1.1731537 0.13790959 - 63000 0.69407873 0.37980402 1.0738828 0.035919608 - 64000 0.54898275 0.39910419 0.94808693 0.0015016851 - 65000 0.58229838 0.42300361 1.005302 0.089787193 - 66000 0.53443537 0.5597136 1.094149 -0.015781756 - 67000 0.59212426 0.56172146 1.1538457 0.030464683 - 68000 0.68164926 0.48724393 1.1688932 0.071465948 - 69000 0.59721737 0.49476309 1.0919805 0.07575647 - 70000 0.52314551 0.31950477 0.84265028 0.11206672 - 71000 0.53230509 0.53846575 1.0707708 0.0047204701 - 72000 0.71341933 0.4924749 1.2058942 0.116568 - 73000 0.70498496 0.54121008 1.246195 0.11210249 - 74000 0.54188682 0.61729607 1.1591829 0.044083048 - 75000 0.44073609 0.42072284 0.86145893 -0.041508511 - 76000 0.51225567 0.36848317 0.88073884 -0.028636748 - 77000 0.6517329 0.5503086 1.2020415 0.049605026 - 78000 0.60053898 0.52760266 1.1281416 0.094361256 - 79000 0.51560788 0.46563043 0.98123832 -0.03336136 - 80000 0.53357884 0.60743981 1.1410186 0.027259883 - 81000 0.6256228 0.40412923 1.029752 0.083274981 - 82000 0.6903519 0.69599412 1.386346 0.168747 - 83000 0.62621394 0.50082841 1.1270424 0.12294403 - 84000 0.5682146 0.73827702 1.3064916 0.085884707 - 85000 0.48179077 0.73669563 1.2184864 0.065002035 - 86000 0.61101399 0.80673836 1.4177523 0.037555163 - 87000 0.52278725 0.71608722 1.2388745 0.020943688 - 88000 0.53318823 0.50916748 1.0423557 -0.01946691 - 89000 0.56428713 0.56042234 1.1247095 0.040998134 - 90000 0.58720508 0.66023073 1.2474358 0.040313529 - 91000 0.61509407 0.86254343 1.4776375 0.15215034 - 92000 0.5640475 0.57694543 1.1409929 0.10238679 - 93000 0.60586378 0.67978456 1.2856483 -0.043948113 - 94000 0.75406595 0.74795347 1.5020194 0.015341415 - 95000 0.4974314 0.60192267 1.0993541 -0.018173218 - 96000 0.50048302 0.82845218 1.3289352 0.045394283 - 97000 0.65335222 0.6470855 1.3004377 0.011624967 - 98000 0.65693072 0.45222133 1.109152 0.13763684 - 99000 0.60573344 0.50284289 1.1085763 0.12853674 - 100000 0.50677068 0.58143063 1.0882013 0.11351254 -Loop time of 3.24642 on 4 procs for 100000 steps with 32 atoms - -Performance: 2661396.711 tau/day, 30803.203 timesteps/s -94.4% CPU use with 4 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0.64148 | 0.70244 | 0.76391 | 6.5 | 21.64 -Neigh | 0.0049012 | 0.0050417 | 0.0052478 | 0.2 | 0.16 -Comm | 0.79447 | 0.88412 | 0.97443 | 8.1 | 27.23 -Output | 0.001776 | 0.0031438 | 0.0072262 | 4.2 | 0.10 -Modify | 1.325 | 1.3684 | 1.4049 | 2.4 | 42.15 -Other | | 0.2833 | | | 8.73 - -Nlocal: 8 ave 9 max 7 min -Histogram: 1 0 0 0 0 2 0 0 0 1 -Nghost: 14 ave 15 max 13 min -Histogram: 1 0 0 0 0 2 0 0 0 1 -Neighs: 13.25 ave 16 max 11 min -Histogram: 1 0 1 0 0 0 1 0 0 1 - -Total # of neighbors = 53 -Ave neighs/atom = 1.65625 -Neighbor list builds = 2654 -Dangerous builds = 0 -Total wall time: 0:00:03 From 4faebaf4ed32aae48f5a4f531821362913b91118 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 14:53:06 -0400 Subject: [PATCH 419/448] add log files for fix pimd/langevin --- .../data.metalnpt01 | 0 .../data.metalnpt02 | 0 .../data.metalnpt03 | 0 .../data.metalnpt04 | 0 .../pimd/{lj => langevin_metal_units}/in.lmp | 6 +- .../log.14Jun23.langevin.metal.g++ | 2 + .../log.14Jun23.langevin.metal.g++.0 | 106 ++++++++++++++++++ .../log.14Jun23.langevin.metal.g++.1 | 106 ++++++++++++++++++ .../log.14Jun23.langevin.metal.g++.2 | 106 ++++++++++++++++++ .../log.14Jun23.langevin.metal.g++.3 | 106 ++++++++++++++++++ .../pimd/{lj => langevin_metal_units}/run.sh | 0 .../data.lj01 | 0 .../data.lj02 | 0 .../in.lmp | 6 +- .../log.14Jun23.langevin.reduced.g++ | 2 + .../log.14Jun23.langevin.reduced.g++.0 | 97 ++++++++++++++++ .../log.14Jun23.langevin.reduced.g++.1 | 97 ++++++++++++++++ .../run.sh | 0 18 files changed, 628 insertions(+), 6 deletions(-) rename examples/PACKAGES/pimd/{lj => langevin_metal_units}/data.metalnpt01 (100%) rename examples/PACKAGES/pimd/{lj => langevin_metal_units}/data.metalnpt02 (100%) rename examples/PACKAGES/pimd/{lj => langevin_metal_units}/data.metalnpt03 (100%) rename examples/PACKAGES/pimd/{lj => langevin_metal_units}/data.metalnpt04 (100%) rename examples/PACKAGES/pimd/{lj => langevin_metal_units}/in.lmp (56%) create mode 100644 examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++ create mode 100644 examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.0 create mode 100644 examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.1 create mode 100644 examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.2 create mode 100644 examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.3 rename examples/PACKAGES/pimd/{lj => langevin_metal_units}/run.sh (100%) rename examples/PACKAGES/pimd/{lj_reduced_units => langevin_reduced_units}/data.lj01 (100%) rename examples/PACKAGES/pimd/{lj_reduced_units => langevin_reduced_units}/data.lj02 (100%) rename examples/PACKAGES/pimd/{lj_reduced_units => langevin_reduced_units}/in.lmp (56%) create mode 100644 examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++ create mode 100644 examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.0 create mode 100644 examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.1 rename examples/PACKAGES/pimd/{lj_reduced_units => langevin_reduced_units}/run.sh (100%) diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt01 b/examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt01 similarity index 100% rename from examples/PACKAGES/pimd/lj/data.metalnpt01 rename to examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt01 diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt02 b/examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt02 similarity index 100% rename from examples/PACKAGES/pimd/lj/data.metalnpt02 rename to examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt02 diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt03 b/examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt03 similarity index 100% rename from examples/PACKAGES/pimd/lj/data.metalnpt03 rename to examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt03 diff --git a/examples/PACKAGES/pimd/lj/data.metalnpt04 b/examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt04 similarity index 100% rename from examples/PACKAGES/pimd/lj/data.metalnpt04 rename to examples/PACKAGES/pimd/langevin_metal_units/data.metalnpt04 diff --git a/examples/PACKAGES/pimd/lj/in.lmp b/examples/PACKAGES/pimd/langevin_metal_units/in.lmp similarity index 56% rename from examples/PACKAGES/pimd/lj/in.lmp rename to examples/PACKAGES/pimd/langevin_metal_units/in.lmp index 9670225958..124063df99 100644 --- a/examples/PACKAGES/pimd/lj/in.lmp +++ b/examples/PACKAGES/pimd/langevin_metal_units/in.lmp @@ -20,9 +20,9 @@ fix 1 all pimd/langevin ensemble npt integrator obabo thermostat PILE_L 1234 tau thermo_style custom step temp f_1[*] vol press thermo 100 -thermo_modify norm no format line "%d %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f" +thermo_modify norm no -dump dcd all custom 100 ${ibead}.xyz id type xu yu zu vx vy vz ix iy iz fx fy fz -dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" +# dump dcd all custom 100 ${ibead}.dcd id type xu yu zu vx vy vz ix iy iz fx fy fz +# dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" run 1000 diff --git a/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++ b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++ new file mode 100644 index 0000000000..fa22106766 --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++ @@ -0,0 +1,2 @@ +LAMMPS (28 Mar 2023) +Running on 4 partitions of processors diff --git a/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.0 b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.0 new file mode 100644 index 0000000000..00787df8ba --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.0 @@ -0,0 +1,106 @@ +LAMMPS (28 Mar 2023) +Processor partition = 0 + using 1 OpenMP thread(s) per MPI task +variable ibead uloop 99 pad + +units metal +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 9.5251 +read_data data.metalnpt${ibead} +read_data data.metalnpt01 +Reading data file ... + orthogonal box = (-11.876697 -11.876697 -11.876697) to (11.876697 11.876697 11.876697) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 200 atoms + reading velocities ... + 200 velocities + read_data CPU = 0.001 seconds + +pair_coeff * * 0.00965188 3.4 +pair_modify shift yes + +mass 1 39.948 + +timestep 0.001 + +velocity all create 0.0 ${ibead} +velocity all create 0.0 01 + +fix 1 all pimd/langevin ensemble npt integrator obabo thermostat PILE_L 1234 tau 1.0 temp 113.15 iso 1.0 barostat BZP taup 1.0 fixcom no + +Initializing PIMD BZP barostat... +The barostat mass is W = 2.3401256650800001e+01 + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no + +# dump dcd all custom 100 ${ibead}.dcd id type xu yu zu vx vy vz ix iy iz fx fy fz +# dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule + +Initializing PI Langevin equation thermostat... +Bead ID | omega | tau | c1 | c2 + 0 0.00000000e+00 1.00000000e+00 9.99500125e-01 3.16148726e-02 + 1 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 + 2 1.18509233e+02 4.21908054e-03 8.88243614e-01 4.59372705e-01 + 3 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 +PILE_L thermostat successfully initialized! + +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 11.5251 + ghost atom cutoff = 11.5251 + binsize = 5.76255, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.121 | 3.121 | 3.121 Mbytes + Step Temp f_1[1] f_1[2] f_1[3] f_1[4] f_1[5] f_1[6] f_1[7] f_1[8] f_1[9] f_1[10] f_1[11] f_1[12] f_1[13] f_1[14] f_1[15] Volume Press + 0 0 0 0 -7.3046601 4.3005229 -21.877018 -8.7249482 2.9571502 -1743.5332 -698.49808 -172.07477 0 0 0.033460054 -0.37064378 4.216227 13402.228 -164.47373 + 100 149.95804 3.8573359 0 -7.7921375 42.886648 -23.396327 -1.980193 2.954003 -1888.0547 -1648.7118 -332.0298 -0.099139345 0.11500091 0.033044702 -0.3701566 42.83112 13235.861 -101.30374 + 200 245.00113 6.3021074 0 -8.2639651 41.690123 -22.521598 -4.273021 2.9600599 -1906.2904 -1609.02 -265.94404 -0.20527926 0.49305948 0.031504957 -0.36829556 41.729191 12619.125 112.22426 + 300 300.57486 7.7316177 0 -8.2986331 43.180131 -21.755813 -7.7032433 2.9714114 -1968.7685 290.49656 251.72564 -0.21935745 0.56300721 0.029467915 -0.36568855 43.236828 11803.2 814.45889 + 400 368.08438 9.4681493 0 -8.4800193 49.109699 -24.824142 2.9744597 2.9794185 -2335.993 1368.7398 570.03286 -0.028366234 0.0094148316 0.028338146 -0.36416383 49.028096 11350.678 1202.0398 + 500 419.32066 10.786088 0 -8.640773 45.427771 -22.825143 16.22356 2.9684828 -2113.91 -272.84753 185.53392 0.091614289 0.098205455 0.028793585 -0.36478567 45.368325 11533.101 952.59748 + 600 385.4127 9.9138817 0 -8.4356035 47.783726 -22.456104 6.837575 2.967236 -2023.8117 -918.27943 -2.4106994 0.093360761 0.10198539 0.029589188 -0.36584873 47.725157 11851.775 676.62913 + 700 360.14242 9.2638601 0 -8.2900275 42.626187 -20.571698 -5.7252564 2.9560528 -1806.9448 -1418.2247 -148.41657 0.075011202 0.065835696 0.030359455 -0.36685105 42.558523 12160.301 456.91446 + 800 346.92167 8.923786 0 -8.0694169 45.160336 -21.885719 -6.7745694 2.9575472 -1894.3641 -1329.3179 -136.42193 0.011114896 0.0014455064 0.030808183 -0.3674233 45.076543 12340.037 454.60123 + 900 364.39442 9.3732334 0 -8.0415668 45.604542 -21.816625 5.586068 2.9578604 -1890.4653 -1271.1107 -111.89061 -0.020285587 0.0048148677 0.030774258 -0.36738033 45.521594 12326.448 499.75868 + 1000 390.77042 10.051697 0 -8.1948009 45.264242 -22.833545 6.9260573 2.960122 -2007.6188 -1179.7125 -70.907567 -0.062733519 0.046047757 0.030329191 -0.36681215 45.191633 12148.179 572.98799 +Loop time of 0.248186 on 1 procs for 1000 steps with 200 atoms + +Performance: 348.126 ns/day, 0.069 hours/ns, 4029.238 timesteps/s, 805.848 katom-step/s +99.6% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.14541 | 0.14541 | 0.14541 | 0.0 | 58.59 +Neigh | 0.00099082 | 0.00099082 | 0.00099082 | 0.0 | 0.40 +Comm | 0.0039966 | 0.0039966 | 0.0039966 | 0.0 | 1.61 +Output | 0.00016346 | 0.00016346 | 0.00016346 | 0.0 | 0.07 +Modify | 0.096205 | 0.096205 | 0.096205 | 0.0 | 38.76 +Other | | 0.001425 | | | 0.57 + +Nlocal: 200 ave 200 max 200 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1342 ave 1342 max 1342 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 10325 ave 10325 max 10325 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 10325 +Ave neighs/atom = 51.625 +Neighbor list builds = 4 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.1 b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.1 new file mode 100644 index 0000000000..83821cafb7 --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.1 @@ -0,0 +1,106 @@ +LAMMPS (28 Mar 2023) +Processor partition = 1 + using 1 OpenMP thread(s) per MPI task +variable ibead uloop 99 pad + +units metal +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 9.5251 +read_data data.metalnpt${ibead} +read_data data.metalnpt02 +Reading data file ... + orthogonal box = (-11.876697 -11.876697 -11.876697) to (11.876697 11.876697 11.876697) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 200 atoms + reading velocities ... + 200 velocities + read_data CPU = 0.001 seconds + +pair_coeff * * 0.00965188 3.4 +pair_modify shift yes + +mass 1 39.948 + +timestep 0.001 + +velocity all create 0.0 ${ibead} +velocity all create 0.0 02 + +fix 1 all pimd/langevin ensemble npt integrator obabo thermostat PILE_L 1234 tau 1.0 temp 113.15 iso 1.0 barostat BZP taup 1.0 fixcom no + +Initializing PIMD BZP barostat... +The barostat mass is W = 2.3401256650800001e+01 + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no + +# dump dcd all custom 100 ${ibead}.dcd id type xu yu zu vx vy vz ix iy iz fx fy fz +# dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule + +Initializing PI Langevin equation thermostat... +Bead ID | omega | tau | c1 | c2 + 0 0.00000000e+00 1.00000000e+00 9.99500125e-01 3.16148726e-02 + 1 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 + 2 1.18509233e+02 4.21908054e-03 8.88243614e-01 4.59372705e-01 + 3 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 +PILE_L thermostat successfully initialized! + +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 11.5251 + ghost atom cutoff = 11.5251 + binsize = 5.76255, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.121 | 3.121 | 3.121 Mbytes + Step Temp f_1[1] f_1[2] f_1[3] f_1[4] f_1[5] f_1[6] f_1[7] f_1[8] f_1[9] f_1[10] f_1[11] f_1[12] f_1[13] f_1[14] f_1[15] Volume Press + 0 0 0 11.920908 -7.3063682 4.3005229 -21.877018 -8.7249482 2.9571502 -1743.5332 -698.49808 -172.07477 0 0 0.033460054 -0.37064378 4.216227 13402.228 -167.65544 + 100 483.61933 12.440028 11.405863 -7.7749671 42.886648 -23.396327 -1.980193 2.954003 -1888.0547 -1648.7118 -332.0298 -0.099139345 0.11500091 0.033044702 -0.3701566 42.83112 13235.861 606.14668 + 200 452.03836 11.627678 11.47094 -8.2534927 41.690123 -22.521598 -4.273021 2.9600599 -1906.2904 -1609.02 -265.94404 -0.20527926 0.49305948 0.031504957 -0.36829556 41.729191 12619.125 583.5476 + 300 470.25997 12.096389 11.739306 -8.3750153 43.180131 -21.755813 -7.7032433 2.9714114 -1968.7685 290.49656 251.72564 -0.21935745 0.56300721 0.029467915 -0.36568855 43.236828 11803.2 1152.6851 + 400 459.46597 11.818737 12.502421 -8.5240576 49.109699 -24.824142 2.9744597 2.9794185 -2335.993 1368.7398 570.03286 -0.028366234 0.0094148316 0.028338146 -0.36416383 49.028096 11350.678 1381.0251 + 500 442.73121 11.388273 11.19396 -8.6488583 45.427771 -22.825143 16.22356 2.9684828 -2113.91 -272.84753 185.53392 0.091614289 0.098205455 0.028793585 -0.36478567 45.368325 11533.101 1000.6119 + 600 493.47034 12.693424 11.91335 -8.4625706 47.783726 -22.456104 6.837575 2.967236 -2023.8117 -918.27943 -2.4106994 0.093360761 0.10198539 0.029589188 -0.36584873 47.725157 11851.775 904.52944 + 700 470.04548 12.090871 10.348757 -8.278182 42.626187 -20.571698 -5.7252564 2.9560528 -1806.9448 -1418.2247 -148.41657 0.075011202 0.065835696 0.030359455 -0.36685105 42.558523 12160.301 715.22796 + 800 458.04928 11.782296 11.152029 -8.0926613 45.160336 -21.885719 -6.7745694 2.9575472 -1894.3641 -1329.3179 -136.42193 0.011114896 0.0014455064 0.030808183 -0.3674233 45.076543 12340.037 678.21261 + 900 468.60547 12.05383 10.937315 -8.0319335 45.604542 -21.816625 5.586068 2.9578604 -1890.4653 -1271.1107 -111.89061 -0.020285587 0.0048148677 0.030774258 -0.36738033 45.521594 12326.448 735.24377 + 1000 427.44192 10.99499 11.916587 -8.2229199 45.264242 -22.833545 6.9260573 2.960122 -2007.6188 -1179.7125 -70.907567 -0.062733519 0.046047757 0.030329191 -0.36681215 45.191633 12148.179 637.98311 +Loop time of 0.248186 on 1 procs for 1000 steps with 200 atoms + +Performance: 348.126 ns/day, 0.069 hours/ns, 4029.238 timesteps/s, 805.848 katom-step/s +99.5% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.14654 | 0.14654 | 0.14654 | 0.0 | 59.04 +Neigh | 0.00099986 | 0.00099986 | 0.00099986 | 0.0 | 0.40 +Comm | 0.0041628 | 0.0041628 | 0.0041628 | 0.0 | 1.68 +Output | 0.00018019 | 0.00018019 | 0.00018019 | 0.0 | 0.07 +Modify | 0.094878 | 0.094878 | 0.094878 | 0.0 | 38.23 +Other | | 0.001424 | | | 0.57 + +Nlocal: 200 ave 200 max 200 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1346 ave 1346 max 1346 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 10328 ave 10328 max 10328 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 10328 +Ave neighs/atom = 51.64 +Neighbor list builds = 4 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.2 b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.2 new file mode 100644 index 0000000000..fd8dd409ae --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.2 @@ -0,0 +1,106 @@ +LAMMPS (28 Mar 2023) +Processor partition = 2 + using 1 OpenMP thread(s) per MPI task +variable ibead uloop 99 pad + +units metal +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 9.5251 +read_data data.metalnpt${ibead} +read_data data.metalnpt03 +Reading data file ... + orthogonal box = (-11.876697 -11.876697 -11.876697) to (11.876697 11.876697 11.876697) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 200 atoms + reading velocities ... + 200 velocities + read_data CPU = 0.001 seconds + +pair_coeff * * 0.00965188 3.4 +pair_modify shift yes + +mass 1 39.948 + +timestep 0.001 + +velocity all create 0.0 ${ibead} +velocity all create 0.0 03 + +fix 1 all pimd/langevin ensemble npt integrator obabo thermostat PILE_L 1234 tau 1.0 temp 113.15 iso 1.0 barostat BZP taup 1.0 fixcom no + +Initializing PIMD BZP barostat... +The barostat mass is W = 2.3401256650800001e+01 + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no + +# dump dcd all custom 100 ${ibead}.dcd id type xu yu zu vx vy vz ix iy iz fx fy fz +# dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule + +Initializing PI Langevin equation thermostat... +Bead ID | omega | tau | c1 | c2 + 0 0.00000000e+00 1.00000000e+00 9.99500125e-01 3.16148726e-02 + 1 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 + 2 1.18509233e+02 4.21908054e-03 8.88243614e-01 4.59372705e-01 + 3 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 +PILE_L thermostat successfully initialized! + +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 11.5251 + ghost atom cutoff = 11.5251 + binsize = 5.76255, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.121 | 3.121 | 3.121 Mbytes + Step Temp f_1[1] f_1[2] f_1[3] f_1[4] f_1[5] f_1[6] f_1[7] f_1[8] f_1[9] f_1[10] f_1[11] f_1[12] f_1[13] f_1[14] f_1[15] Volume Press + 0 0 0 10.862314 -7.320388 4.3005229 -21.877018 -8.7249482 2.9571502 -1743.5332 -698.49808 -172.07477 0 0 0.033460054 -0.37064378 4.216227 13402.228 -175.34503 + 100 455.18121 11.708521 11.48472 -7.8033686 42.886648 -23.396327 -1.980193 2.954003 -1888.0547 -1648.7118 -332.0298 -0.099139345 0.11500091 0.033044702 -0.3701566 42.83112 13235.861 526.41632 + 200 460.81997 11.853566 10.817157 -8.2276485 41.690123 -22.521598 -4.273021 2.9600599 -1906.2904 -1609.02 -265.94404 -0.20527926 0.49305948 0.031504957 -0.36829556 41.729191 12619.125 615.80924 + 300 481.48652 12.385166 10.035423 -8.3866916 43.180131 -21.755813 -7.7032433 2.9714114 -1968.7685 290.49656 251.72564 -0.21935745 0.56300721 0.029467915 -0.36568855 43.236828 11803.2 1169.2917 + 400 487.3584 12.536208 11.766522 -8.3643382 49.109699 -24.824142 2.9744597 2.9794185 -2335.993 1368.7398 570.03286 -0.028366234 0.0094148316 0.028338146 -0.36416383 49.028096 11350.678 1574.1427 + 500 446.36019 11.48162 12.144202 -8.680266 45.427771 -22.825143 16.22356 2.9684828 -2113.91 -272.84753 185.53392 0.091614289 0.098205455 0.028793585 -0.36478567 45.368325 11533.101 979.68395 + 600 500.3783 12.871115 11.075008 -8.47833 47.783726 -22.456104 6.837575 2.967236 -2023.8117 -918.27943 -2.4106994 0.093360761 0.10198539 0.029589188 -0.36584873 47.725157 11851.775 912.39361 + 700 435.40634 11.199857 10.923558 -8.3090105 42.626187 -20.571698 -5.7252564 2.9560528 -1806.9448 -1418.2247 -148.41657 0.075011202 0.065835696 0.030359455 -0.36685105 42.558523 12160.301 617.20857 + 800 446.82793 11.493652 11.599712 -8.0900498 45.160336 -21.885719 -6.7745694 2.9575472 -1894.3641 -1329.3179 -136.42193 0.011114896 0.0014455064 0.030808183 -0.3674233 45.076543 12340.037 652.13243 + 900 448.28506 11.531133 12.130739 -8.0810557 45.604542 -21.816625 5.586068 2.9578604 -1890.4653 -1271.1107 -111.89061 -0.020285587 0.0048148677 0.030774258 -0.36738033 45.521594 12326.448 674.68073 + 1000 440.94913 11.342433 10.765654 -8.1419484 45.264242 -22.833545 6.9260573 2.960122 -2007.6188 -1179.7125 -70.907567 -0.062733519 0.046047757 0.030329191 -0.36681215 45.191633 12148.179 730.67128 +Loop time of 0.248185 on 1 procs for 1000 steps with 200 atoms + +Performance: 348.128 ns/day, 0.069 hours/ns, 4029.259 timesteps/s, 805.852 katom-step/s +97.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.14702 | 0.14702 | 0.14702 | 0.0 | 59.24 +Neigh | 0.0010003 | 0.0010003 | 0.0010003 | 0.0 | 0.40 +Comm | 0.0039821 | 0.0039821 | 0.0039821 | 0.0 | 1.60 +Output | 0.00023527 | 0.00023527 | 0.00023527 | 0.0 | 0.09 +Modify | 0.094519 | 0.094519 | 0.094519 | 0.0 | 38.08 +Other | | 0.001427 | | | 0.58 + +Nlocal: 200 ave 200 max 200 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1346 ave 1346 max 1346 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 10313 ave 10313 max 10313 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 10313 +Ave neighs/atom = 51.565 +Neighbor list builds = 4 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.3 b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.3 new file mode 100644 index 0000000000..423ebb7d63 --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_metal_units/log.14Jun23.langevin.metal.g++.3 @@ -0,0 +1,106 @@ +LAMMPS (28 Mar 2023) +Processor partition = 3 + using 1 OpenMP thread(s) per MPI task +variable ibead uloop 99 pad + +units metal +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 9.5251 +read_data data.metalnpt${ibead} +read_data data.metalnpt04 +Reading data file ... + orthogonal box = (-11.876697 -11.876697 -11.876697) to (11.876697 11.876697 11.876697) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 200 atoms + reading velocities ... + 200 velocities + read_data CPU = 0.001 seconds + +pair_coeff * * 0.00965188 3.4 +pair_modify shift yes + +mass 1 39.948 + +timestep 0.001 + +velocity all create 0.0 ${ibead} +velocity all create 0.0 04 + +fix 1 all pimd/langevin ensemble npt integrator obabo thermostat PILE_L 1234 tau 1.0 temp 113.15 iso 1.0 barostat BZP taup 1.0 fixcom no + +Initializing PIMD BZP barostat... +The barostat mass is W = 2.3401256650800001e+01 + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no + +# dump dcd all custom 100 ${ibead}.dcd id type xu yu zu vx vy vz ix iy iz fx fy fz +# dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule + +Initializing PI Langevin equation thermostat... +Bead ID | omega | tau | c1 | c2 + 0 0.00000000e+00 1.00000000e+00 9.99500125e-01 3.16148726e-02 + 1 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 + 2 1.18509233e+02 4.21908054e-03 8.88243614e-01 4.59372705e-01 + 3 8.37986825e+01 5.96668092e-03 9.19616372e-01 3.92817678e-01 +PILE_L thermostat successfully initialized! + +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 11.5251 + ghost atom cutoff = 11.5251 + binsize = 5.76255, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.121 | 3.121 | 3.121 Mbytes + Step Temp f_1[1] f_1[2] f_1[3] f_1[4] f_1[5] f_1[6] f_1[7] f_1[8] f_1[9] f_1[10] f_1[11] f_1[12] f_1[13] f_1[14] f_1[15] Volume Press + 0 0 0 10.794425 -7.3457072 4.3005229 -21.877018 -8.7249482 2.9571502 -1743.5332 -698.49808 -172.07477 0 0 0.033460054 -0.37064378 4.216227 13402.228 -191.02389 + 100 426.01705 10.958338 12.206372 -7.8040582 42.886648 -23.396327 -1.980193 2.954003 -1888.0547 -1648.7118 -332.0298 -0.099139345 0.11500091 0.033044702 -0.3701566 42.83112 13235.861 464.39271 + 200 414.52703 10.662783 11.934129 -8.2331312 41.690123 -22.521598 -4.273021 2.9600599 -1906.2904 -1609.02 -265.94404 -0.20527926 0.49305948 0.031504957 -0.36829556 41.729191 12619.125 502.87052 + 300 424.85622 10.928478 11.681713 -8.357621 43.180131 -21.755813 -7.7032433 2.9714114 -1968.7685 290.49656 251.72564 -0.21935745 0.56300721 0.029467915 -0.36568855 43.236828 11803.2 1058.1162 + 400 485.80103 12.496148 12.255827 -8.3658975 49.109699 -24.824142 2.9744597 2.9794185 -2335.993 1368.7398 570.03286 -0.028366234 0.0094148316 0.028338146 -0.36416383 49.028096 11350.678 1570.2486 + 500 462.99006 11.909386 11.187609 -8.6934698 45.427771 -22.825143 16.22356 2.9684828 -2113.91 -272.84753 185.53392 0.091614289 0.098205455 0.028793585 -0.36478567 45.368325 11533.101 1014.2134 + 600 465.24407 11.967366 11.168375 -8.4422887 47.783726 -22.456104 6.837575 2.967236 -2023.8117 -918.27943 -2.4106994 0.093360761 0.10198539 0.029589188 -0.36584873 47.725157 11851.775 864.12413 + 700 426.16111 10.962044 11.000011 -8.2855512 42.626187 -20.571698 -5.7252564 2.9560528 -1806.9448 -1418.2247 -148.41657 0.075011202 0.065835696 0.030359455 -0.36685105 42.558523 12160.301 614.76939 + 800 454.53159 11.691811 10.834606 -8.0654281 45.160336 -21.885719 -6.7745694 2.9575472 -1894.3641 -1329.3179 -136.42193 0.011114896 0.0014455064 0.030808183 -0.3674233 45.076543 12340.037 684.85907 + 900 441.72064 11.362278 10.4492 -8.0786302 45.604542 -21.816625 5.586068 2.9578604 -1890.4653 -1271.1107 -111.89061 -0.020285587 0.0048148677 0.030774258 -0.36738033 45.521594 12326.448 659.68525 + 1000 429.90929 11.058457 11.851933 -8.1578394 45.264242 -22.833545 6.9260573 2.960122 -2007.6188 -1179.7125 -70.907567 -0.062733519 0.046047757 0.030329191 -0.36681215 45.191633 12148.179 698.73278 +Loop time of 0.248175 on 1 procs for 1000 steps with 200 atoms + +Performance: 348.141 ns/day, 0.069 hours/ns, 4029.409 timesteps/s, 805.882 katom-step/s +98.1% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.14919 | 0.14919 | 0.14919 | 0.0 | 60.12 +Neigh | 0.00099112 | 0.00099112 | 0.00099112 | 0.0 | 0.40 +Comm | 0.0040992 | 0.0040992 | 0.0040992 | 0.0 | 1.65 +Output | 0.0001723 | 0.0001723 | 0.0001723 | 0.0 | 0.07 +Modify | 0.092299 | 0.092299 | 0.092299 | 0.0 | 37.19 +Other | | 0.00142 | | | 0.57 + +Nlocal: 200 ave 200 max 200 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1346 ave 1346 max 1346 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 10332 ave 10332 max 10332 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 10332 +Ave neighs/atom = 51.66 +Neighbor list builds = 4 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/pimd/lj/run.sh b/examples/PACKAGES/pimd/langevin_metal_units/run.sh similarity index 100% rename from examples/PACKAGES/pimd/lj/run.sh rename to examples/PACKAGES/pimd/langevin_metal_units/run.sh diff --git a/examples/PACKAGES/pimd/lj_reduced_units/data.lj01 b/examples/PACKAGES/pimd/langevin_reduced_units/data.lj01 similarity index 100% rename from examples/PACKAGES/pimd/lj_reduced_units/data.lj01 rename to examples/PACKAGES/pimd/langevin_reduced_units/data.lj01 diff --git a/examples/PACKAGES/pimd/lj_reduced_units/data.lj02 b/examples/PACKAGES/pimd/langevin_reduced_units/data.lj02 similarity index 100% rename from examples/PACKAGES/pimd/lj_reduced_units/data.lj02 rename to examples/PACKAGES/pimd/langevin_reduced_units/data.lj02 diff --git a/examples/PACKAGES/pimd/lj_reduced_units/in.lmp b/examples/PACKAGES/pimd/langevin_reduced_units/in.lmp similarity index 56% rename from examples/PACKAGES/pimd/lj_reduced_units/in.lmp rename to examples/PACKAGES/pimd/langevin_reduced_units/in.lmp index 012214c4b2..80bfbe4956 100644 --- a/examples/PACKAGES/pimd/lj_reduced_units/in.lmp +++ b/examples/PACKAGES/pimd/langevin_reduced_units/in.lmp @@ -18,9 +18,9 @@ fix 1 all pimd/langevin ensemble nvt integrator obabo temp 1.00888 lj 0.00965188 thermo_style custom step temp f_1[*] vol press thermo 100 -thermo_modify norm no format line "%d %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f %.16f" +thermo_modify norm no -dump dcd all custom 1 ${ibead}.xyz id type x y z vx vy vz ix iy iz fx fy fz -dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" +#dump dcd all custom 1 ${ibead}.lammpstrj id type x y z vx vy vz ix iy iz fx fy fz +#dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" run 1000 diff --git a/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++ b/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++ new file mode 100644 index 0000000000..4ed421dddb --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++ @@ -0,0 +1,2 @@ +LAMMPS (28 Mar 2023) +Running on 2 partitions of processors diff --git a/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.0 b/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.0 new file mode 100644 index 0000000000..d219e20845 --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.0 @@ -0,0 +1,97 @@ +LAMMPS (28 Mar 2023) +Processor partition = 0 + using 1 OpenMP thread(s) per MPI task +variable ibead uloop 32 pad + +units lj +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 2.8015 +read_data data.lj${ibead} +read_data data.lj01 +Reading data file ... + orthogonal box = (-3.4945131 -3.4945131 -3.4945131) to (3.4945131 3.4945131 3.4945131) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 200 atoms + read_data CPU = 0.001 seconds + +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +mass 1 1.0 + +timestep 0.00044905847 + +fix 1 all pimd/langevin ensemble nvt integrator obabo temp 1.00888 lj 0.00965188 3.4 39.948 4.135667403e-3 1.03646168908e-4 thermostat PILE_L ${ibead} +fix 1 all pimd/langevin ensemble nvt integrator obabo temp 1.00888 lj 0.00965188 3.4 39.948 4.135667403e-3 1.03646168908e-4 thermostat PILE_L 01 + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no + +#dump dcd all custom 1 ${ibead}.lammpstrj id type x y z vx vy vz ix iy iz fx fy fz +#dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule + +Initializing PI Langevin equation thermostat... +Bead ID | omega | tau | c1 | c2 + 0 0.00000000e+00 1.00000000e+00 9.99775496e-01 2.11886210e-02 + 1 1.31777963e+02 3.79426112e-03 9.42540858e-01 3.34090903e-01 +PILE_L thermostat successfully initialized! + +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 3.1015 + ghost atom cutoff = 3.1015 + binsize = 1.55075, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.117 | 3.117 | 3.117 Mbytes + Step Temp f_1[1] f_1[2] f_1[3] f_1[4] f_1[5] f_1[6] f_1[7] f_1[8] f_1[9] f_1[10] Volume Press + 0 0 0 0 -875.67022 841866.06 -843041.14 253.30998 382.47517 -1646.2945 -1.9663356 -0.82731217 341.38937 -1.3810467 + 100 14.815998 4422.5753 0 -534.91485 5336.9805 -409.03828 7790.9787 306.80845 -0.79877176 13.250868 8.3263811 341.38937 12.561531 + 200 13.762526 4108.114 0 -535.07896 4177.1707 63.548813 -8225.489 308.68383 0.1240984 12.723365 8.0800159 341.38937 12.1757 + 300 12.566448 3751.0847 0 -493.13907 3999.3337 -31.433066 8675.7059 309.21599 -0.061382631 14.105486 8.6052841 341.38937 12.245009 + 400 11.843976 3535.4267 0 -515.14836 3784.077 -23.971605 -81.467506 309.02093 -0.046811856 13.638064 8.2470184 341.38937 11.61585 + 500 11.100239 3313.4214 0 -521.49831 3555.6926 -56.076799 648.94757 309.45936 -0.10950702 12.805213 7.7261445 341.38937 10.991018 + 600 9.9616183 2973.5431 0 -462.72888 3219.061 41.992567 3171.6576 309.48724 0.082003271 13.759365 8.0375919 341.38937 11.071546 + 700 9.3388468 2787.6458 0 -501.33865 2901.4483 81.033913 2000.5159 309.02619 0.15824338 12.744135 7.4580508 341.38937 10.129991 + 800 8.9069211 2658.716 0 -523.1858 2864.6773 -29.435005 2329.1521 308.67617 -0.057480808 11.604242 6.8135454 341.38937 9.3513467 + 900 8.5046965 2538.6519 0 -543.75602 2597.5491 50.752591 601.47078 308.62547 0.099109884 10.497389 6.2142574 341.38937 8.6389792 + 1000 8.0725601 2409.6592 0 -571.72872 2533.47 -23.431499 -1267.4683 308.58765 -0.045757135 9.421094 5.5928021 341.38937 7.8375753 +Loop time of 0.201181 on 1 procs for 1000 steps with 200 atoms + +Performance: 192854.150 tau/day, 4970.640 timesteps/s, 994.128 katom-step/s +98.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.11949 | 0.11949 | 0.11949 | 0.0 | 59.39 +Neigh | 0.011868 | 0.011868 | 0.011868 | 0.0 | 5.90 +Comm | 0.0041169 | 0.0041169 | 0.0041169 | 0.0 | 2.05 +Output | 0.00011916 | 0.00011916 | 0.00011916 | 0.0 | 0.06 +Modify | 0.064249 | 0.064249 | 0.064249 | 0.0 | 31.94 +Other | | 0.00134 | | | 0.67 + +Nlocal: 200 ave 200 max 200 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1117 ave 1117 max 1117 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 7492 ave 7492 max 7492 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 7492 +Ave neighs/atom = 37.46 +Neighbor list builds = 55 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.1 b/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.1 new file mode 100644 index 0000000000..0804a3488a --- /dev/null +++ b/examples/PACKAGES/pimd/langevin_reduced_units/log.14Jun23.langevin.reduced.g++.1 @@ -0,0 +1,97 @@ +LAMMPS (28 Mar 2023) +Processor partition = 1 + using 1 OpenMP thread(s) per MPI task +variable ibead uloop 32 pad + +units lj +atom_style atomic +atom_modify map yes +boundary p p p +pair_style lj/cut 2.8015 +read_data data.lj${ibead} +read_data data.lj02 +Reading data file ... + orthogonal box = (-3.4945131 -3.4945131 -3.4945131) to (3.4945131 3.4945131 3.4945131) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 200 atoms + read_data CPU = 0.001 seconds + +pair_coeff * * 1.0 1.0 +pair_modify shift yes + +mass 1 1.0 + +timestep 0.00044905847 + +fix 1 all pimd/langevin ensemble nvt integrator obabo temp 1.00888 lj 0.00965188 3.4 39.948 4.135667403e-3 1.03646168908e-4 thermostat PILE_L ${ibead} +fix 1 all pimd/langevin ensemble nvt integrator obabo temp 1.00888 lj 0.00965188 3.4 39.948 4.135667403e-3 1.03646168908e-4 thermostat PILE_L 02 + +thermo_style custom step temp f_1[*] vol press +thermo 100 +thermo_modify norm no + +#dump dcd all custom 1 ${ibead}.lammpstrj id type x y z vx vy vz ix iy iz fx fy fz +#dump_modify dcd sort id format line "%d %d %.16f %.16f %.16f %.16f %.16f %.16f %d %d %d %.16f %.16f %.16f" + +run 1000 +Generated 0 of 0 mixed pair_coeff terms from geometric mixing rule + +Initializing PI Langevin equation thermostat... +Bead ID | omega | tau | c1 | c2 + 0 0.00000000e+00 1.00000000e+00 9.99775496e-01 2.11886210e-02 + 1 1.31777963e+02 3.79426112e-03 9.42540858e-01 3.34090903e-01 +PILE_L thermostat successfully initialized! + +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 3.1015 + ghost atom cutoff = 3.1015 + binsize = 1.55075, bins = 5 5 5 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.117 | 3.117 | 3.117 Mbytes + Step Temp f_1[1] f_1[2] f_1[3] f_1[4] f_1[5] f_1[6] f_1[7] f_1[8] f_1[9] f_1[10] Volume Press + 0 0 0 843646.47 -904.74343 841866.06 -843041.14 253.30998 382.47517 -1646.2945 -1.9663356 -0.82731217 341.38937 -0.58528882 + 100 3.1994696 955.04167 1014.3663 -520.08788 5336.9805 -409.03828 7790.9787 306.80845 -0.79877176 13.250868 8.3263811 341.38937 5.9400539 + 200 2.0518234 612.46927 541.77919 -550.11284 4177.1707 63.548813 -8225.489 308.68383 0.1240984 12.723365 8.0800159 341.38937 5.1568532 + 300 2.0005565 597.16612 636.76107 -492.53916 3999.3337 -31.433066 8675.7059 309.21599 -0.061382631 14.105486 8.6052841 341.38937 6.1061183 + 400 2.1301774 635.85796 629.2996 -501.35894 3784.077 -23.971605 -81.467506 309.02093 -0.046811856 13.638064 8.2470184 341.38937 6.0950651 + 500 2.1090509 629.55171 661.4048 -527.18699 3555.6926 -56.076799 648.94757 309.45936 -0.10950702 12.805213 7.7261445 341.38937 5.6641225 + 600 2.1073653 629.04855 563.33543 -484.13719 3219.061 41.992567 3171.6576 309.48724 0.082003271 13.759365 8.0375919 341.38937 6.2053973 + 700 1.9719777 588.63535 524.29409 -497.78822 2901.4483 81.033913 2000.5159 309.02619 0.15824338 12.744135 7.4580508 341.38937 5.9107525 + 800 2.0469949 611.02799 634.76301 -516.64387 2864.6773 -29.435005 2329.1521 308.67617 -0.057480808 11.604242 6.8135454 341.38937 5.445481 + 900 1.9587942 584.70008 554.57541 -536.62232 2597.5491 50.752591 601.47078 308.62547 0.099109884 10.497389 6.2142574 341.38937 4.9080572 + 1000 2.0978185 626.19882 628.7595 -559.41879 2533.47 -23.431499 -1267.4683 308.58765 -0.045757135 9.421094 5.5928021 341.38937 4.5477372 +Loop time of 0.20118 on 1 procs for 1000 steps with 200 atoms + +Performance: 192855.450 tau/day, 4970.674 timesteps/s, 994.135 katom-step/s +99.6% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.12009 | 0.12009 | 0.12009 | 0.0 | 59.69 +Neigh | 0.012807 | 0.012807 | 0.012807 | 0.0 | 6.37 +Comm | 0.0040331 | 0.0040331 | 0.0040331 | 0.0 | 2.00 +Output | 0.00012271 | 0.00012271 | 0.00012271 | 0.0 | 0.06 +Modify | 0.062764 | 0.062764 | 0.062764 | 0.0 | 31.20 +Other | | 0.001361 | | | 0.68 + +Nlocal: 200 ave 200 max 200 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1117 ave 1117 max 1117 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 7460 ave 7460 max 7460 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 7460 +Ave neighs/atom = 37.3 +Neighbor list builds = 57 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/pimd/lj_reduced_units/run.sh b/examples/PACKAGES/pimd/langevin_reduced_units/run.sh similarity index 100% rename from examples/PACKAGES/pimd/lj_reduced_units/run.sh rename to examples/PACKAGES/pimd/langevin_reduced_units/run.sh From 77898e4a86f82d9c231fe743f07662671351ceed Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 18:28:51 -0400 Subject: [PATCH 420/448] update log files for fix widom --- examples/mc/log.14Jun23.widom.lj.g++.1 | 91 +++++++++++++++ examples/mc/log.14Jun23.widom.lj.g++.4 | 91 +++++++++++++++ examples/mc/log.14Jun23.widom.spce.g++.1 | 139 +++++++++++++++++++++++ examples/mc/log.30Jun20.widom.lj.g++.1 | 89 --------------- examples/mc/log.30Jun20.widom.lj.g++.4 | 89 --------------- examples/mc/log.30Jun20.widom.spce.g++.1 | 133 ---------------------- 6 files changed, 321 insertions(+), 311 deletions(-) create mode 100644 examples/mc/log.14Jun23.widom.lj.g++.1 create mode 100644 examples/mc/log.14Jun23.widom.lj.g++.4 create mode 100644 examples/mc/log.14Jun23.widom.spce.g++.1 delete mode 100644 examples/mc/log.30Jun20.widom.lj.g++.1 delete mode 100644 examples/mc/log.30Jun20.widom.lj.g++.4 delete mode 100644 examples/mc/log.30Jun20.widom.spce.g++.1 diff --git a/examples/mc/log.14Jun23.widom.lj.g++.1 b/examples/mc/log.14Jun23.widom.lj.g++.1 new file mode 100644 index 0000000000..6cbbae89ed --- /dev/null +++ b/examples/mc/log.14Jun23.widom.lj.g++.1 @@ -0,0 +1,91 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# Kob and Andersen model Phys. Rev. E 51, 4626 (1995) + +units lj +atom_style atomic + +pair_style lj/cut 2.5 +pair_modify shift yes + +read_data data.widom.lj +Reading data file ... + orthogonal box = (0 0 0) to (9.4 9.4 9.4) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 1000 atoms + reading velocities ... + 1000 velocities + read_data CPU = 0.006 seconds + +pair_coeff 1 1 1.0 1.0 2.5 +pair_coeff 1 2 1.5 0.8 2.0 +pair_coeff 2 2 0.5 0.88 2.2 + +neighbor 0.3 bin +neigh_modify delay 0 every 5 check yes + +fix mywidom all widom 10 100000 2 29494 0.75 + +fix 1 all langevin 0.75 0.75 0.1 48279 zero yes +fix 2 all nve + +timestep 0.002 + +thermo_style custom step temp pe etotal press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3] +thermo 10 + +run 100 +Generated 0 of 1 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 5 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 7 7 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.181 | 3.181 | 3.181 Mbytes + Step Temp PotEng TotEng Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3] + 0 0.75021245 -6.4204308 -5.2962374 7.2962696 830.584 1.2039721 0 0 830.584 + 10 0.7358936 -6.4405082 -5.3377717 7.1699962 830.584 1.2039721 -3.8577501 171.3429 830.584 + 20 0.75426414 -6.4267946 -5.2965298 7.2833985 830.584 1.2039721 -4.0708206 227.63895 830.584 + 30 0.72947489 -6.4064078 -5.3132896 7.3872583 830.584 1.2039721 -4.4304803 367.7146 830.584 + 40 0.73504751 -6.4248725 -5.3234038 7.2927069 830.584 1.2039721 -4.1904189 266.99373 830.584 + 50 0.76497439 -6.4352472 -5.2889331 7.3046861 830.584 1.2039721 -3.8628472 172.51133 830.584 + 60 0.75752861 -6.4147051 -5.2795485 7.4416 830.584 1.2039721 -3.5355467 111.5042 830.584 + 70 0.77775078 -6.4210798 -5.2556202 7.4473703 830.584 1.2039721 -3.4754802 102.92223 830.584 + 80 0.80937104 -6.4320008 -5.2191583 7.4121087 830.584 1.2039721 -3.9287513 188.35625 830.584 + 90 0.76321255 -6.4203633 -5.2766893 7.4307727 830.584 1.2039721 -4.2257529 279.87337 830.584 + 100 0.74561743 -6.4010576 -5.2837499 7.52907 830.584 1.2039721 -3.6817835 135.5099 830.584 +Loop time of 10.2362 on 1 procs for 100 steps with 1000 atoms + +Performance: 1688.128 tau/day, 9.769 timesteps/s, 9.769 katom-step/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.058411 | 0.058411 | 0.058411 | 0.0 | 0.57 +Neigh | 0.017611 | 0.017611 | 0.017611 | 0.0 | 0.17 +Comm | 0.001774 | 0.001774 | 0.001774 | 0.0 | 0.02 +Output | 0.00029892 | 0.00029892 | 0.00029892 | 0.0 | 0.00 +Modify | 10.158 | 10.158 | 10.158 | 0.0 | 99.23 +Other | | 0.0003838 | | | 0.00 + +Nlocal: 1000 ave 1000 max 1000 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 3049 ave 3049 max 3049 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 46176 ave 46176 max 46176 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 46176 +Ave neighs/atom = 46.176 +Neighbor list builds = 10 +Dangerous builds = 0 +Total wall time: 0:00:10 diff --git a/examples/mc/log.14Jun23.widom.lj.g++.4 b/examples/mc/log.14Jun23.widom.lj.g++.4 new file mode 100644 index 0000000000..7a1171f1b8 --- /dev/null +++ b/examples/mc/log.14Jun23.widom.lj.g++.4 @@ -0,0 +1,91 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +# Kob and Andersen model Phys. Rev. E 51, 4626 (1995) + +units lj +atom_style atomic + +pair_style lj/cut 2.5 +pair_modify shift yes + +read_data data.widom.lj +Reading data file ... + orthogonal box = (0 0 0) to (9.4 9.4 9.4) + 1 by 2 by 2 MPI processor grid + reading atoms ... + 1000 atoms + reading velocities ... + 1000 velocities + read_data CPU = 0.009 seconds + +pair_coeff 1 1 1.0 1.0 2.5 +pair_coeff 1 2 1.5 0.8 2.0 +pair_coeff 2 2 0.5 0.88 2.2 + +neighbor 0.3 bin +neigh_modify delay 0 every 5 check yes + +fix mywidom all widom 10 100000 2 29494 0.75 + +fix 1 all langevin 0.75 0.75 0.1 48279 zero yes +fix 2 all nve + +timestep 0.002 + +thermo_style custom step temp pe etotal press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3] +thermo 10 + +run 100 +Generated 0 of 1 mixed pair_coeff terms from geometric mixing rule +Neighbor list info ... + update: every = 5 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 2.8 + ghost atom cutoff = 2.8 + binsize = 1.4, bins = 7 7 7 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut, perpetual + attributes: half, newton on + pair build: half/bin/atomonly/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.13 | 3.13 | 3.131 Mbytes + Step Temp PotEng TotEng Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3] + 0 0.75021245 -6.4204308 -5.2962374 7.2962696 830.584 1.2039721 0 0 830.584 + 10 0.74279259 -6.4332442 -5.3201696 7.2071344 830.584 1.2039721 -3.4462258 98.984938 830.584 + 20 0.73016272 -6.4222911 -5.3281423 7.2714238 830.584 1.2039721 -4.4887329 397.41346 830.584 + 30 0.74416342 -6.429139 -5.3140101 7.2713375 830.584 1.2039721 -4.3313574 322.19056 830.584 + 40 0.73295457 -6.4370942 -5.3387618 7.227091 830.584 1.2039721 -4.7419281 557.00309 830.584 + 50 0.76914235 -6.4473959 -5.2948361 7.2179148 830.584 1.2039721 -3.1794069 69.352982 830.584 + 60 0.74099083 -6.4433012 -5.3329265 7.204973 830.584 1.2039721 -3.5231065 109.66994 830.584 + 70 0.74514671 -6.4288463 -5.312244 7.2771269 830.584 1.2039721 -1.0154832 3.8727995 830.584 + 80 0.72787097 -6.4457574 -5.3550427 7.1130709 830.584 1.2039721 -3.6691709 133.2501 830.584 + 90 0.78452846 -6.5034376 -5.3278217 6.8238659 830.584 1.2039721 -2.0798339 16.008373 830.584 + 100 0.77188499 -6.487313 -5.3306433 6.9133194 830.584 1.2039721 -2.066579 15.727938 830.584 +Loop time of 1.59209 on 4 procs for 100 steps with 1000 atoms + +Performance: 10853.637 tau/day, 62.810 timesteps/s, 62.810 katom-step/s +96.4% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.014713 | 0.015481 | 0.016154 | 0.4 | 0.97 +Neigh | 0.0045952 | 0.0047537 | 0.0048917 | 0.2 | 0.30 +Comm | 0.026382 | 0.086811 | 0.14145 | 13.9 | 5.45 +Output | 0.00022704 | 0.0002596 | 0.00035704 | 0.0 | 0.02 +Modify | 1.4299 | 1.4845 | 1.5447 | 3.4 | 93.24 +Other | | 0.0003365 | | | 0.02 + +Nlocal: 250 ave 256 max 242 min +Histogram: 1 0 0 0 1 0 0 0 1 1 +Nghost: 1666 ave 1670 max 1659 min +Histogram: 1 0 0 0 0 0 1 0 0 2 +Neighs: 11538 ave 11832 max 11091 min +Histogram: 1 0 0 0 0 0 1 1 0 1 + +Total # of neighbors = 46152 +Ave neighs/atom = 46.152 +Neighbor list builds = 10 +Dangerous builds = 0 +Total wall time: 0:00:01 diff --git a/examples/mc/log.14Jun23.widom.spce.g++.1 b/examples/mc/log.14Jun23.widom.spce.g++.1 new file mode 100644 index 0000000000..712566985d --- /dev/null +++ b/examples/mc/log.14Jun23.widom.spce.g++.1 @@ -0,0 +1,139 @@ +LAMMPS (28 Mar 2023 - Development) + using 1 OpenMP thread(s) per MPI task +units real +dimension 3 +boundary p p p +atom_style full + +pair_style lj/cut/coul/long 10.0 +bond_style harmonic +angle_style harmonic + +read_data data.spce +Reading data file ... + orthogonal box = (-0.031613 -0.023523 -0.085255) to (43.234352 44.939753 42.306533) + 1 by 1 by 1 MPI processor grid + reading atoms ... + 8640 atoms + scanning bonds ... + 2 = max bonds/atom + scanning angles ... + 1 = max angles/atom + reading bonds ... + 5760 bonds + reading angles ... + 2880 angles +Finding 1-2 1-3 1-4 neighbors ... + special bond factors lj: 0 0 0 + special bond factors coul: 0 0 0 + 2 = max # of 1-2 neighbors + 1 = max # of 1-3 neighbors + 1 = max # of 1-4 neighbors + 2 = max # of special neighbors + special bonds CPU = 0.002 seconds + read_data CPU = 0.048 seconds + +molecule h2omol H2O.txt +Read molecule template h2omol: + 1 molecules + 0 fragments + 3 atoms with max type 2 + 2 bonds with max type 1 + 1 angles with max type 1 + 0 dihedrals with max type 0 + 0 impropers with max type 0 + +### Flexible SPC/E Potential Parameters ### +### Zhang et al., Fluid Phase Equilibria, 262 (2007) 210-216 ### +pair_coeff 1 1 0.1502629 3.1169 +pair_coeff 1 2 0.0341116368 2.04845 +pair_coeff 2 2 0.00774378 0.98 + +bond_coeff 1 176.864 0.9611 +angle_coeff 1 42.1845 109.4712 +kspace_style pppm 1.0e-4 + +fix mywidom all widom 10 20 0 29494 298 mol h2omol + +fix 2 all nvt temp 298.0 298.0 100.0 + +neighbor 2.0 bin +neigh_modify delay 10 every 2 check yes + + +#run variables +timestep 0.5 + +thermo 10 +thermo_style custom step etotal pe temp press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3] + +run 100 +PPPM initialization ... + using 12-bit tables for long-range coulomb (src/kspace.cpp:342) + G vector (1/distance) = 0.2690183 + grid = 24 24 24 + stencil order = 5 + estimated absolute RMS force accuracy = 0.024843102 + estimated relative force accuracy = 7.4814263e-05 + using double precision KISS FFT + 3d grid and FFT values/proc = 29791 13824 +Generated 0 of 1 mixed pair_coeff terms from geometric mixing rule +WARNING: Fix widom using full_energy option (src/MC/fix_widom.cpp:320) +0 atoms in group FixWidom:widom_exclusion_group:mywidom +0 atoms in group FixWidom:rotation_gas_atoms:mywidom +WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (src/neighbor.cpp:654) +Neighbor list info ... + update: every = 2 steps, delay = 10 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 12 + ghost atom cutoff = 12 + binsize = 6, bins = 8 8 8 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair lj/cut/coul/long, perpetual + attributes: half, newton on + pair build: half/bin/newton + stencil: half/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 29.66 | 29.66 | 29.66 Mbytes + Step TotEng PotEng Temp Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3] + 0 -29703.973 -29703.973 0 -4764.5901 82468.116 1.0447118 0 0 82468.116 + 10 -29718 -32598.944 111.87604 -498.88935 82468.116 1.0447118 200.15526 1.6274344e-147 82468.116 + 20 -29698.227 -32625.357 113.6696 -3120.7115 82468.116 1.0447118 -1.0295764 5.6893637 82468.116 + 30 -29668.463 -33188.922 136.71037 -8129.0179 82468.116 1.0447118 5.5971294 7.856256e-05 82468.116 + 40 -29654.066 -34017.797 169.45726 -5730.6427 82468.116 1.0447118 128.14313 1.0550462e-94 82468.116 + 50 -29627.714 -33214.549 139.28799 -3954.0179 82468.116 1.0447118 122.28545 2.0851209e-90 82468.116 + 60 -29602.616 -32995.039 131.73836 -8099.2136 82468.116 1.0447118 -1.4752191 12.07497 82468.116 + 70 -29591.096 -33872.451 166.25834 -7065.2821 82468.116 1.0447118 17.210054 2.3911575e-13 82468.116 + 80 -29553.631 -32971.209 132.7152 -3535.4257 82468.116 1.0447118 11.148921 6.6631697e-09 82468.116 + 90 -29530.109 -33346.146 148.18857 -5312.6414 82468.116 1.0447118 51.783293 1.055658e-38 82468.116 + 100 -29505.327 -34074.801 177.4469 -5991.0034 82468.116 1.0447118 32.415523 1.6878187e-24 82468.116 +Loop time of 55.4401 on 1 procs for 100 steps with 8640 atoms + +Performance: 0.078 ns/day, 308.000 hours/ns, 1.804 timesteps/s, 15.584 katom-step/s +99.8% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 5.4117 | 5.4117 | 5.4117 | 0.0 | 9.76 +Bond | 0.029451 | 0.029451 | 0.029451 | 0.0 | 0.05 +Kspace | 0.73758 | 0.73758 | 0.73758 | 0.0 | 1.33 +Neigh | 1.4296 | 1.4296 | 1.4296 | 0.0 | 2.58 +Comm | 0.018593 | 0.018593 | 0.018593 | 0.0 | 0.03 +Output | 0.00069303 | 0.00069303 | 0.00069303 | 0.0 | 0.00 +Modify | 47.81 | 47.81 | 47.81 | 0.0 | 86.24 +Other | | 0.002525 | | | 0.00 + +Nlocal: 8640 ave 8640 max 8640 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 23534 ave 23534 max 23534 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 3.27356e+06 ave 3.27356e+06 max 3.27356e+06 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 3273560 +Ave neighs/atom = 378.88426 +Ave special neighs/atom = 2 +Neighbor list builds = 220 +Dangerous builds = 0 +Total wall time: 0:00:55 diff --git a/examples/mc/log.30Jun20.widom.lj.g++.1 b/examples/mc/log.30Jun20.widom.lj.g++.1 deleted file mode 100644 index 71621f9b4e..0000000000 --- a/examples/mc/log.30Jun20.widom.lj.g++.1 +++ /dev/null @@ -1,89 +0,0 @@ -LAMMPS (30 Jun 2020) - using 1 OpenMP thread(s) per MPI task -# Kob and Andersen model Phys. Rev. E 51, 4626 (1995) - -units lj -atom_style atomic - -pair_style lj/cut 2.5 -pair_modify shift yes - -read_data data.widom.lj - orthogonal box = (0.0000000 0.0000000 0.0000000) to (9.4000000 9.4000000 9.4000000) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 1000 atoms - reading velocities ... - 1000 velocities - read_data CPU = 0.003 seconds - -pair_coeff 1 1 1.0 1.0 2.5 -pair_coeff 1 2 1.5 0.8 2.0 -pair_coeff 2 2 0.5 0.88 2.2 - -neighbor 0.3 bin -neigh_modify delay 0 every 5 check yes - -fix mywidom all widom 10 100000 2 29494 0.75 - -fix 1 all langevin 0.75 0.75 0.1 48279 zero yes -fix 2 all nve - -timestep 0.002 - -thermo_style custom step temp pe etotal press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3] -thermo 10 - -run 100 -Neighbor list info ... - update every 5 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 2.8 - ghost atom cutoff = 2.8 - binsize = 1.4, bins = 7 7 7 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair lj/cut, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/3d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 3.181 | 3.181 | 3.181 Mbytes -Step Temp PotEng TotEng Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3] - 0 0.75021245 -6.4204308 -5.2962374 7.2962696 830.584 1.2039721 0 0 830.584 - 10 0.7358936 -6.4405082 -5.3377717 7.1699962 830.584 1.2039721 -3.8577501 171.3429 830.584 - 20 0.75426414 -6.4267946 -5.2965298 7.2833985 830.584 1.2039721 -4.0708206 227.63895 830.584 - 30 0.72947489 -6.4064078 -5.3132896 7.3872583 830.584 1.2039721 -4.4304803 367.7146 830.584 - 40 0.73504751 -6.4248725 -5.3234038 7.2927069 830.584 1.2039721 -4.1904189 266.99373 830.584 - 50 0.76497439 -6.4352472 -5.2889331 7.3046861 830.584 1.2039721 -3.8628472 172.51133 830.584 - 60 0.75752861 -6.4147051 -5.2795485 7.4416 830.584 1.2039721 -3.5355467 111.5042 830.584 - 70 0.77775078 -6.4210798 -5.2556202 7.4473703 830.584 1.2039721 -3.4754802 102.92223 830.584 - 80 0.80937104 -6.4320008 -5.2191583 7.4121087 830.584 1.2039721 -3.9287513 188.35625 830.584 - 90 0.76321255 -6.4203633 -5.2766893 7.4307727 830.584 1.2039721 -4.2257529 279.87337 830.584 - 100 0.74561743 -6.4010576 -5.2837499 7.52907 830.584 1.2039721 -3.6817835 135.5099 830.584 -Loop time of 25.8264 on 1 procs for 100 steps with 1000 atoms - -Performance: 669.082 tau/day, 3.872 timesteps/s -99.8% CPU use with 1 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0.08186 | 0.08186 | 0.08186 | 0.0 | 0.32 -Neigh | 0.023613 | 0.023613 | 0.023613 | 0.0 | 0.09 -Comm | 0.0053532 | 0.0053532 | 0.0053532 | 0.0 | 0.02 -Output | 0.00037837 | 0.00037837 | 0.00037837 | 0.0 | 0.00 -Modify | 25.715 | 25.715 | 25.715 | 0.0 | 99.57 -Other | | 0.0005643 | | | 0.00 - -Nlocal: 1000.00 ave 1000 max 1000 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 3049.00 ave 3049 max 3049 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 46176.0 ave 46176 max 46176 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 46176 -Ave neighs/atom = 46.176000 -Neighbor list builds = 10 -Dangerous builds = 0 -Total wall time: 0:00:25 diff --git a/examples/mc/log.30Jun20.widom.lj.g++.4 b/examples/mc/log.30Jun20.widom.lj.g++.4 deleted file mode 100644 index f726faed66..0000000000 --- a/examples/mc/log.30Jun20.widom.lj.g++.4 +++ /dev/null @@ -1,89 +0,0 @@ -LAMMPS (30 Jun 2020) - using 1 OpenMP thread(s) per MPI task -# Kob and Andersen model Phys. Rev. E 51, 4626 (1995) - -units lj -atom_style atomic - -pair_style lj/cut 2.5 -pair_modify shift yes - -read_data data.widom.lj - orthogonal box = (0.0000000 0.0000000 0.0000000) to (9.4000000 9.4000000 9.4000000) - 1 by 2 by 2 MPI processor grid - reading atoms ... - 1000 atoms - reading velocities ... - 1000 velocities - read_data CPU = 0.002 seconds - -pair_coeff 1 1 1.0 1.0 2.5 -pair_coeff 1 2 1.5 0.8 2.0 -pair_coeff 2 2 0.5 0.88 2.2 - -neighbor 0.3 bin -neigh_modify delay 0 every 5 check yes - -fix mywidom all widom 10 100000 2 29494 0.75 - -fix 1 all langevin 0.75 0.75 0.1 48279 zero yes -fix 2 all nve - -timestep 0.002 - -thermo_style custom step temp pe etotal press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3] -thermo 10 - -run 100 -Neighbor list info ... - update every 5 steps, delay 0 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 2.8 - ghost atom cutoff = 2.8 - binsize = 1.4, bins = 7 7 7 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair lj/cut, perpetual - attributes: half, newton on - pair build: half/bin/atomonly/newton - stencil: half/bin/3d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 3.13 | 3.13 | 3.131 Mbytes -Step Temp PotEng TotEng Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3] - 0 0.75021245 -6.4204308 -5.2962374 7.2962696 830.584 1.2039721 0 0 830.584 - 10 0.74279259 -6.4332442 -5.3201696 7.2071344 830.584 1.2039721 -3.4462258 98.984938 830.584 - 20 0.73016272 -6.4222911 -5.3281423 7.2714238 830.584 1.2039721 -4.4887329 397.41346 830.584 - 30 0.74416342 -6.429139 -5.3140101 7.2713375 830.584 1.2039721 -4.3313574 322.19056 830.584 - 40 0.73295457 -6.4370942 -5.3387618 7.227091 830.584 1.2039721 -4.7419281 557.00309 830.584 - 50 0.76914235 -6.4473959 -5.2948361 7.2179148 830.584 1.2039721 -3.1794069 69.352982 830.584 - 60 0.74099083 -6.4433012 -5.3329265 7.204973 830.584 1.2039721 -3.5231065 109.66994 830.584 - 70 0.74514671 -6.4288463 -5.312244 7.2771269 830.584 1.2039721 -1.0154832 3.8727995 830.584 - 80 0.72787097 -6.4457574 -5.3550427 7.1130709 830.584 1.2039721 -3.6691709 133.2501 830.584 - 90 0.78452846 -6.5034376 -5.3278217 6.8238659 830.584 1.2039721 -2.0798339 16.008373 830.584 - 100 0.77188499 -6.487313 -5.3306433 6.9133194 830.584 1.2039721 -2.066579 15.727938 830.584 -Loop time of 3.37748 on 4 procs for 100 steps with 1000 atoms - -Performance: 5116.239 tau/day, 29.608 timesteps/s -98.7% CPU use with 4 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0.02025 | 0.020952 | 0.021322 | 0.3 | 0.62 -Neigh | 0.0059071 | 0.0060568 | 0.0061543 | 0.1 | 0.18 -Comm | 0.016558 | 0.059554 | 0.094282 | 12.2 | 1.76 -Output | 0.00022173 | 0.00042927 | 0.0010471 | 0.0 | 0.01 -Modify | 3.2552 | 3.2902 | 3.3335 | 1.7 | 97.42 -Other | | 0.0003003 | | | 0.01 - -Nlocal: 250.000 ave 256 max 242 min -Histogram: 1 0 0 0 1 0 0 0 1 1 -Nghost: 1666.00 ave 1670 max 1659 min -Histogram: 1 0 0 0 0 0 1 0 0 2 -Neighs: 11538.0 ave 11832 max 11091 min -Histogram: 1 0 0 0 0 0 1 1 0 1 - -Total # of neighbors = 46152 -Ave neighs/atom = 46.152000 -Neighbor list builds = 10 -Dangerous builds = 0 -Total wall time: 0:00:03 diff --git a/examples/mc/log.30Jun20.widom.spce.g++.1 b/examples/mc/log.30Jun20.widom.spce.g++.1 deleted file mode 100644 index 25aecc685d..0000000000 --- a/examples/mc/log.30Jun20.widom.spce.g++.1 +++ /dev/null @@ -1,133 +0,0 @@ -LAMMPS (30 Jun 2020) - using 1 OpenMP thread(s) per MPI task -units real -dimension 3 -boundary p p p -atom_style full - -pair_style lj/cut/coul/long 10.0 -bond_style harmonic -angle_style harmonic - -read_data data.spce - orthogonal box = (-0.031613 -0.023523 -0.085255) to (43.234352 44.939753 42.306533) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 8640 atoms - scanning bonds ... - 2 = max bonds/atom - scanning angles ... - 1 = max angles/atom - reading bonds ... - 5760 bonds - reading angles ... - 2880 angles - 2 = max # of 1-2 neighbors - 1 = max # of 1-3 neighbors - 1 = max # of 1-4 neighbors - 2 = max # of special neighbors - special bonds CPU = 0.008 seconds - read_data CPU = 0.028 seconds - -molecule h2omol H2O.txt -Read molecule template h2omol: - 1 molecules - 3 atoms with max type 2 - 2 bonds with max type 1 - 1 angles with max type 1 - 0 dihedrals with max type 0 - 0 impropers with max type 0 - -### Flexible SPC/E Potential Parameters ### -### Zhang et al., Fluid Phase Equilibria, 262 (2007) 210-216 ### -pair_coeff 1 1 0.1502629 3.1169 -pair_coeff 1 2 0.0341116368 2.04845 -pair_coeff 2 2 0.00774378 0.98 - -bond_coeff 1 176.864 0.9611 -angle_coeff 1 42.1845 109.4712 -kspace_style pppm 1.0e-4 - -fix mywidom all widom 10 20 0 29494 298 mol h2omol - -fix 2 all nvt temp 298.0 298.0 100.0 - -neighbor 2.0 bin -neigh_modify delay 10 every 2 check yes - - -#run variables -timestep 0.5 - -thermo 10 -thermo_style custom step etotal pe temp press vol density f_mywidom[1] f_mywidom[2] f_mywidom[3] - -run 100 -PPPM initialization ... - using 12-bit tables for long-range coulomb (src/kspace.cpp:330) - G vector (1/distance) = 0.2690183 - grid = 24 24 24 - stencil order = 5 - estimated absolute RMS force accuracy = 0.024843102 - estimated relative force accuracy = 7.4814263e-05 - using double precision FFTW3 - 3d grid and FFT values/proc = 29791 13824 -WARNING: Fix Widom using full_energy option (src/MC/fix_widom.cpp:297) -0 atoms in group FixWidom:widom_exclusion_group:mywidom -0 atoms in group FixWidom:rotation_gas_atoms:mywidom -WARNING: Neighbor exclusions used with KSpace solver may give inconsistent Coulombic energies (src/neighbor.cpp:487) -Neighbor list info ... - update every 2 steps, delay 10 steps, check yes - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 12 - ghost atom cutoff = 12 - binsize = 6, bins = 8 8 8 - 1 neighbor lists, perpetual/occasional/extra = 1 0 0 - (1) pair lj/cut/coul/long, perpetual - attributes: half, newton on - pair build: half/bin/newton - stencil: half/bin/3d/newton - bin: standard -Per MPI rank memory allocation (min/avg/max) = 29.66 | 29.66 | 29.66 Mbytes -Step TotEng PotEng Temp Press Volume Density f_mywidom[1] f_mywidom[2] f_mywidom[3] - 0 -29703.973 -29703.973 0 -4764.5901 82468.116 1.9140713 0 0 82468.116 - 10 -29712.131 -31110.041 54.285179 -3154.4423 82468.116 1.9140713 241.93348 3.7366217e-178 82468.116 - 20 -29711.939 -32614.429 112.71273 -4216.1592 82468.116 1.9140713 16.095006 1.5716469e-12 82468.116 - 30 -29688.142 -32368.506 104.08688 -4093.6515 82468.116 1.9140713 5.7862327 5.7086352e-05 82468.116 - 40 -29662.343 -32252.144 100.57005 -1458.5339 82468.116 1.9140713 126.68071 1.2467216e-93 82468.116 - 50 -29646.78 -32837.635 123.91081 -4607.1155 82468.116 1.9140713 74.622397 1.8790479e-55 82468.116 - 60 -29628.968 -33001.229 130.9554 -4589.5296 82468.116 1.9140713 3.6575433 0.0020780497 82468.116 - 70 -29602.78 -32816.28 124.79023 -3082.1133 82468.116 1.9140713 13.983097 5.561247e-11 82468.116 - 80 -29577.552 -33141.454 138.39742 -6332.8138 82468.116 1.9140713 41.98931 1.6075608e-31 82468.116 - 90 -29550.865 -33792.115 164.70094 -4607.6419 82468.116 1.9140713 68.690681 4.2082269e-51 82468.116 - 100 -29515.107 -34052.782 176.21207 -3609.5709 82468.116 1.9140713 41.090597 7.3326206e-31 82468.116 -Loop time of 163.407 on 1 procs for 100 steps with 8640 atoms - -Performance: 0.026 ns/day, 907.819 hours/ns, 0.612 timesteps/s -99.8% CPU use with 1 MPI tasks x 1 OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 8.5495 | 8.5495 | 8.5495 | 0.0 | 5.23 -Bond | 0.031981 | 0.031981 | 0.031981 | 0.0 | 0.02 -Kspace | 2.3995 | 2.3995 | 2.3995 | 0.0 | 1.47 -Neigh | 5.0542 | 5.0542 | 5.0542 | 0.0 | 3.09 -Comm | 0.051965 | 0.051965 | 0.051965 | 0.0 | 0.03 -Output | 0.0018802 | 0.0018802 | 0.0018802 | 0.0 | 0.00 -Modify | 147.31 | 147.31 | 147.31 | 0.0 | 90.15 -Other | | 0.003614 | | | 0.00 - -Nlocal: 8640.00 ave 8640 max 8640 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 23499.0 ave 23499 max 23499 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 3.27380e+06 ave 3.2738e+06 max 3.2738e+06 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 3273800 -Ave neighs/atom = 378.91204 -Ave special neighs/atom = 2.0000000 -Neighbor list builds = 220 -Dangerous builds = 0 -Total wall time: 0:02:44 From 4d02c6f26f391f9703b49ba7a79af890c5a147b3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 21:50:27 -0400 Subject: [PATCH 421/448] update version strings for upcoming release --- doc/lammps.1 | 4 ++-- doc/src/Commands_removed.rst | 2 +- doc/src/Fortran.rst | 2 +- doc/src/compute_count_type.rst | 2 +- doc/src/compute_stress_cartesian.rst | 4 ++-- doc/src/compute_stress_mop.rst | 2 +- doc/src/fix_dpd_source.rst | 2 +- doc/src/fix_efield.rst | 2 +- doc/src/fix_print.rst | 2 +- doc/src/fix_reaxff_species.rst | 2 +- doc/src/package.rst | 2 +- doc/src/pair_aip_water_2dm.rst | 2 +- doc/src/pair_lepton.rst | 6 ++++-- doc/src/pair_lj_cut_sphere.rst | 2 +- doc/src/pair_lj_expand_sphere.rst | 2 +- doc/src/print.rst | 2 +- doc/src/variable.rst | 4 ++-- src/library.cpp | 2 +- src/version.h | 3 +-- 19 files changed, 25 insertions(+), 24 deletions(-) diff --git a/doc/lammps.1 b/doc/lammps.1 index b1be867e60..9bc107624f 100644 --- a/doc/lammps.1 +++ b/doc/lammps.1 @@ -1,7 +1,7 @@ -.TH LAMMPS "1" "28 March 2023" "2023-03-28" +.TH LAMMPS "1" "15 June 2023" "2023-06-15" .SH NAME .B LAMMPS -\- Molecular Dynamics Simulator. Version 28 March 2023 +\- Molecular Dynamics Simulator. Version 15 June 2023 .SH SYNOPSIS .B lmp diff --git a/doc/src/Commands_removed.rst b/doc/src/Commands_removed.rst index d50eab3a41..1848a28024 100644 --- a/doc/src/Commands_removed.rst +++ b/doc/src/Commands_removed.rst @@ -41,7 +41,7 @@ warning. LATTE package ------------- -.. deprecated:: TBD +.. deprecated:: 15Jun2023 The LATTE package with the fix latte command was removed from LAMMPS. This functionality has been superseded by :doc:`fix mdi/qm ` diff --git a/doc/src/Fortran.rst b/doc/src/Fortran.rst index a0e4da56b5..7e9f16fa70 100644 --- a/doc/src/Fortran.rst +++ b/doc/src/Fortran.rst @@ -620,7 +620,7 @@ Procedures Bound to the :f:type:`lammps` Derived Type output, depending on the data requested through *what*. Note that *index* uses 1-based indexing to access thermo output columns. - .. versionadded:: TBD + .. versionadded:: 15Jun2023 Note that this function actually does not return a value, but rather associates the pointer on the left side of the assignment to point to diff --git a/doc/src/compute_count_type.rst b/doc/src/compute_count_type.rst index 81fffb4f28..ca3b02ecdb 100644 --- a/doc/src/compute_count_type.rst +++ b/doc/src/compute_count_type.rst @@ -25,7 +25,7 @@ Examples Description """"""""""" -.. versionadded:: TBD +.. versionadded:: 15Jun2023 Define a computation that counts the current number of atoms for each atom type. Or the number of bonds (angles, dihedrals, impropers) for diff --git a/doc/src/compute_stress_cartesian.rst b/doc/src/compute_stress_cartesian.rst index 3e1e9d9a8a..46785149f8 100644 --- a/doc/src/compute_stress_cartesian.rst +++ b/doc/src/compute_stress_cartesian.rst @@ -41,7 +41,7 @@ split into a kinetic contribution :math:`P^k` and a virial contribution This compute obeys momentum balance through fluid interfaces. They use the Irving--Kirkwood contour, which is the straight line between particle pairs. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 Added support for bond styles @@ -119,4 +119,4 @@ Related commands .. _Ikeshoji2: -**(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). \ No newline at end of file +**(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). diff --git a/doc/src/compute_stress_mop.rst b/doc/src/compute_stress_mop.rst index ec654dc61c..21c2963545 100644 --- a/doc/src/compute_stress_mop.rst +++ b/doc/src/compute_stress_mop.rst @@ -66,7 +66,7 @@ that atoms have crossed the plane if their positions at times and uses the velocity at time :math:`t-\Delta t/2` given by the velocity Verlet algorithm. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 contributions from bond and angle potentials diff --git a/doc/src/fix_dpd_source.rst b/doc/src/fix_dpd_source.rst index ade9659d00..71894161f1 100644 --- a/doc/src/fix_dpd_source.rst +++ b/doc/src/fix_dpd_source.rst @@ -61,7 +61,7 @@ heat conduction with a source term (see Fig.12 in :ref:`(Li2014) `) or diffusion with a source term (see Fig.1 in :ref:`(Li2015) `), as an analog of a periodic Poiseuille flow problem. -.. deprecated:: TBD +.. deprecated:: 15Jun2023 The *sphere* and *cuboid* keywords will be removed in a future version of LAMMPS. The same functionality and more can be achieved with a region. diff --git a/doc/src/fix_efield.rst b/doc/src/fix_efield.rst index 4cf92cf946..e38e1e6894 100644 --- a/doc/src/fix_efield.rst +++ b/doc/src/fix_efield.rst @@ -136,7 +136,7 @@ due to the electric field were a spring-like F = kx, then the energy formula should be E = -0.5kx\^2. If you don't do this correctly, the minimization will not converge properly. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 The *potential* keyword can be used as an alternative to the *energy* keyword to specify the name of an atom-style variable, which is used to compute the diff --git a/doc/src/fix_print.rst b/doc/src/fix_print.rst index 938b40d1f9..05abbe3c98 100644 --- a/doc/src/fix_print.rst +++ b/doc/src/fix_print.rst @@ -44,7 +44,7 @@ one word. If it contains variables it must be enclosed in double quotes to ensure they are not evaluated when the input script line is read, but will instead be evaluated each time the string is printed. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 support for vector style variables diff --git a/doc/src/fix_reaxff_species.rst b/doc/src/fix_reaxff_species.rst index c22c9d7b9f..6a171ede5e 100644 --- a/doc/src/fix_reaxff_species.rst +++ b/doc/src/fix_reaxff_species.rst @@ -88,7 +88,7 @@ If the filename ends with ".gz", the output file is written in gzipped format. A gzipped dump file will be about 3x smaller than the text version, but will also take longer to write. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 Support for wildcards added diff --git a/doc/src/package.rst b/doc/src/package.rst index b0549ba7d9..0f28598029 100644 --- a/doc/src/package.rst +++ b/doc/src/package.rst @@ -433,7 +433,7 @@ with 16 threads, for a total of 128. Note that the default settings for *tpc* and *tptask* are fine for most problems, regardless of how many MPI tasks you assign to a Phi. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 The *pppm_table* keyword with the argument yes allows to use a pre-computed table to efficiently spread the charge to the PPPM grid. diff --git a/doc/src/pair_aip_water_2dm.rst b/doc/src/pair_aip_water_2dm.rst index 532ee8f8f6..5cee40edda 100644 --- a/doc/src/pair_aip_water_2dm.rst +++ b/doc/src/pair_aip_water_2dm.rst @@ -33,7 +33,7 @@ Examples Description """"""""""" -.. versionadded:: TBD +.. versionadded:: 15Jun2023 The *aip/water/2dm* style computes the anisotropic interfacial potential (AIP) potential for interfaces of water with two-dimensional (2D) diff --git a/doc/src/pair_lepton.rst b/doc/src/pair_lepton.rst index 608265ecbd..21e619a3d9 100644 --- a/doc/src/pair_lepton.rst +++ b/doc/src/pair_lepton.rst @@ -61,9 +61,11 @@ Description .. versionadded:: 8Feb2023 -.. versionchanged:: TBD + added pair styles *lepton* and *lepton/coul* - added pair style lepton/sphere +.. versionchanged:: 15Jun2023 + + added pair style *lepton/sphere* Pair styles *lepton*, *lepton/coul*, *lepton/sphere* compute pairwise interactions between particles which depend on the distance and have a diff --git a/doc/src/pair_lj_cut_sphere.rst b/doc/src/pair_lj_cut_sphere.rst index 428047d5df..31f84bc40e 100644 --- a/doc/src/pair_lj_cut_sphere.rst +++ b/doc/src/pair_lj_cut_sphere.rst @@ -33,7 +33,7 @@ Examples Description """"""""""" -.. versionadded:: TBD +.. versionadded:: 15Jun2023 The *lj/cut/sphere* style compute the standard 12/6 Lennard-Jones potential, given by diff --git a/doc/src/pair_lj_expand_sphere.rst b/doc/src/pair_lj_expand_sphere.rst index c60cf160f0..2c01624251 100644 --- a/doc/src/pair_lj_expand_sphere.rst +++ b/doc/src/pair_lj_expand_sphere.rst @@ -33,7 +33,7 @@ Examples Description """"""""""" -.. versionadded:: TBD +.. versionadded:: 15Jun2023 The *lj/expand/sphere* style compute a 12/6 Lennard-Jones potential with a distance shifted by :math:`\Delta = \frac{1}{2} (d_i + d_j)`, the diff --git a/doc/src/print.rst b/doc/src/print.rst index f5a872e768..a221ed04b6 100644 --- a/doc/src/print.rst +++ b/doc/src/print.rst @@ -46,7 +46,7 @@ lines of output, the string can be enclosed in triple quotes, as in the last example above. If the text string contains variables, they will be evaluated and their current values printed. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 support for vector style variables diff --git a/doc/src/variable.rst b/doc/src/variable.rst index 1b1acba92d..67600af62d 100644 --- a/doc/src/variable.rst +++ b/doc/src/variable.rst @@ -1001,7 +1001,7 @@ map kind (atom, bond, angle, dihedral, or improper) and the second argument is the label. The function returns the corresponding numeric type or triggers an error if the queried label does not exist. -.. versionadded:: TBD +.. versionadded:: 15Jun2023 The is_typelabel(kind,label) function has the same arguments as label2type(), but returns 1 if the type label has been assigned, @@ -1320,7 +1320,7 @@ Vectors" discussion above. Vector Initialization --------------------- -.. versionadded:: TBD +.. versionadded:: 15Jun2023 *Vector*-style variables only can be initialized with a special syntax, instead of using a formula. The syntax is a bracketed, diff --git a/src/library.cpp b/src/library.cpp index 1996ebbcb4..872b59693f 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -756,7 +756,7 @@ double lammps_get_thermo(void *handle, const char *keyword) * \verbatim embed:rst -.. versionadded:: TBD +.. versionadded:: 15Jun2023 This function provides access to cached data from the last thermo output. This differs from :cpp:func:`lammps_get_thermo` in that it does not trigger diff --git a/src/version.h b/src/version.h index 2d0eb0480e..63547c4a01 100644 --- a/src/version.h +++ b/src/version.h @@ -1,2 +1 @@ -#define LAMMPS_VERSION "28 Mar 2023" -#define LAMMPS_UPDATE "Development" +#define LAMMPS_VERSION "15 Jun 2023" From b8dda7ebfe9c3b04b9ca46e375714a139a9ac24b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 22:08:30 -0400 Subject: [PATCH 422/448] documentation formatting and spelling fixes --- doc/src/compute_stress_cartesian.rst | 3 ++- doc/src/compute_stress_curvilinear.rst | 5 +++-- doc/utils/sphinx-config/false_positives.txt | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/doc/src/compute_stress_cartesian.rst b/doc/src/compute_stress_cartesian.rst index 3e1e9d9a8a..d2c2aa9ba9 100644 --- a/doc/src/compute_stress_cartesian.rst +++ b/doc/src/compute_stress_cartesian.rst @@ -26,6 +26,7 @@ Examples """""""" .. code-block:: LAMMPS + compute 1 all stress/cartesian x 0.1 NULL 0 compute 1 all stress/cartesian y 0.1 z 0.1 compute 1 all stress/cartesian x 0.1 NULL 0 ke pair @@ -119,4 +120,4 @@ Related commands .. _Ikeshoji2: -**(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). \ No newline at end of file +**(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). diff --git a/doc/src/compute_stress_curvilinear.rst b/doc/src/compute_stress_curvilinear.rst index edd1df9217..022a87058f 100644 --- a/doc/src/compute_stress_curvilinear.rst +++ b/doc/src/compute_stress_curvilinear.rst @@ -36,6 +36,7 @@ Examples """""""" .. code-block:: LAMMPS + compute 1 all stress/cylinder -10.0 10.0 15.0 0.25 compute 1 all stress/cylinder -10.0 10.0 15.0 0.25 ke no compute 1 all stress/spherical 0 0 0 0.1 10 @@ -59,7 +60,7 @@ The compute *stress/cylinder* computes the stress profile along the radial direction in cylindrical coordinates, as described in :ref:`(Addington)`. The compute *stress/spherical* computes the stress profile along the radial direction in spherical -coordinates, as described in :ref:`(Ikeshoji)`. +coordinates, as described in :ref:`(Ikeshoji)`. Output info @@ -125,7 +126,7 @@ The keyword default for ke in style *stress/cylinder* is yes. ---------- -.. _Ikeshoji2: +.. _Ikeshoji4: **(Ikeshoji)** Ikeshoji, Hafskjold, Furuholt, Mol Sim, 29, 101-109, (2003). diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index 867a0e0631..5791288a06 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -552,6 +552,7 @@ conformational Connor conp conq +const ConstMatrix Contrib cooperativity From 4eb602e0d47530b05baff96df6b625e282a8eae3 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 14 Jun 2023 22:18:08 -0400 Subject: [PATCH 423/448] improve error messages and apply clang-format --- src/EXTRA-COMPUTE/compute_stress_cartesian.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp index 3835b8bea9..0380acbb82 100644 --- a/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp +++ b/src/EXTRA-COMPUTE/compute_stress_cartesian.cpp @@ -62,7 +62,7 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg { if (lmp->citeme) lmp->citeme->add(cite_compute_stress_cartesian); - if (narg < 7) error->all(FLERR, "Illegal compute stress/cartesian command: illegal number of arguments."); + if (narg < 7) utils::missing_cmd_args(FLERR, "compute stress/cartesian", error); // no triclinic boxes if (domain->triclinic) error->all(FLERR, "Compute stress/cartesian requires an orthogonal box"); @@ -158,10 +158,14 @@ ComputeStressCartesian::ComputeStressCartesian(LAMMPS *lmp, int narg, char **arg compute_bond = false; int iarg = 7; while (iarg < narg) { - if (strcmp(arg[iarg], "ke") == 0) compute_ke = true; - else if (strcmp(arg[iarg], "pair") == 0) compute_pair = true; - else if (strcmp(arg[iarg], "bond") == 0) compute_bond = true; - else error->all(FLERR, "Illegal compute stress/atom command"); + if (strcmp(arg[iarg], "ke") == 0) + compute_ke = true; + else if (strcmp(arg[iarg], "pair") == 0) + compute_pair = true; + else if (strcmp(arg[iarg], "bond") == 0) + compute_bond = true; + else + error->all(FLERR, "Unknown compute stress/cartesian keyword: {}", arg[iarg]); iarg++; } } @@ -371,7 +375,7 @@ void ComputeStressCartesian::compute_array() // i == atom1, j == atom2 int i = neighbor->bondlist[i_bond][0]; int j = neighbor->bondlist[i_bond][1]; - int btype = neighbor->bondlist[i_bond][2]; + int btype = neighbor->bondlist[i_bond][2]; // Skip if one of both atoms is not in group if (!(mask[i] & groupbit)) continue; @@ -389,7 +393,7 @@ void ComputeStressCartesian::compute_array() double dx = x[j][0] - x[i][0]; double dy = x[j][1] - x[i][1]; double dz = x[j][2] - x[i][2]; - double rsq = dx*dx + dy*dy + dz*dz; + double rsq = dx * dx + dy * dy + dz * dz; double xi = x[i][dir1] - boxlo[dir1]; double yi = x[i][dir2] - boxlo[dir2]; From e01bde5be518853f14ee2b72481b51168a090d8a Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 15 Jun 2023 01:50:07 -0400 Subject: [PATCH 424/448] avoid null pointer dereference --- src/INTEL/fix_intel.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/INTEL/fix_intel.cpp b/src/INTEL/fix_intel.cpp index 59224cc511..4c46608677 100644 --- a/src/INTEL/fix_intel.cpp +++ b/src/INTEL/fix_intel.cpp @@ -306,16 +306,17 @@ void FixIntel::init() if (force->pair_match("gayberne/intel$", 0)) _torque_flag = 1; const int nstyles = _pair_intel_count; - if (force->pair_match("^hybrid", 0) != nullptr) { + if (force->pair_match("^hybrid", 0)) { _pair_hybrid_flag = 1; // Check if need to handle torque auto hybrid = dynamic_cast(force->pair); - for (int i = 0; i < hybrid->nstyles; i++) - if (utils::strmatch(hybrid->keywords[i],"/intel$") && - utils::strmatch(hybrid->keywords[i],"gayberne")) - _torque_flag = 1; - + if (hybrid) { + for (int i = 0; i < hybrid->nstyles; i++) + if (utils::strmatch(hybrid->keywords[i],"/intel$") && + utils::strmatch(hybrid->keywords[i],"gayberne")) + _torque_flag = 1; + } if (force->newton_pair != 0 && force->pair->no_virial_fdotr_compute) error->all(FLERR,"INTEL package requires fdotr virial with newton on."); } else From 55d767e41609cbbd0016e9cff0f6279ed59621c8 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Thu, 15 Jun 2023 01:51:12 -0400 Subject: [PATCH 425/448] make sure intermediate results are 64-bit compatible, so the won't overflow --- src/INTEL/npair_full_bin_ghost_intel.cpp | 2 +- src/INTEL/npair_intel.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/INTEL/npair_full_bin_ghost_intel.cpp b/src/INTEL/npair_full_bin_ghost_intel.cpp index 381db62c08..920c0c559a 100644 --- a/src/INTEL/npair_full_bin_ghost_intel.cpp +++ b/src/INTEL/npair_full_bin_ghost_intel.cpp @@ -559,7 +559,7 @@ void NPairFullBinGhostIntel::fbi(const int offload, NeighList * list, if (ct + obound > list_size) { if (i < ito - 1) { *overflow = 1; - ct = (ifrom + tid * 2) * maxnbors; + ct = (bigint)(ifrom + tid * 2) * (bigint)maxnbors; } } } diff --git a/src/INTEL/npair_intel.cpp b/src/INTEL/npair_intel.cpp index 8b05aa38aa..600109d7ae 100644 --- a/src/INTEL/npair_intel.cpp +++ b/src/INTEL/npair_intel.cpp @@ -723,7 +723,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, if (ct + obound > list_size) { if (i < ito - 1) { *overflow = 1; - ct = (ifrom + tid * 2) * maxnbors; + ct = (bigint)(ifrom + tid * 2) * (bigint)maxnbors; } } } @@ -737,7 +737,7 @@ void NPairIntel::bin_newton(const int offload, NeighList *list, if (ct + obound > list_size) { if (i < ito - 1) { *overflow = 1; - ct = (ifrom + tid * 2) * maxnbors; + ct = (bigint)(ifrom + tid * 2) * (bigint)maxnbors; } } } From 0df1542be10815a6d735779fecd7ffce4f5835e5 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Thu, 15 Jun 2023 10:22:35 -0600 Subject: [PATCH 426/448] Pair SNAP tuning for Kokkos SYCL --- src/KOKKOS/kokkos_type.h | 8 ++++++-- src/KOKKOS/pair_snap_kokkos.h | 11 +++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/KOKKOS/kokkos_type.h b/src/KOKKOS/kokkos_type.h index 3c9886905e..fac75221bc 100644 --- a/src/KOKKOS/kokkos_type.h +++ b/src/KOKKOS/kokkos_type.h @@ -1310,9 +1310,13 @@ struct alignas(4 * sizeof(int)) reax_int4 { #define SNAP_KOKKOS_HOST_VECLEN 1 #ifdef LMP_KOKKOS_GPU -#define SNAP_KOKKOS_DEVICE_VECLEN 32 + #if defined(KOKKOS_ENABLE_SYCL) + #define SNAP_KOKKOS_DEVICE_VECLEN 16 + #else + #define SNAP_KOKKOS_DEVICE_VECLEN 32 + #endif #else -#define SNAP_KOKKOS_DEVICE_VECLEN 1 + #define SNAP_KOKKOS_DEVICE_VECLEN 1 #endif diff --git a/src/KOKKOS/pair_snap_kokkos.h b/src/KOKKOS/pair_snap_kokkos.h index fba95a679e..0df02e0bc7 100644 --- a/src/KOKKOS/pair_snap_kokkos.h +++ b/src/KOKKOS/pair_snap_kokkos.h @@ -97,6 +97,17 @@ class PairSNAPKokkos : public PairSNAP { static constexpr int tile_size_transform_bi = 2; static constexpr int tile_size_compute_yi = 2; static constexpr int team_size_compute_fused_deidrj = 2; +#elif defined(KOKKOS_ENABLE_SYCL) + static constexpr int team_size_compute_neigh = 4; + static constexpr int tile_size_compute_ck = 4; + static constexpr int tile_size_pre_ui = 4; + static constexpr int team_size_compute_ui = 4; + static constexpr int tile_size_transform_ui = 4; + static constexpr int tile_size_compute_zi = 4; + static constexpr int tile_size_compute_bi = 4; + static constexpr int tile_size_transform_bi = 4; + static constexpr int tile_size_compute_yi = 8; + static constexpr int team_size_compute_fused_deidrj = 4; #else static constexpr int team_size_compute_neigh = 4; static constexpr int tile_size_compute_ck = 4; From 74c4eb10636e3fe6656c3bebd070b443a0445e3e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 16 Jun 2023 12:12:12 -0400 Subject: [PATCH 427/448] indicate that LAMMPS was built from a development version --- src/version.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/version.h b/src/version.h index 63547c4a01..2a1c8a9a37 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1,2 @@ #define LAMMPS_VERSION "15 Jun 2023" +#define LAMMPS_UPDATE "Development" From 59c5ed63e375ff1b66ee9d27468d9874b579a597 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 16 Jun 2023 12:12:23 -0400 Subject: [PATCH 428/448] programming style --- src/dump_image.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/dump_image.cpp b/src/dump_image.cpp index ff1c540d3f..0d54c60595 100644 --- a/src/dump_image.cpp +++ b/src/dump_image.cpp @@ -201,7 +201,7 @@ DumpImage::DumpImage(LAMMPS *lmp, int narg, char **arg) : if (iflag == ArgInfo::COMPUTE) id_grid_compute = utils::strdup(id); else if (iflag == ArgInfo::FIX) id_grid_fix = utils::strdup(id); - delete [] id; + delete[] id; grid_igrid = igrid; grid_idata = idata; grid_index = index; @@ -461,18 +461,18 @@ DumpImage::~DumpImage() { delete image; - delete [] diamtype; - delete [] diamelement; - delete [] colortype; - delete [] colorelement; - delete [] bdiamtype; - delete [] bcolortype; + delete[] diamtype; + delete[] diamelement; + delete[] colortype; + delete[] colorelement; + delete[] bdiamtype; + delete[] bcolortype; memory->destroy(chooseghost); memory->destroy(bufcopy); memory->destroy(gbuf); - delete [] id_grid_compute; - delete [] id_grid_fix; + delete[] id_grid_compute; + delete[] id_grid_fix; } /* ---------------------------------------------------------------------- */ From a20ed8e5e4bc40ebc65e0ba0954a4c091e8d76f2 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 16 Jun 2023 12:13:22 -0400 Subject: [PATCH 429/448] improve error messages for dump style custom --- src/dump_custom.cpp | 75 +++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp index 517956caf1..33cfba2cef 100644 --- a/src/dump_custom.cpp +++ b/src/dump_custom.cpp @@ -61,12 +61,12 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : fix(nullptr), id_variable(nullptr), variable(nullptr), vbuf(nullptr), id_custom(nullptr), custom(nullptr), custom_flag(nullptr), typenames(nullptr), pack_choice(nullptr) { - if (narg == 5) error->all(FLERR,"No dump custom arguments specified"); + if (narg == 5) error->all(FLERR,"No dump {} arguments specified", style); clearstep = 1; nevery = utils::inumeric(FLERR,arg[3],false,lmp); - if (nevery <= 0) error->all(FLERR,"Illegal dump custom command"); + if (nevery <= 0) error->all(FLERR,"Illegal dump {} command: output frequency must be > 0", style); // expand args if any have wildcard character "*" // ok to include trailing optional args, @@ -141,7 +141,7 @@ DumpCustom::DumpCustom(LAMMPS *lmp, int narg, char **arg) : else if (vtype[i] == Dump::BIGINT) cols += BIGINT_FORMAT " "; vformat[i] = nullptr; } - cols.resize(cols.size()-1); + if (nfield > 0) cols.resize(cols.size()-1); format_default = utils::strdup(cols); format_column_user = new char*[nfield]; @@ -309,20 +309,20 @@ void DumpCustom::init_style() for (i = 0; i < ncompute; i++) { compute[i] = modify->get_compute_by_id(id_compute[i]); - if (!compute[i]) error->all(FLERR,"Could not find dump custom compute ID {}",id_compute[i]); + if (!compute[i]) error->all(FLERR,"Could not find dump {} compute ID {}",style,id_compute[i]); } for (i = 0; i < nfix; i++) { fix[i] = modify->get_fix_by_id(id_fix[i]); - if (!fix[i]) error->all(FLERR,"Could not find dump custom fix ID {}", id_fix[i]); + if (!fix[i]) error->all(FLERR,"Could not find dump {} fix ID {}", style, id_fix[i]); if (nevery % fix[i]->peratom_freq) - error->all(FLERR,"Dump custom and fix not computed at compatible times"); + error->all(FLERR,"Dump {} and fix not computed at compatible times", style); } for (i = 0; i < nvariable; i++) { int ivariable = input->variable->find(id_variable[i]); if (ivariable < 0) - error->all(FLERR,"Could not find dump custom variable name {}", id_variable[i]); + error->all(FLERR,"Could not find dump {} variable name {}", style, id_variable[i]); variable[i] = ivariable; } @@ -330,7 +330,7 @@ void DumpCustom::init_style() for (int i = 0; i < ncustom; i++) { icustom = atom->find_custom(id_custom[i],flag,cols); if (icustom < 0) - error->all(FLERR,"Could not find dump custom atom property name"); + error->all(FLERR,"Could not find dump {} atom property name", style); custom[i] = icustom; if (!flag && !cols) custom_flag[i] = IVEC; else if (flag && !cols) custom_flag[i] = DVEC; @@ -341,7 +341,7 @@ void DumpCustom::init_style() // check validity of region if (idregion && !domain->get_region_by_id(idregion)) - error->all(FLERR,"Region {} for dump custom does not exist", idregion); + error->all(FLERR,"Region {} for dump {} does not exist", idregion, style); // open single file, one time only @@ -1461,7 +1461,8 @@ int DumpCustom::parse_fields(int narg, char **arg) switch (argi.get_type()) { case ArgInfo::UNKNOWN: - error->all(FLERR,"Invalid attribute in dump custom command"); + case ArgInfo::NONE: + error->all(FLERR,"Invalid attribute {} in dump {} command",arg[iarg],style); break; // compute value = c_ID @@ -1472,15 +1473,15 @@ int DumpCustom::parse_fields(int narg, char **arg) vtype[iarg] = Dump::DOUBLE; icompute = modify->get_compute_by_id(name); - if (!icompute) error->all(FLERR,"Could not find dump custom compute ID: {}",name); + if (!icompute) error->all(FLERR,"Could not find dump {} compute ID: {}", style, name); if (icompute->peratom_flag == 0) - error->all(FLERR,"Dump custom compute {} does not compute per-atom info",name); + error->all(FLERR,"Dump {} compute {} does not compute per-atom info", style, name); if (argi.get_dim() == 0 && icompute->size_peratom_cols > 0) - error->all(FLERR,"Dump custom compute {} does not calculate per-atom vector",name); + error->all(FLERR,"Dump {} compute {} does not calculate per-atom vector", style, name); if (argi.get_dim() > 0 && icompute->size_peratom_cols == 0) - error->all(FLERR,"Dump custom compute {} does not calculate per-atom array",name); + error->all(FLERR,"Dump {} compute {} does not calculate per-atom array", style, name); if (argi.get_dim() > 0 && argi.get_index1() > icompute->size_peratom_cols) - error->all(FLERR,"Dump custom compute {} vector is accessed out-of-range",name); + error->all(FLERR,"Dump {} compute {} vector is accessed out-of-range", style, name); field2index[iarg] = add_compute(name); break; @@ -1493,15 +1494,15 @@ int DumpCustom::parse_fields(int narg, char **arg) vtype[iarg] = Dump::DOUBLE; ifix = modify->get_fix_by_id(name); - if (!ifix) error->all(FLERR,"Could not find dump custom fix ID: {}",name); + if (!ifix) error->all(FLERR,"Could not find dump {} fix ID: {}", style, name); if (ifix->peratom_flag == 0) - error->all(FLERR,"Dump custom fix {} does not compute per-atom info",name); + error->all(FLERR,"Dump {} fix {} does not compute per-atom info", style, name); if (argi.get_dim() == 0 && ifix->size_peratom_cols > 0) - error->all(FLERR,"Dump custom fix {} does not compute per-atom vector",name); + error->all(FLERR,"Dump {} fix {} does not compute per-atom vector", style, name); if (argi.get_dim() > 0 && ifix->size_peratom_cols == 0) - error->all(FLERR,"Dump custom fix {} does not compute per-atom array",name); + error->all(FLERR,"Dump {} fix {} does not compute per-atom array", style, name); if (argi.get_dim() > 0 && argi.get_index1() > ifix->size_peratom_cols) - error->all(FLERR,"Dump custom fix {} vector is accessed out-of-range",name); + error->all(FLERR,"Dump {} fix {} vector is accessed out-of-range", style, name); field2index[iarg] = add_fix(name); break; @@ -1513,9 +1514,9 @@ int DumpCustom::parse_fields(int narg, char **arg) vtype[iarg] = Dump::DOUBLE; n = input->variable->find(name); - if (n < 0) error->all(FLERR,"Could not find dump custom variable name {}",name); + if (n < 0) error->all(FLERR,"Could not find dump {} variable name {}", style, name); if (input->variable->atomstyle(n) == 0) - error->all(FLERR,"Dump custom variable {} is not atom-style variable",name); + error->all(FLERR,"Dump {} variable {} is not atom-style variable", style, name); field2index[iarg] = add_variable(name); break; @@ -1532,12 +1533,12 @@ int DumpCustom::parse_fields(int narg, char **arg) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); if (argindex[iarg] == 0) { if (!flag || cols) - error->all(FLERR,"Property double vector {} for dump custom does not exist",name); + error->all(FLERR,"Property double vector {} for dump {} does not exist", name, style); } else { if (!flag || !cols) - error->all(FLERR,"Property double array {} for dump custom does not exist",name); + error->all(FLERR,"Property double array {} for dump {} does not exist", name, style); if (argindex[iarg] > atom->dcols[n]) - error->all(FLERR,"Dump custom property array {} is accessed out-of-range",name); + error->all(FLERR,"Dump {} property array {} is accessed out-of-range", style, name); } field2index[iarg] = add_custom(name,1); @@ -1555,12 +1556,12 @@ int DumpCustom::parse_fields(int narg, char **arg) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); if (argindex[iarg] == 0) { if (flag || cols) - error->all(FLERR,"Property integer vector {} for dump custom does not exist",name); + error->all(FLERR,"Property integer vector {} for dump {} does not exist", name, style); } else { if (flag || !cols) - error->all(FLERR,"Property integer array {} for dump custom does not exist",name); + error->all(FLERR,"Property integer array {} for dump {} does not exist", name, style); if (argindex[iarg] > atom->icols[n]) - error->all(FLERR,"Dump custom property array {} is accessed out-of-range",name); + error->all(FLERR,"Dump {} property array {} is accessed out-of-range", style, name); } field2index[iarg] = add_custom(name,0); @@ -1945,9 +1946,9 @@ int DumpCustom::modify_param(int narg, char **arg) case ArgInfo::VARIABLE: thresh_array[nthresh] = VARIABLE; n = input->variable->find(name); - if (n < 0) error->all(FLERR,"Could not find dump modify variable name: {}",name); + if (n < 0) error->all(FLERR,"Could not find dump modify variable name: {}", name); if (input->variable->atomstyle(n) == 0) - error->all(FLERR,"Dump modify variable {} is not atom-style variable",name); + error->all(FLERR,"Dump modify variable {} is not atom-style variable", name); field2index[nfield+nthresh] = add_variable(name); break; @@ -1961,13 +1962,13 @@ int DumpCustom::modify_param(int narg, char **arg) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); if (argindex[nfield+nthresh] == 0) { if (!flag || cols) - error->all(FLERR,"Property double vector for dump custom does not exist"); + error->all(FLERR,"Property double vector {} for dump {} does not exist", name, style); thresh_array[nthresh] = DVEC; } else { if (!flag || !cols) - error->all(FLERR,"Property double array for dump custom does not exist"); + error->all(FLERR,"Property double array {} for dump {} does not exist", name, style); if (argindex[nfield+nthresh] > atom->dcols[n]) - error->all(FLERR,"Dump custom property array is accessed out-of-range"); + error->all(FLERR,"Dump {} property array {} is accessed out-of-range", style, name); thresh_array[nthresh] = DARRAY; } @@ -1983,13 +1984,13 @@ int DumpCustom::modify_param(int narg, char **arg) error->all(FLERR,"Could not find custom per-atom property ID: {}", name); if (argindex[nfield+nthresh] == 0) { if (flag || cols) - error->all(FLERR,"Property integer vector for dump custom does not exist"); + error->all(FLERR,"Property integer vector {} for dump {} does not exist", name, style); thresh_array[nthresh] = IVEC; } else { if (flag || !cols) - error->all(FLERR,"Property integer array for dump custom does not exist"); + error->all(FLERR,"Property integer array {} for dump {} does not exist", name, style); if (argindex[nfield+nthresh] > atom->icols[n]) - error->all(FLERR,"Dump custom property array is accessed out-of-range"); + error->all(FLERR,"Dump {} property array {} is accessed out-of-range", style, name); thresh_array[nthresh] = IARRAY; } @@ -1999,7 +2000,7 @@ int DumpCustom::modify_param(int narg, char **arg) // no match default: - error->all(FLERR,"Invalid dump_modify thresh attribute: {}",name); + error->all(FLERR,"Invalid dump_modify thresh attribute: {}", name); break; } } From bb9dc960b76ebb92841352f6b00fbc88dd90c9e9 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 16 Jun 2023 10:26:01 -0600 Subject: [PATCH 430/448] Use updated values from @cjknight --- src/KOKKOS/pair_snap_kokkos.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/KOKKOS/pair_snap_kokkos.h b/src/KOKKOS/pair_snap_kokkos.h index 0df02e0bc7..ca1884bfd2 100644 --- a/src/KOKKOS/pair_snap_kokkos.h +++ b/src/KOKKOS/pair_snap_kokkos.h @@ -100,9 +100,9 @@ class PairSNAPKokkos : public PairSNAP { #elif defined(KOKKOS_ENABLE_SYCL) static constexpr int team_size_compute_neigh = 4; static constexpr int tile_size_compute_ck = 4; - static constexpr int tile_size_pre_ui = 4; - static constexpr int team_size_compute_ui = 4; - static constexpr int tile_size_transform_ui = 4; + static constexpr int tile_size_pre_ui = 8; + static constexpr int team_size_compute_ui = 8; + static constexpr int tile_size_transform_ui = 8; static constexpr int tile_size_compute_zi = 4; static constexpr int tile_size_compute_bi = 4; static constexpr int tile_size_transform_bi = 4; From 2d3bbd2e725a00e2af227862ea86d9de2f9422d9 Mon Sep 17 00:00:00 2001 From: Stan Gerald Moore Date: Fri, 16 Jun 2023 10:52:21 -0600 Subject: [PATCH 431/448] Temporarily disable team policy for ghost neigh list build due to known bug --- src/KOKKOS/npair_kokkos.cpp | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/src/KOKKOS/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index 852a4a9280..06567cbeb6 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -240,22 +240,25 @@ void NPairKokkos::build(NeighList *list_) // assumes newton off NPairKokkosBuildFunctorGhost f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); -#ifdef LMP_KOKKOS_GPU - if (ExecutionSpaceFromDevice::space == Device) { - int team_size = atoms_per_bin*factor; - int team_size_max = Kokkos::TeamPolicy(team_size,Kokkos::AUTO).team_size_max(f,Kokkos::ParallelForTag()); - if (team_size <= team_size_max) { - Kokkos::TeamPolicy config((mbins+factor-1)/factor,team_size); - Kokkos::parallel_for(config, f); - } else { // fall back to flat method - f.sharedsize = 0; - Kokkos::parallel_for(nall, f); - } - } else - Kokkos::parallel_for(nall, f); -#else + +// temporarily disable team policy for ghost due to known bug + +//#ifdef LMP_KOKKOS_GPU +// if (ExecutionSpaceFromDevice::space == Device) { +// int team_size = atoms_per_bin*factor; +// int team_size_max = Kokkos::TeamPolicy(team_size,Kokkos::AUTO).team_size_max(f,Kokkos::ParallelForTag()); +// if (team_size <= team_size_max) { +// Kokkos::TeamPolicy config((mbins+factor-1)/factor,team_size); +// Kokkos::parallel_for(config, f); +// } else { // fall back to flat method +// f.sharedsize = 0; +// Kokkos::parallel_for(nall, f); +// } +// } else +// Kokkos::parallel_for(nall, f); +//#else Kokkos::parallel_for(nall, f); -#endif +//#endif } else { if (SIZE) { NPairKokkosBuildFunctorSize f(data,atoms_per_bin * 6 * sizeof(X_FLOAT) * factor); From 6f5e5746b356e15f2a18a60c4e67de73f946182d Mon Sep 17 00:00:00 2001 From: ilia-nikiforov-umn <78983960+ilia-nikiforov-umn@users.noreply.github.com> Date: Fri, 16 Jun 2023 12:21:42 -0500 Subject: [PATCH 432/448] Update lib/kim/README Fix some typos and update to non-deprecated form of kim commands --- lib/kim/README | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/kim/README b/lib/kim/README index 3cba4a4597..b4cba92fb5 100644 --- a/lib/kim/README +++ b/lib/kim/README @@ -1,6 +1,6 @@ This directory contains build settings for the KIM API library which is -required to use the KIM package and its kim_init, kim_interactions, kim_query, -and pair_kim commands in a LAMMPS input script. +required to use the KIM package and its kim init, kim interactions and kim query +commands in a LAMMPS input script. Information about the KIM project can be found at https://openkim.org. The KIM project is lead by Ellad Tadmor and Ryan Elliott (U Minn). @@ -13,7 +13,7 @@ do the same thing by typing "python Install.py" from within this directory, or you can do it manually by following the instructions below. -Use of the kim_query command requires that the CURL library (libcurl) +Use of the kim query command requires that the CURL library (libcurl) development package and its configuration query tool, curl-config, are installed. The provided Makefile.lammps is set up to automatically detect this. @@ -29,7 +29,7 @@ $ printf "${PWD}/installed-kim-api-X-X.Y.Z" > ./kim-prefix.txt 2. Download and unpack the kim-api $ wget http://s3.openkim.org/kim-api/kim-api-X.Y.Z.txz -$ tar zxvf kim-api-X.Y.Z.txz +$ tar xvf kim-api-X.Y.Z.txz # configure the kim-api $ cd kim-api-X.Y.Z @@ -50,7 +50,7 @@ $ rm -rf kim-api-X.Y.Z.txz 5. To add items do the following (replace the kim item name with your desired value) -$ source ${PWD}/kim-api-X.Y.Z/bin/kim-api-activate +$ source ${PWD}/installed-kim-api-X.Y.Z/bin/kim-api-activate $ kim-api-collections-management install system EAM_ErcolessiAdams_1994_Al__MO_324507536345_002 @@ -59,7 +59,7 @@ $ kim-api-collections-management install system EAM_ErcolessiAdams_1994_Al__MO_3 When these steps are complete you can build LAMMPS with the KIM package installed: -$ cd lammpos/src +$ cd lammps/src $ make yes-kim $ make g++ (or whatever target you wish) From ce75691eaed0c71c5eb8d258c534dd97d96297a5 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 00:35:05 -0400 Subject: [PATCH 433/448] address issues flagged by coverity scan --- src/DPD-REACT/fix_eos_table_rx.cpp | 10 ++++------ src/DPD-REACT/fix_rx.cpp | 15 +++++---------- src/YAFF/pair_lj_switch3_coulgauss_long.cpp | 2 -- 3 files changed, 9 insertions(+), 18 deletions(-) diff --git a/src/DPD-REACT/fix_eos_table_rx.cpp b/src/DPD-REACT/fix_eos_table_rx.cpp index 2687a11658..f7afddc64f 100644 --- a/src/DPD-REACT/fix_eos_table_rx.cpp +++ b/src/DPD-REACT/fix_eos_table_rx.cpp @@ -476,16 +476,14 @@ void FixEOStableRX::read_table(Table *tb, Table *tb2, char *file, char *keyword) utils::sfgets(FLERR,line,MAXLINE,fp,file,error); nwords = utils::count_words(utils::trim_comment(line)); - if (nwords != nspecies+2) { - printf("nwords=%d nspecies=%d\n",nwords,nspecies); - error->all(FLERR,"Illegal fix eos/table/rx command"); - } - nwords = 0; + if (nwords != nspecies+2) + error->all(FLERR,"Illegal fix eos/table/rx command: nwords={} nspecies={}", nwords, nspecies); + word = strtok(line," \t\n\r\f"); word = strtok(nullptr," \t\n\r\f"); rtmp = atof(word); - for (int icolumn=0;icolumn Date: Sat, 17 Jun 2023 14:38:49 -0400 Subject: [PATCH 434/448] fix logic bug --- src/ELECTRODE/fix_electrode_conp.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ELECTRODE/fix_electrode_conp.cpp b/src/ELECTRODE/fix_electrode_conp.cpp index 1547fa6b97..dafd3c8fec 100644 --- a/src/ELECTRODE/fix_electrode_conp.cpp +++ b/src/ELECTRODE/fix_electrode_conp.cpp @@ -1209,8 +1209,8 @@ FixElectrodeConp::~FixElectrodeConp() } catch (std::exception &) { } } - if (!modify->get_fix_by_id(id)) // avoid segfault if derived fixes' ctor throws err - atom->delete_callback(id, Atom::GROW); // atomvec track local electrode atoms + + if (modify->get_fix_by_id(id)) atom->delete_callback(id, Atom::GROW); delete[] recvcounts; delete[] displs; From 37ca3f9af83e7e99614eff5c281e4a5925c5aa53 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 14:38:59 -0400 Subject: [PATCH 435/448] apply clang-format --- src/ELECTRODE/fix_electrode_conp.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/ELECTRODE/fix_electrode_conp.cpp b/src/ELECTRODE/fix_electrode_conp.cpp index dafd3c8fec..85f59127f1 100644 --- a/src/ELECTRODE/fix_electrode_conp.cpp +++ b/src/ELECTRODE/fix_electrode_conp.cpp @@ -859,7 +859,7 @@ void FixElectrodeConp::update_charges() std::vector FixElectrodeConp::ele_ele_interaction(const std::vector &q_local) { - assert((int)q_local.size() == nlocalele); + assert((int) q_local.size() == nlocalele); assert(algo == Algo::CG || algo == Algo::MATRIX_CG); if (algo == Algo::CG) { set_charges(q_local); @@ -873,7 +873,7 @@ std::vector FixElectrodeConp::ele_ele_interaction(const std::vector q_local) { - assert((int)q_local.size() == nlocalele); + assert((int) q_local.size() == nlocalele); double *q = atom->q; for (int i = 0; i < nlocalele; i++) q[atom->map(taglist_local[i])] = q_local[i]; comm->forward_comm(this); @@ -942,7 +942,7 @@ std::vector FixElectrodeConp::scale_vector(double alpha, std::vector FixElectrodeConp::add_nlocalele(std::vector a, std::vector b) { - assert(((int)a.size() == nlocalele) && ((int)b.size() == nlocalele)); + assert(((int) a.size() == nlocalele) && ((int) b.size() == nlocalele)); for (int i = 0; i < nlocalele; i++) a[i] += b[i]; return a; } @@ -951,7 +951,7 @@ std::vector FixElectrodeConp::add_nlocalele(std::vector a, std:: double FixElectrodeConp::dot_nlocalele(std::vector a, std::vector b) { - assert(((int)a.size() == nlocalele) && ((int)b.size() == nlocalele)); + assert(((int) a.size() == nlocalele) && ((int) b.size() == nlocalele)); double out = 0.; for (int i = 0; i < nlocalele; i++) out += a[i] * b[i]; MPI_Allreduce(MPI_IN_PLACE, &out, 1, MPI_DOUBLE, MPI_SUM, world); @@ -962,7 +962,7 @@ double FixElectrodeConp::dot_nlocalele(std::vector a, std::vector FixElectrodeConp::times_elastance(std::vector x) { - assert((int)x.size() == ngroup); + assert((int) x.size() == ngroup); auto out = std::vector(nlocalele, 0.); for (int i = 0; i < nlocalele; i++) { double *_noalias row = elastance[list_iele[i]]; @@ -1412,7 +1412,7 @@ void FixElectrodeConp::gather_list_iele() } } nlocalele = static_cast(taglist_local.size()); // just for safety - assert((int)iele_to_group_local.size() == nlocalele); + assert((int) iele_to_group_local.size() == nlocalele); if (matrix_algo) { MPI_Allgather(&nlocalele, 1, MPI_INT, recvcounts, 1, MPI_INT, world); From 9231ec6dbe6978c79dd81f60ee7c1739a25665bc Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 14:39:32 -0400 Subject: [PATCH 436/448] avoid segfault on deleting callback when there is an error in the constructor or a derived class --- src/QEQ/fix_qeq.cpp | 3 ++- src/RIGID/fix_rigid_small.cpp | 2 +- src/RIGID/fix_shake.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/QEQ/fix_qeq.cpp b/src/QEQ/fix_qeq.cpp index c8112ca24d..394ce69d22 100644 --- a/src/QEQ/fix_qeq.cpp +++ b/src/QEQ/fix_qeq.cpp @@ -143,7 +143,8 @@ FixQEq::FixQEq(LAMMPS *lmp, int narg, char **arg) : FixQEq::~FixQEq() { // unregister callbacks to this fix from Atom class - atom->delete_callback(id,Atom::GROW); + + if (modify->get_fix_by_id(id)) atom->delete_callback(id,Atom::GROW); memory->destroy(s_hist); memory->destroy(t_hist); diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index 089c644f1e..c579e362c7 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -481,7 +481,7 @@ FixRigidSmall::~FixRigidSmall() { // unregister callbacks to this fix from Atom class - atom->delete_callback(id,Atom::GROW); + if (modify->get_fix_by_id(id)) atom->delete_callback(id,Atom::GROW); // delete locally stored arrays diff --git a/src/RIGID/fix_shake.cpp b/src/RIGID/fix_shake.cpp index 6cd624c755..94c7668453 100644 --- a/src/RIGID/fix_shake.cpp +++ b/src/RIGID/fix_shake.cpp @@ -255,7 +255,7 @@ FixShake::~FixShake() // unregister callbacks to this fix from Atom class - atom->delete_callback(id,Atom::GROW); + if (modify->get_fix_by_id(id)) atom->delete_callback(id,Atom::GROW); // set bond_type and angle_type back to positive for SHAKE clusters // must set for all SHAKE bonds and angles stored by each atom From a3de790a0da60c1ff13a39e0617bc75f45bdb9b1 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 15:01:17 -0400 Subject: [PATCH 437/448] include git descriptor info when compiling develop or maintenance version --- src/lammps.cpp | 8 +++++++- unittest/CMakeLists.txt | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/lammps.cpp b/src/lammps.cpp index 1c7d12f79c..956793c20a 100644 --- a/src/lammps.cpp +++ b/src/lammps.cpp @@ -132,6 +132,12 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : num_ver = utils::date2num(version); restart_ver = -1; + // append git descriptor info to update string when compiling development or maintenance version + + std::string update_string = UPDATE_STRING; + if (has_git_info() && (update_string == " - Development") || (update_string == " - Maintenance")) + update_string += fmt::format(" - {}", git_descriptor()); + external_comm = 0; mdicomm = nullptr; @@ -524,7 +530,7 @@ LAMMPS::LAMMPS(int narg, char **arg, MPI_Comm communicator) : if (infile == nullptr) error->one(FLERR,"Cannot open input script {}: {}", arg[inflag], utils::getsyserror()); if (!helpflag) - utils::logmesg(this,fmt::format("LAMMPS ({}{})\n",version,UPDATE_STRING)); + utils::logmesg(this,fmt::format("LAMMPS ({}{})\n", version, update_string)); // warn against using I/O redirection in parallel runs if ((inflag == 0) && (universe->nprocs > 1)) diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index f41e8a2878..f7be54f9ae 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -54,7 +54,7 @@ add_test(NAME RunLammps COMMAND $ -log none -echo none -in in.empty) set_tests_properties(RunLammps PROPERTIES ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=2" - PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development)?( - Maintenance)?\\)") + PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development.*)?( - Maintenance.*)?\\)") # check if the compiled executable will print the help message add_test(NAME HelpMessage From 058d817335db93ed263cb9aa16770af20761a408 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 17:45:16 -0400 Subject: [PATCH 438/448] whitespace --- src/RIGID/fix_rigid_small.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RIGID/fix_rigid_small.cpp b/src/RIGID/fix_rigid_small.cpp index c579e362c7..bf0a847d48 100644 --- a/src/RIGID/fix_rigid_small.cpp +++ b/src/RIGID/fix_rigid_small.cpp @@ -259,7 +259,7 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : utils::numeric(FLERR,arg[iarg+3],false,lmp); p_flag[0] = p_flag[1] = p_flag[2] = 1; if (domain->dimension == 2) { - p_start[2] = p_stop[2] = p_period[2] = 0.0; + p_start[2] = p_stop[2] = p_period[2] = 0.0; p_flag[2] = 0; } iarg += 4; @@ -275,7 +275,7 @@ FixRigidSmall::FixRigidSmall(LAMMPS *lmp, int narg, char **arg) : p_flag[0] = p_flag[1] = p_flag[2] = 1; if (domain->dimension == 2) { p_start[2] = p_stop[2] = p_period[2] = 0.0; - p_flag[2] = 0; + p_flag[2] = 0; } iarg += 4; From f193a87426b0a4bb32abd8fb22369869aa15f25c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 18:04:38 -0400 Subject: [PATCH 439/448] correct CMake syntax --- unittest/c-library/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unittest/c-library/CMakeLists.txt b/unittest/c-library/CMakeLists.txt index 21b00b5c03..496cbb5055 100644 --- a/unittest/c-library/CMakeLists.txt +++ b/unittest/c-library/CMakeLists.txt @@ -88,7 +88,7 @@ if(BUILD_MPI) add_test(NAME RunCoupleSimpleCC COMMAND $ 1 ${LAMMPS_DIR}/examples/COUPLE/simple/in.lj) - if($) + if(TARGET simpleF90) add_test(NAME RunCoupleSimpleF90 COMMAND $ 1 ${LAMMPS_DIR}/examples/COUPLE/simple/in.lj) set_tests_properties(RunCoupleSimpleF90 PROPERTIES From 5eba9d7ee3de42cc5fbc20c1bdfa45e614f013cd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 18:04:54 -0400 Subject: [PATCH 440/448] update regex for change to version output --- unittest/c-library/CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/unittest/c-library/CMakeLists.txt b/unittest/c-library/CMakeLists.txt index 496cbb5055..3e5b7a8cc0 100644 --- a/unittest/c-library/CMakeLists.txt +++ b/unittest/c-library/CMakeLists.txt @@ -80,7 +80,7 @@ if(BUILD_MPI) COMMAND $ 1 ${LAMMPS_DIR}/examples/COUPLE/plugin/in.lj $) set_tests_properties(RunCoupleSimplePlugin PROPERTIES ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=2" - PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development)?( - Maintenance)?\\)") + PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development.*)?( - Maintenance.*)?\\)") endif() add_subdirectory(${LAMMPS_DIR}/examples/COUPLE/simple ${CMAKE_BINARY_DIR}/build-simple) add_test(NAME RunCoupleSimpleC @@ -93,10 +93,10 @@ if(BUILD_MPI) COMMAND $ 1 ${LAMMPS_DIR}/examples/COUPLE/simple/in.lj) set_tests_properties(RunCoupleSimpleF90 PROPERTIES ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=2" - PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development)?( - Maintenance)?\\)") + PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development.*)?( - Maintenance.*)?\\)") endif() set_tests_properties(RunCoupleSimpleC RunCoupleSimpleCC PROPERTIES ENVIRONMENT "TSAN_OPTIONS=ignore_noninstrumented_modules=1;HWLOC_HIDE_ERRORS=2" - PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development)?( - Maintenance)?\\)") + PASS_REGULAR_EXPRESSION "LAMMPS \\([0-9]+ [A-Za-z]+ 2[0-9][0-9][0-9]( - Update [0-9]+)?( - Development.*)?( - Maintenance.*)?\\)") endif() From 753a0bd386162925b4d93c48bd4bcda06df308fe Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 18:22:53 -0400 Subject: [PATCH 441/448] remove obsolete Fortran interfaces from examples/COUPLE folder --- doc/src/Fortran.rst | 11 - examples/COUPLE/README | 13 +- examples/COUPLE/fortran2/.gitignore | 1 - examples/COUPLE/fortran2/LAMMPS-wrapper.cpp | 96 - examples/COUPLE/fortran2/LAMMPS-wrapper.h | 41 - examples/COUPLE/fortran2/LAMMPS.F90 | 1788 ----------------- examples/COUPLE/fortran2/Makefile | 41 - examples/COUPLE/fortran2/README | 273 --- examples/COUPLE/fortran2/in.simple | 16 - examples/COUPLE/fortran2/simple.f90 | 112 -- .../COUPLE/fortran_dftb/LAMMPS-wrapper.cpp | 96 - examples/COUPLE/fortran_dftb/LAMMPS-wrapper.h | 40 - .../COUPLE/fortran_dftb/LAMMPS-wrapper2.cpp | 80 - .../COUPLE/fortran_dftb/LAMMPS-wrapper2.h | 37 - examples/COUPLE/fortran_dftb/LAMMPS.F90 | 982 --------- examples/COUPLE/fortran_dftb/README | 37 - examples/COUPLE/fortran_dftb/data.diamond | 148 -- examples/COUPLE/fortran_dftb/dftb_in.hsd | 40 - examples/COUPLE/fortran_dftb/dftb_pin.hsd | 129 -- examples/COUPLE/fortran_dftb/in.simple | 16 - examples/COUPLE/fortran_dftb/log.simple | 71 - examples/COUPLE/fortran_dftb/makefile | 45 - examples/COUPLE/fortran_dftb/simple.f90 | 110 - 23 files changed, 4 insertions(+), 4219 deletions(-) delete mode 100644 examples/COUPLE/fortran2/.gitignore delete mode 100644 examples/COUPLE/fortran2/LAMMPS-wrapper.cpp delete mode 100644 examples/COUPLE/fortran2/LAMMPS-wrapper.h delete mode 100644 examples/COUPLE/fortran2/LAMMPS.F90 delete mode 100644 examples/COUPLE/fortran2/Makefile delete mode 100644 examples/COUPLE/fortran2/README delete mode 100644 examples/COUPLE/fortran2/in.simple delete mode 100644 examples/COUPLE/fortran2/simple.f90 delete mode 100644 examples/COUPLE/fortran_dftb/LAMMPS-wrapper.cpp delete mode 100644 examples/COUPLE/fortran_dftb/LAMMPS-wrapper.h delete mode 100644 examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.cpp delete mode 100644 examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.h delete mode 100644 examples/COUPLE/fortran_dftb/LAMMPS.F90 delete mode 100644 examples/COUPLE/fortran_dftb/README delete mode 100644 examples/COUPLE/fortran_dftb/data.diamond delete mode 100644 examples/COUPLE/fortran_dftb/dftb_in.hsd delete mode 100644 examples/COUPLE/fortran_dftb/dftb_pin.hsd delete mode 100644 examples/COUPLE/fortran_dftb/in.simple delete mode 100644 examples/COUPLE/fortran_dftb/log.simple delete mode 100644 examples/COUPLE/fortran_dftb/makefile delete mode 100644 examples/COUPLE/fortran_dftb/simple.f90 diff --git a/doc/src/Fortran.rst b/doc/src/Fortran.rst index 7e9f16fa70..3b9ad9d1ff 100644 --- a/doc/src/Fortran.rst +++ b/doc/src/Fortran.rst @@ -56,17 +56,6 @@ C++ in the ``examples/COUPLE/simple`` folder of the LAMMPS distribution. and Ubuntu 18.04 LTS and not compatible. Either newer compilers need to be installed or the Linux updated. -.. versionchanged:: 8Feb2023 - -.. note:: - - A contributed Fortran interface is available in the - ``examples/COUPLE/fortran2`` folder. However, since the completion - of the :f:mod:`LIBLAMMPS` module, this interface is now deprecated, - no longer actively maintained and will likely be removed in the - future. Please see the ``README`` file in that folder for more - information about it and how to contact its author and maintainer. - ---------- Creating or deleting a LAMMPS object diff --git a/examples/COUPLE/README b/examples/COUPLE/README index adf46d027d..13e593d55d 100644 --- a/examples/COUPLE/README +++ b/examples/COUPLE/README @@ -19,12 +19,12 @@ See these sections of the LAMMPS manual for details: Build LAMMPS as a library (doc/html/Build_basics.html) Link LAMMPS as a library to another code (doc/html/Build_link.html) Coupling LAMMPS to other codes (doc/html/Howto_couple.html) -Using LAMMPS in client/server mode (doc/html/Howto_client_server.html) Library interface to LAMMPS (doc/html/Howto_library.html) +Detailed documentation of the LAMMPS interfaces (doc/html/Library.html) -The library interface to LAMMPS is in src/library.cpp. Routines can -be easily added to this file so an external program can perform the -LAMMPS tasks desired. +The core library interface to LAMMPS is in src/library.cpp. Routines +can be easily added to this file so an external program can perform +the LAMMPS tasks desired. ------------------------------------------------------------------- @@ -36,10 +36,5 @@ plugin example for loading LAMMPS at runtime from a shared library lammps_spparks grain-growth Monte Carlo with strain via MD, coupling to SPPARKS kinetic MC code library collection of useful inter-code communication routines -fortran2 a more sophisticated wrapper on the LAMMPS library API that - can be called from Fortran -fortran_dftb wrapper written by Nir Goldman (LLNL), as an - extension to fortran2, used for calling LAMMPS - from Fortran DFTB+ tight-binding code Each sub-directory has its own README with more details. diff --git a/examples/COUPLE/fortran2/.gitignore b/examples/COUPLE/fortran2/.gitignore deleted file mode 100644 index 63a7748cf4..0000000000 --- a/examples/COUPLE/fortran2/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.mod diff --git a/examples/COUPLE/fortran2/LAMMPS-wrapper.cpp b/examples/COUPLE/fortran2/LAMMPS-wrapper.cpp deleted file mode 100644 index 4774cb6b49..0000000000 --- a/examples/COUPLE/fortran2/LAMMPS-wrapper.cpp +++ /dev/null @@ -1,96 +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: Karl D. Hammond - University of Missouri (USA), 2012 -------------------------------------------------------------------------- */ - -/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself - provides a (I hope) robust Fortran interface to library.cpp and - library.h. All functions herein COULD be added to library.cpp instead of - including this as a separate file. See the README for instructions. */ - -#include -#include "LAMMPS-wrapper.h" -#define LAMMPS_LIB_MPI 1 -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace LAMMPS_NS; - -void lammps_open_fortran_wrapper (int argc, char **argv, - MPI_Fint communicator, void **ptr) -{ - MPI_Comm C_communicator = MPI_Comm_f2c (communicator); - lammps_open (argc, argv, C_communicator, ptr); -} - -int lammps_get_ntypes (void *ptr) -{ - class LAMMPS *lmp = (class LAMMPS *) ptr; - int ntypes = lmp->atom->ntypes; - return ntypes; -} - -void lammps_error_all (void *ptr, const char *file, int line, const char *str) -{ - class LAMMPS *lmp = (class LAMMPS *) ptr; - lmp->error->all (file, line, str); -} - -int lammps_extract_compute_vectorsize (void *ptr, char *id, int style) -{ - int *size; - size = (int *) lammps_extract_compute(ptr, id, style, LMP_SIZE_VECTOR); - if (size) return *size; - return 0; -} - -void lammps_extract_compute_arraysize (void *ptr, char *id, int style, - int *nrows, int *ncols) -{ - int *tmp; - tmp = (int *) lammps_extract_compute(ptr, id, style, LMP_SIZE_ROWS); - if (tmp) *nrows = *tmp; - tmp = (int *) lammps_extract_compute(ptr, id, style, LMP_SIZE_COLS); - if (tmp) *ncols = *tmp; - return; -} - -int lammps_extract_fix_vectorsize (void *ptr, char *id, int style) -{ - int *size; - size = (int *) lammps_extract_fix(ptr, id, style, LMP_SIZE_VECTOR, 0, 0); - if (size) return *size; - return 0; -} - -void lammps_extract_fix_arraysize (void *ptr, char *id, int style, - int *nrows, int *ncols) -{ - int *tmp; - tmp = (int *) lammps_extract_fix(ptr, id, style, LMP_SIZE_ROWS, 0, 0); - if (tmp) *nrows = *tmp; - tmp = (int *) lammps_extract_fix(ptr, id, style, LMP_SIZE_COLS, 0, 0); - if (tmp) *ncols = *tmp; - return; -} - -/* vim: set ts=3 sts=3 expandtab: */ diff --git a/examples/COUPLE/fortran2/LAMMPS-wrapper.h b/examples/COUPLE/fortran2/LAMMPS-wrapper.h deleted file mode 100644 index 02e1a651a9..0000000000 --- a/examples/COUPLE/fortran2/LAMMPS-wrapper.h +++ /dev/null @@ -1,41 +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: Karl D. Hammond - University of Missouri (USA), 2012 -------------------------------------------------------------------------- */ - -/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself - provides a (I hope) robust Fortran interface to library.cpp and - library.h. All prototypes herein COULD be added to library.h instead of - including this as a separate file. See the README for instructions. */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Prototypes for auxiliary functions */ -void lammps_open_fortran_wrapper (int, char**, MPI_Fint, void**); -int lammps_get_ntypes (void*); -int lammps_extract_compute_vectorsize (void*, char*, int); -void lammps_extract_compute_arraysize (void*, char*, int, int*, int*); -int lammps_extract_fix_vectorsize (void*, char*, int); -void lammps_extract_fix_arraysize (void*, char*, int, int*, int*); -void lammps_error_all (void*, const char*, int, const char*); - -#ifdef __cplusplus -} -#endif - -/* vim: set ts=3 sts=3 expandtab: */ diff --git a/examples/COUPLE/fortran2/LAMMPS.F90 b/examples/COUPLE/fortran2/LAMMPS.F90 deleted file mode 100644 index 2f4ae2c95e..0000000000 --- a/examples/COUPLE/fortran2/LAMMPS.F90 +++ /dev/null @@ -1,1788 +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: Karl D. Hammond -! University of Tennessee, Knoxville (USA), 2012 -! Updated October 2020 by the author (now at the University of Missouri). -!-------------------------------------------------------------------------- - -!! NOTE ------------------------------------------------------------------- -! This interface is obsolete and may be removed in a future release of -! LAMMPS. The interface in fortran/lammps.f90 replaces this one. That API -! is maintained by the LAMMPS developers and has documentation written for -! it; it is based loosely on this one, but binds all procedures to a lammps -! derived type. That interface was written in large -! part by the same author, but is also supported by other developers. -!-------------------------------------------------------------------------- - -!! LAMMPS, a Fortran 2003 module containing an interface between Fortran -!! programs and the C-style functions in library.cpp that ship with LAMMPS. -!! This file should be accompanied by LAMMPS-wrapper.cpp and LAMMPS-wrapper.h, -!! which define wrapper functions that ease portability and enforce array -!! dimensions. -!! -!! Everything in this module should be 100% portable by way of Fortran 2003's -!! ISO_C_BINDING intrinsic module. See the README for instructions for -!! compilation and use. -!! -!! Here are the PUBLIC functions and subroutines included in this module. -!! subroutine lammps_open (command_line, communicator, ptr) -!! subroutine lammps_open_no_mpi (command_line, ptr) -!! subroutine lammps_close (ptr) -!! integer (kind=C_int) lammps_version (ptr) -!! subroutine lammps_file (ptr, str) -!! subroutine lammps_command (ptr, str) -!! subroutine lammps_commands_list (ptr, cmds) -!! subroutine lammps_commands_string (ptr, str) -!! subroutine lammps_free (ptr) -!! integer function lammps_extract_setting (ptr, name) -!! subroutine lammps_extract_global (global, ptr, name) -!! subroutine lammps_extract_box (ptr, boxlo, boxhi, xy, yz, xz, & -!! periodicity, box_change) -!! subroutine lammps_extract_atom (atom, ptr, name) -!! subroutine lammps_extract_compute (compute, ptr, id, style, type) -!! subroutine lammps_extract_fix (fix, ptr, id, style, type, i, j) -!! subroutine lammps_extract_variable (variable, ptr, name, group) -!! double precision function lammps_get_thermo (ptr, name) -!! double precision function lammps_get_natoms (ptr) -!! subroutine lammps_set_variable (ptr, name, str, [err]) -!! subroutine lammps_reset_box (ptr, boxlo, boxhi, xy, yz, xz) -!! subroutine lammps_gather_atoms (ptr, name, count, data) -!! subroutine lammps_gather_atoms_concat (ptr, name, count, data) -!! subroutine lammps_gather_atoms_subset (ptr, name, count, ids, data) -!! subroutine lammps_scatter_atoms (ptr, name, data) -!! subroutine lammps_scatter_atoms_subset (ptr, name, ids, data) -!! logical function lammps_config_has_package (package_name) -!! integer function lammps_config_package_count () -!! logical function lammps_config_package_name (index, buffer) -!! logical function lammps_config_has_gzip_support () -!! logical function lammps_config_has_png_support () -!! logical function lammps_config_has_jpeg_support () -!! logical function lammps_config_has_ffmpeg_support () -!! logical function lammps_config_has_exceptions () -!! integer function lammps_find_pair_neighlist (ptr, style, exact, nsub, -!! request) -!! integer function lammps_find_fix_neighlist (ptr, id, request) -!! integer function lammps_find_compute_neighlist (ptr, id, request) -!! integer function lammps_neighlist_num_elements (ptr, idx) -!! subroutine lammps_neighlist_element_neighbors (ptr, idx, element, iatom, -!! numneigh, neighbors) -!! subroutine lammps_create_atoms (ptr, n, id, type, x, v, image, -!1 shrinkexceed) -!! -!! The following are also available if compiled with -DLAMMPS_EXCEPTIONS -!! function lammps_has_error (ptr) -!! function lammps_get_last_error_message (ptr, buffer) -!! -!! Note that the following function is not implemented from this interface: -!! lammps_set_fix_external_callback - -#define FLERR __FILE__,__LINE__ -! The above line allows for similar error checking as is done with standard -! LAMMPS files. - -! This should (?) allow this module to work with settings in lmptype.h -#if !defined(LAMMPS_SMALLSMALL) && !defined(LAMMPS_BIGBIG) && !defined(LAMMPS_SMALLBIG) -#define LAMMPS_SMALLBIG -#endif - -#ifdef LAMMPS_SMALLBIG -#define C_smallint C_int -#define C_imageint C_int -#define C_tagint C_int -#define C_bigint C_int64_t -#endif - -#ifdef LAMMPS_BIGBIG -#define C_smallint C_int -#define C_imageint C_int64_t -#define C_tagint C_int64_t -#define C_bigint C_int64_t -#endif - -#ifdef LAMMPS_SMALLSMALL -#define C_smallint C_int -#define C_imageint C_int -#define C_tagint C_int -#define C_bigint C_int -#endif - -module LAMMPS - - use, intrinsic :: ISO_C_binding, only : C_double, C_int, C_ptr, C_char, & - C_NULL_CHAR, C_NULL_PTR, C_loc, C_F_pointer, C_int64_t, & - lammps_instance => C_ptr - implicit none - private - - ! We inherit some ISO_C_BINDING entities for ease of use - public :: lammps_instance, C_ptr, C_double, C_int - ! Only the following functions may be called by the user: - public :: lammps_open, lammps_open_no_mpi, lammps_close, & - lammps_version, lammps_file, lammps_command, lammps_commands_list, & - lammps_commands_string, lammps_free, lammps_extract_setting, & - lammps_extract_global, lammps_extract_box, lammps_extract_atom, & - lammps_extract_compute, lammps_extract_fix, lammps_extract_variable, & - lammps_get_thermo, lammps_get_natoms, lammps_set_variable, & - lammps_reset_box, lammps_gather_atoms, lammps_gather_atoms_concat, & - lammps_gather_atoms_subset, lammps_scatter_atoms, & - lammps_scatter_atoms_subset, lammps_config_has_package, & - lammps_config_package_count, lammps_config_package_name, & - lammps_config_has_gzip_support, lammps_config_has_png_support, & - lammps_config_has_jpeg_support, lammps_config_has_ffmpeg_support, & - lammps_config_has_exceptions, lammps_find_pair_neighlist, & - lammps_find_fix_neighlist, lammps_find_compute_neighlist, & - lammps_neighlist_num_elements, lammps_neighlist_element_neighbors, & - lammps_create_atoms - -#ifdef LAMMPS_EXCEPTIONS - public :: lammps_has_error, lammps_get_last_error_message -#endif - - !! constants for extracting data from computes and fixes - !! and data types - - INTEGER, PARAMETER :: LMP_STYLE_GLOBAL = 0, LMP_STYLE_ATOM = 1, & - LMP_STYLE_LOCAL = 2, LMP_TYPE_SCALAR = 0, LMP_TYPE_VECTOR = 1, & - LMP_TYPE_ARRAY = 2, LMP_SIZE_VECTOR = 3, LMP_SIZE_ROWS = 4, & - LMP_SIZE_COLS = 5, LAMMPS_INT = 0, LAMMPS_INT_2D = 1, & - LAMMPS_DOUBLE = 2, LAMMPS_DOUBLE_2D = 3, LAMMPS_INT64 = 4, & - LAMMPS_INT64_2D = 5, LAMMPS_STRING = 6 - - PUBLIC :: LMP_STYLE_GLOBAL, LMP_STYLE_ATOM, LMP_STYLE_LOCAL, & - LMP_TYPE_SCALAR, LMP_TYPE_VECTOR, LMP_TYPE_ARRAY, & - LMP_SIZE_VECTOR, LMP_SIZE_ROWS, LMP_SIZE_COLS, LAMMPS_INT, & - LAMMPS_INT_2D, LAMMPS_DOUBLE, LAMMPS_DOUBLE_2D, LAMMPS_INT64, & - LAMMPS_INT64_2D, LAMMPS_STRING - - !! Functions supplemental to the prototypes in library.h. {{{1 - !! The function definitions (in C++) are contained in LAMMPS-wrapper.cpp. - !! I would have written the first in Fortran, but the MPI libraries (which - !! were written in C) have C-based functions to convert from Fortran MPI - !! handles to C MPI handles, and there is no Fortran equivalent for those - !! functions. - interface - subroutine lammps_open_wrapper (argc, argv, communicator, ptr) & - bind (C, name='lammps_open_fortran_wrapper') - import :: C_int, C_ptr - integer (C_int), value :: argc - type (C_ptr), dimension(*) :: argv - integer, value :: communicator - type (C_ptr) :: ptr - end subroutine lammps_open_wrapper - subroutine lammps_actual_error_all (ptr, file, line, str) & - bind (C, name='lammps_error_all') - import :: C_int, C_char, C_ptr - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: file, str - integer (C_int), value :: line - end subroutine lammps_actual_error_all - function lammps_get_ntypes (ptr) result (ntypes) & - bind (C, name='lammps_get_ntypes') - import :: C_int, C_ptr - type (C_ptr), value :: ptr - integer (C_int) :: ntypes - end function lammps_get_ntypes - function lammps_actual_extract_compute_vectorsize (ptr, id, style) & - result (vectorsize) bind (C, name='lammps_extract_compute_vectorsize') - import :: C_int, C_char, C_ptr - integer (C_int) :: vectorsize - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - end function lammps_actual_extract_compute_vectorsize - subroutine lammps_actual_extract_compute_arraysize (ptr, id, style, & - nrows, ncols) bind (C, name='lammps_extract_compute_arraysize') - import :: C_int, C_char, C_ptr - integer (C_int) :: arraysize - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - integer (C_int) :: nrows, ncols - end subroutine lammps_actual_extract_compute_arraysize - function lammps_actual_extract_fix_vectorsize (ptr, id, style) & - result (vectorsize) bind (C, name='lammps_extract_fix_vectorsize') - import :: C_int, C_char, C_ptr - integer (C_int) :: vectorsize - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - end function lammps_actual_extract_fix_vectorsize - subroutine lammps_actual_extract_fix_arraysize (ptr, id, style, & - nrows, ncols) bind (C, name='lammps_extract_fix_arraysize') - import :: C_int, C_char, C_ptr - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - integer (C_int) :: nrows, ncols - end subroutine lammps_actual_extract_fix_arraysize - end interface - - !! Functions/subroutines defined in library.h and library.cpp {{{1 - interface - subroutine lammps_actual_open_no_mpi (argc, argv, ptr) & - bind (C, name='lammps_open_no_mpi') - import :: C_int, C_ptr - integer (C_int), value :: argc - type (C_ptr), dimension(*) :: argv - type (C_ptr) :: ptr - end subroutine lammps_actual_open_no_mpi - - subroutine lammps_close (ptr) bind (C, name='lammps_close') - import :: C_ptr - type (C_ptr), value :: ptr - end subroutine lammps_close - - function lammps_version (ptr) result (version) & - bind (C, name='lammps_version') - import :: C_ptr, C_int - type (C_ptr), value :: ptr - integer (kind=C_int) :: version - end function lammps_version - - subroutine lammps_actual_file (ptr, str) bind (C, name='lammps_file') - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: str - end subroutine lammps_actual_file - - function lammps_actual_command (ptr, str) result (command) & - bind (C, name='lammps_command') - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: str - type (C_ptr) :: command - end function lammps_actual_command - - subroutine lammps_actual_commands_list (ptr, ncmd, cmds) & - bind (C, name='lammps_commands_list') - import :: C_ptr, C_int - type (C_ptr), value :: ptr - type (C_ptr), dimension(*) :: cmds - integer (C_int), value :: ncmd - end subroutine lammps_actual_commands_list - - subroutine lammps_actual_commands_string (ptr, str) & - bind (C, name='lammps_commands_string') - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: str - end subroutine lammps_actual_commands_string - - subroutine lammps_free (ptr) bind (C, name='lammps_free') - import :: C_ptr - type (C_ptr), value :: ptr - end subroutine lammps_free - - function lammps_actual_extract_setting (ptr, name) result (setting) & - bind(C, name='lammps_extract_setting') - import :: C_ptr, C_char, C_int - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name - integer (kind=C_int) :: setting - end function lammps_actual_extract_setting - - function lammps_actual_extract_global (ptr, name) & - bind (C, name='lammps_extract_global') result (global) - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name - type (C_ptr) :: global - end function lammps_actual_extract_global - - subroutine lammps_actual_extract_box (ptr, boxlo, boxhi, xy, yz, & - xz, periodicity, box_change) bind (C, name='lammps_extract_box') - import :: C_ptr, C_double, C_int - type (C_ptr), value :: ptr - real (C_double) :: boxlo(3), boxhi(3), xy, yz, xz - integer (C_int) :: periodicity(3), box_change - end subroutine lammps_actual_extract_box - - function lammps_actual_extract_atom (ptr, name) & - bind (C, name='lammps_extract_atom') result (atom) - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name - type (C_ptr) :: atom - end function lammps_actual_extract_atom - - function lammps_actual_extract_compute (ptr, id, style, type) & - result (compute) bind (C, name='lammps_extract_compute') - import :: C_ptr, C_char, C_int - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style, type - type (C_ptr) :: compute - end function lammps_actual_extract_compute - - function lammps_actual_extract_fix (ptr, id, style, type, i, j) & - result (fix) bind (C, name='lammps_extract_fix') - import :: C_ptr, C_char, C_int - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style, type, i, j - type (C_ptr) :: fix - end function lammps_actual_extract_fix - - function lammps_actual_extract_variable (ptr, name, group) & - result (variable) bind (C, name='lammps_extract_variable') - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name, group - type (C_ptr) :: variable - end function lammps_actual_extract_variable - - function lammps_actual_get_thermo (ptr, name) result (dval) & - bind (C, name='lammps_get_thermo') - import :: C_ptr, C_char, C_double - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name - real (C_double) :: dval - end function lammps_actual_get_thermo - - function lammps_get_natoms (ptr) result (natoms) & - bind (C, name='lammps_get_natoms') - import :: C_ptr, C_double - type (C_ptr), value :: ptr - real (C_double) :: natoms - end function lammps_get_natoms - - function lammps_actual_set_variable (ptr, name, str) result (err) & - bind (C, name='lammps_set_variable') - import :: C_ptr, C_char, C_int - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name, str - integer (C_int) :: err - end function lammps_actual_set_variable - - subroutine lammps_actual_reset_box (ptr, boxlo, boxhi, xy, yz, xz) & - bind (C, name='lammps_reset_box') - import :: C_ptr, C_double, C_int - type (C_ptr), value :: ptr - real (C_double) :: boxlo(3), boxhi(3), xy, yz, xz - end subroutine lammps_actual_reset_box - - subroutine lammps_actual_gather_atoms (ptr, name, type, count, data) & - bind (C, name='lammps_gather_atoms') - import :: C_ptr, C_int, C_char - type (C_ptr), value :: ptr, data - character (kind=C_char), dimension(*) :: name - integer (C_int), value :: type, count - end subroutine lammps_actual_gather_atoms - - subroutine lammps_actual_gather_atoms_concat (ptr, name, type, count, & - data) bind (C, name='lammps_gather_atoms_concat') - import :: C_ptr, C_int, C_char - type (C_ptr), value :: ptr, data - character (kind=C_char), dimension(*) :: name - integer (C_int), value :: type, count - end subroutine lammps_actual_gather_atoms_concat - - subroutine lammps_actual_gather_atoms_subset (ptr, name, type, count, & - ndata, ids, data) bind (C, name='lammps_gather_atoms_subset') - import :: C_ptr, C_int, C_char - type (C_ptr), value :: ptr, data - character (kind=C_char), dimension(*) :: name - integer (C_int), value :: type, count, ndata - integer (C_int) :: ids(:) - end subroutine lammps_actual_gather_atoms_subset - - subroutine lammps_actual_scatter_atoms (ptr, name, type, count, data) & - bind (C, name='lammps_scatter_atoms') - import :: C_ptr, C_int, C_char - type (C_ptr), value :: ptr, data - character (kind=C_char), dimension(*) :: name - integer (C_int), value :: type, count - end subroutine lammps_actual_scatter_atoms - - subroutine lammps_actual_scatter_atoms_subset (ptr, name, type, count, & - ndata, ids, data) bind (C, name='lammps_scatter_atoms_subset') - import :: C_ptr, C_int, C_char - type (C_ptr), value :: ptr, data - character (kind=C_char), dimension(*) :: name - integer (C_int), value :: type, count, ndata - integer (C_int), dimension(*) :: ids - end subroutine lammps_actual_scatter_atoms_subset - - function lammps_actual_config_has_package (package_name) & - result (has_it) bind (C, name='lammps_config_has_package') - import :: C_char, C_int - character (len=1, kind=C_char), dimension(*) :: package_name - integer (C_int) :: has_it - end function lammps_actual_config_has_package - - function lammps_config_package_count () result (count) & - bind (C, name='lammps_config_package_count') - import :: C_int - integer (C_int) :: count - end function lammps_config_package_count - - function lammps_actual_config_package_name (index, buffer, max_size) & - result (num) bind (C, name='lammps_config_package_name') - import :: C_int, C_char - integer (C_int), value :: index, max_size - character (len=1, kind=C_char), dimension(*) :: buffer - integer (C_int) :: num - end function lammps_actual_config_package_name - - function lammps_actual_config_has_gzip_support () result (C_has_it) & - bind (C, name='lammps_config_has_gzip_support') - import :: C_int - integer (C_int) :: C_has_it - end function lammps_actual_config_has_gzip_support - - function lammps_actual_config_has_png_support () result (C_has_it) & - bind (C, name='lammps_config_has_png_support') - import :: C_int - integer (C_int) :: C_has_it - end function lammps_actual_config_has_png_support - - function lammps_actual_config_has_jpeg_support () result (C_has_it) & - bind (C, name='lammps_config_has_jpeg_support') - import :: C_int - integer (C_int) :: C_has_it - end function lammps_actual_config_has_jpeg_support - - function lammps_actual_config_has_ffmpeg_support () result (C_has_it) & - bind (C, name='lammps_config_has_ffmpeg_support') - import :: C_int - integer (C_int) :: C_has_it - end function lammps_actual_config_has_ffmpeg_support - - function lammps_actual_config_has_exceptions () result (C_has_it) & - bind (C, name='lammps_config_has_exceptions') - import :: C_int - integer (C_int) :: C_has_it - end function lammps_actual_config_has_exceptions - - function lammps_actual_find_pair_neighlist (ptr, style, exact, nsub, & - request) result (C_neighlist) & - bind (C, name='lammps_find_pair_neighlist') - import :: C_ptr, C_int, C_char - integer (C_int) :: C_neighlist - type (C_ptr), value :: ptr - character (len=1, kind=C_char), dimension(*) :: style - integer (C_int), value :: exact, nsub, request - end function lammps_actual_find_pair_neighlist - - function lammps_actual_find_fix_neighlist (ptr, id, request) & - result (C_neighlist) bind (C, name='lammps_find_fix_neighlist') - import :: C_ptr, C_int, C_char - integer (C_int) :: C_neighlist - type (C_ptr), value :: ptr - character (len=1, kind=C_char), dimension(*) :: id - integer (C_int), value :: request - end function lammps_actual_find_fix_neighlist - - function lammps_actual_find_compute_neighlist (ptr, id, request) & - result (C_neighlist) bind (C, name='lammps_find_compute_neighlist') - import :: C_ptr, C_int, C_char - integer (C_int) :: C_neighlist - type (C_ptr), value :: ptr - character (len=1, kind=C_char), dimension(*) :: id - integer (C_int), value :: request - end function lammps_actual_find_compute_neighlist - - function lammps_actual_neighlist_num_elements (ptr, idx) & - result (nelements) bind (C, name='lammps_neighlist_num_elements') - import :: C_ptr, C_int - integer (C_int) :: nelements - type (C_ptr), value :: ptr - integer (C_int), value :: idx - end function lammps_actual_neighlist_num_elements - - subroutine lammps_actual_neighlist_element_neighbors (ptr, idx, & - element, iatom, numneigh, neighbors) & - bind (C, name='lammps_neighlist_element_neighbors') - import :: C_ptr, C_int - type (C_ptr), value :: ptr - integer (C_int), value :: idx, element - integer (C_int) :: iatom, numneigh - type (C_ptr) :: neighbors - end subroutine lammps_actual_neighlist_element_neighbors - - subroutine lammps_actual_create_atoms (ptr, n, id, type, x, v, image, & - shrinkexceed) bind (C, name='lammps_create_atoms') - import :: C_ptr, C_int64_t, C_double, C_int - type (C_ptr), value :: ptr - integer (C_int), value :: n - integer (C_tagint) :: id - integer (C_int) :: type - real (C_double), dimension(*) :: x, v - integer (C_imageint), dimension(*) :: image - integer (C_int), value :: shrinkexceed - end subroutine lammps_actual_create_atoms - -#ifdef LAMMPS_EXCEPTIONS - - function lammps_actual_has_error (ptr) result (C_has_it) & - bind (C, name='lammps_has_error') - import :: C_int, C_ptr - type (C_ptr), value :: ptr - integer (C_int) :: C_has_it - end function lammps_actual_has_error - - function lammps_actual_get_last_error_message (ptr, buffer, & - buffer_size) result (error_type) & - bind (C, name='lammps_get_last_error_message') - import :: C_ptr, C_char, C_int - type (C_ptr), value :: ptr - integer (C_int), value :: buffer_size - character (len=1, kind=C_char), dimension(*) :: buffer - integer (C_int) :: error_type - end function lammps_actual_get_last_error_message - -#endif - - end interface - - ! Generic functions for the wrappers below {{{1 - - interface lammps_extract_global - module procedure lammps_extract_global_i, & - lammps_extract_global_dp - end interface lammps_extract_global - - interface lammps_extract_atom - module procedure lammps_extract_atom_ia, & - lammps_extract_atom_dpa, & - lammps_extract_atom_dp2a - end interface lammps_extract_atom - - interface lammps_extract_compute - module procedure lammps_extract_compute_dp, & - lammps_extract_compute_dpa, & - lammps_extract_compute_dp2a - end interface lammps_extract_compute - - interface lammps_extract_fix - module procedure lammps_extract_fix_dp, & - lammps_extract_fix_dpa, & - lammps_extract_fix_dp2a - end interface lammps_extract_fix - - interface lammps_extract_variable - module procedure lammps_extract_variable_dp, & - lammps_extract_variable_dpa - end interface lammps_extract_variable - - interface lammps_gather_atoms - module procedure lammps_gather_atoms_ia, lammps_gather_atoms_dpa - end interface lammps_gather_atoms - - interface lammps_gather_atoms_concat - module procedure lammps_gather_atoms_concat_ia, & - lammps_gather_atoms_concat_dpa - end interface lammps_gather_atoms_concat - - interface lammps_gather_atoms_subset - module procedure lammps_gather_atoms_subset_ia, & - lammps_gather_atoms_subset_dpa - end interface lammps_gather_atoms_subset - - interface lammps_scatter_atoms - module procedure lammps_scatter_atoms_ia, lammps_scatter_atoms_dpa - end interface lammps_scatter_atoms - - interface lammps_scatter_atoms_subset - module procedure lammps_scatter_atoms_subset_ia, & - lammps_scatter_atoms_subset_dpa - end interface lammps_scatter_atoms_subset - -contains !! Wrapper functions local to this module {{{1 - - subroutine lammps_open (command_line, communicator, ptr) - character (len=*), intent(in) :: command_line - integer, intent(in) :: communicator - type (C_ptr) :: ptr - integer (C_int) :: argc - type (C_ptr), dimension(:), allocatable :: argv - character (kind=C_char), dimension(len_trim(command_line)+1), target :: & - c_command_line - c_command_line = string2Cstring (command_line) - call Cstring2argcargv (c_command_line, argc, argv) - call lammps_open_wrapper (argc, argv, communicator, ptr) - deallocate (argv) - end subroutine lammps_open - -!----------------------------------------------------------------------------- - - subroutine lammps_open_no_mpi (command_line, ptr) - character (len=*), intent(in) :: command_line - type (C_ptr) :: ptr - integer (C_int) :: argc - type (C_ptr), dimension(:), allocatable :: argv - character (kind=C_char), dimension(len_trim(command_line)+1), target :: & - c_command_line - c_command_line = string2Cstring (command_line) - call Cstring2argcargv (c_command_line, argc, argv) - call lammps_actual_open_no_mpi (argc, argv, ptr) - deallocate (argv) - end subroutine lammps_open_no_mpi - -!----------------------------------------------------------------------------- - - subroutine lammps_file (ptr, str) - type (C_ptr) :: ptr - character (len=*) :: str - character (kind=C_char), dimension(len_trim(str)+1) :: Cstr - Cstr = string2Cstring (str) - call lammps_actual_file (ptr, Cstr) - end subroutine lammps_file - -!----------------------------------------------------------------------------- - - subroutine lammps_command (ptr, str) - type (C_ptr) :: ptr - character (len=*) :: str - character (kind=C_char), dimension(len_trim(str)+1) :: Cstr - type (C_ptr) :: dummy - Cstr = string2Cstring (str) - dummy = lammps_actual_command (ptr, Cstr) - end subroutine lammps_command - -!----------------------------------------------------------------------------- - - subroutine lammps_commands_list (ptr, cmds) - type (C_ptr), intent(in) :: ptr - character (len=*), dimension(:) :: cmds - integer (C_int) :: ncmd -! character (kind=C_char,len=1), dimension(size(cmds)) :: C_cmds - type (C_ptr), dimension(:), allocatable :: C_cmds - character (len=1, kind=C_char), allocatable, target :: C_strings(:,:) - integer :: i, max_len - ncmd = size(cmds) - allocate (C_cmds(ncmd)) - max_len = 0 - do i=1, size(cmds) - if ( len(cmds(i)) > max_len ) max_len = len(cmds(i)) - end do - allocate (C_strings(max_len + 1, ncmd)) - do i=1, size(cmds) - C_strings(:,i) = string2Cstring(cmds(i)) - C_cmds(i) = C_loc(C_strings(1,i)) - end do - call lammps_actual_commands_list (ptr, ncmd, C_cmds) - deallocate (C_strings) - deallocate (C_cmds) - end subroutine lammps_commands_list - -!----------------------------------------------------------------------------- - - subroutine lammps_commands_string (ptr, str) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: str - character (kind=C_char), dimension(len_trim(str)+1) :: C_str - C_str = string2Cstring (str) - call lammps_actual_commands_string (ptr, C_str) - end subroutine lammps_commands_string - -!----------------------------------------------------------------------------- - - function lammps_extract_setting (ptr, name) result (setting) - integer :: setting - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (kind=C_char), dimension(len_trim(name)+1) :: C_name - C_name = string2Cstring (name) - setting = lammps_actual_extract_setting (ptr, C_name) - end function lammps_extract_setting - -!----------------------------------------------------------------------------- - -! lammps_extract_global {{{2 - function lammps_extract_global_Cptr (ptr, name) result (global) - type (C_ptr) :: global - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - Cname = string2Cstring (name) - global = lammps_actual_extract_global (ptr, Cname) - end function lammps_extract_global_Cptr - subroutine lammps_extract_global_i (global, ptr, name) - integer (C_int), pointer, intent(out) :: global - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - Cptr = lammps_extract_global_Cptr (ptr, name) - call C_F_pointer (Cptr, global) - end subroutine lammps_extract_global_i - subroutine lammps_extract_global_dp (global, ptr, name) - real (C_double), pointer, intent(out) :: global - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - Cptr = lammps_extract_global_Cptr (ptr, name) - call C_F_pointer (Cptr, global) - end subroutine lammps_extract_global_dp - -!----------------------------------------------------------------------------- - -! lammps_extract_box {{{2 - subroutine lammps_extract_box (ptr, boxlo, boxhi, xy, yz, xz, & - periodicity, box_change) - type (C_ptr), intent(in) :: ptr - double precision, dimension(3), intent(out) :: boxlo, boxhi - double precision, intent(out) :: xy, yz, xz - logical, intent(out) :: periodicity(3), box_change - integer (kind=C_int) :: C_periodicity(3), C_box_change - real (C_double) :: C_boxlo(3), C_boxhi(3), C_xy, C_yz, C_xz - call lammps_actual_extract_box (ptr, C_boxlo, C_boxhi, C_xy, C_yz, & - C_xz, C_periodicity, C_box_change) - boxlo = C_boxlo - boxhi = C_boxhi - xy = C_xy - yz = C_yz - xz = C_xz - periodicity = (C_periodicity == 1) - box_change = (C_box_change == 1) - end subroutine - -!----------------------------------------------------------------------------- - -! lammps_extract_atom {{{2 - function lammps_extract_atom_Cptr (ptr, name) result (atom) - type (C_ptr) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - Cname = string2Cstring (name) - atom = lammps_actual_extract_atom (ptr, Cname) - end function lammps_extract_atom_Cptr - subroutine lammps_extract_atom_ia (atom, ptr, name) - integer (C_int), dimension(:), pointer, intent(out) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - integer (C_int), pointer :: nelements - call lammps_extract_global_i (nelements, ptr, 'nlocal') - Cptr = lammps_extract_atom_Cptr (ptr, name) - call C_F_pointer (Cptr, atom, (/nelements/)) - end subroutine lammps_extract_atom_ia - subroutine lammps_extract_atom_dpa (atom, ptr, name) - real (C_double), dimension(:), pointer, intent(out) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - integer (C_int), pointer :: nlocal - integer :: nelements - real (C_double), dimension(:), pointer :: Fptr - if ( name == 'mass' ) then - nelements = lammps_get_ntypes (ptr) + 1 - else if ( name == 'x' .or. name == 'v' .or. name == 'f' .or. & - name == 'mu' .or. name == 'omega' .or. name == 'torque' .or. & - name == 'angmom' ) then - ! We should not be getting a rank-2 array here! - call lammps_error_all (ptr, FLERR, 'You cannot extract those atom& - & data (' // trim(name) // ') into a rank 1 array.') - return - else - ! Everything else we can get is probably nlocal units long - call lammps_extract_global_i (nlocal, ptr, 'nlocal') - nelements = nlocal - end if - Cptr = lammps_extract_atom_Cptr (ptr, name) - call C_F_pointer (Cptr, Fptr, (/nelements/)) - if ( name == 'mass' ) then - atom(0:) => Fptr - else - atom => Fptr - end if - end subroutine lammps_extract_atom_dpa - subroutine lammps_extract_atom_dp2a (atom, ptr, name) - real (C_double), dimension(:,:), pointer, intent(out) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - type (C_ptr), pointer, dimension(:) :: Catom - integer (C_int), pointer :: nelements - if ( name /= 'x' .and. name /= 'v' .and. name /= 'f' .and. & - name /= 'mu' .and. name /= 'omega' .and. name /= 'tandque' .and. & - name /= 'angmom' ) then - ! We should not be getting a rank-2 array here! - call lammps_error_all (ptr, FLERR, 'You cannot extract those atom& - & data (' // trim(name) // ') into a rank 2 array.') - return - end if - Cptr = lammps_extract_atom_Cptr (ptr, name) - call lammps_extract_global_i (nelements, ptr, 'nlocal') - ! Catom will now be the array of void* pointers that the void** pointer - ! pointed to. Catom(1) is now the pointer to the first element. - call C_F_pointer (Cptr, Catom, (/nelements/)) - ! Now get the actual array, which has its shape transposed from what we - ! might think of it in C - call C_F_pointer (Catom(1), atom, (/3, nelements/)) - end subroutine lammps_extract_atom_dp2a - -!----------------------------------------------------------------------------- - -! lammps_extract_compute {{{2 - function lammps_extract_compute_Cptr (ptr, id, style, type) result (compute) - type (C_ptr) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - integer (kind=C_int) :: Cstyle, Ctype - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = style - Ctype = type - compute = lammps_actual_extract_compute (ptr, Cid, Cstyle, Ctype) - end function lammps_extract_compute_Cptr - subroutine lammps_extract_compute_dp (compute, ptr, id, style, type) - real (C_double), pointer, intent(out) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - type (C_ptr) :: Cptr - ! The only valid values of (style,type) are (0,0) for scalar 'compute' - if ( style /= 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot pack per-atom/local& - & data into a scalar.') - return - end if - if ( type == 1 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & vector (rank 1) into a scalar.') - return - else if ( type == 2 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & array (rank 2) into a scalar.') - return - end if - Cptr = lammps_extract_compute_Cptr (ptr, id, style, type) - call C_F_pointer (Cptr, compute) - end subroutine lammps_extract_compute_dp - subroutine lammps_extract_compute_dpa (compute, ptr, id, style, type) - real (C_double), dimension(:), pointer, intent(out) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - type (C_ptr) :: Cptr - integer :: nelements - ! Check for the correct dimensionality - if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & scalar (rank 0) into a rank 1 variable.') - return - else if ( type == 2 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & array (rank 2) into a rank 1 variable.') - return - end if - nelements = lammps_extract_compute_vectorsize (ptr, id, style) - Cptr = lammps_extract_compute_Cptr (ptr, id, style, type) - call C_F_pointer (Cptr, compute, (/nelements/)) - end subroutine lammps_extract_compute_dpa - subroutine lammps_extract_compute_dp2a (compute, ptr, id, style, type) - real (C_double), dimension(:,:), pointer, intent(out) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - type (C_ptr) :: Cptr - type (C_ptr), pointer, dimension(:) :: Ccompute - integer :: nr, nc - ! Check for the correct dimensionality - if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & scalar (rank 0) into a rank 2 variable.') - return - else if ( type == 1 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & array (rank 1) into a rank 2 variable.') - return - end if - call lammps_extract_compute_arraysize (ptr, id, style, nr, nc) - Cptr = lammps_extract_compute_Cptr (ptr, id, style, type) - call C_F_pointer (Cptr, Ccompute, (/nr/)) - ! Note that the matrix is transposed, from Fortran's perspective - call C_F_pointer (Ccompute(1), compute, (/nc, nr/)) - end subroutine lammps_extract_compute_dp2a - -!----------------------------------------------------------------------------- - -! lammps_extract_fix {{{2 - function lammps_extract_fix_Cptr (ptr, id, style, type, i, j) & - result (fix) - type (C_ptr) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - integer (kind=C_int) :: Cstyle, Ctype, Ci, Cj - Cid = string2Cstring (id) - Cstyle = style - Ctype = type - Ci = i - 1 ! This is for consistency with the values from f_ID[i], - Cj = j - 1 ! which is different from what library.cpp uses! - if ( (type >= 1 .and. Ci < 0) .or. & - (type == 2 .and. (Ci < 0 .or. Cj < 0) ) ) then - call lammps_error_all (ptr, FLERR, 'Index out of range in& - & lammps_extract_fix') - end if - fix = lammps_actual_extract_fix (ptr, Cid, Cstyle, Ctype, Ci, Cj) - end function lammps_extract_fix_Cptr - subroutine lammps_extract_fix_dp (fix, ptr, id, style, type, i, j) - real (C_double), intent(out) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - type (C_ptr) :: Cptr - real (C_double), pointer :: Fptr - ! Check for the correct dimensionality - if ( style /= 0 ) then - select case (type) - case (0) - call lammps_error_all (ptr, FLERR, 'There is no per-atom or local& - & scalar data available from fixes.') - case (1) - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix''s & - &per-atom/local vector (rank 1) into a scalar.') - case (2) - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix''s & - &per-atom/local array (rank 2) into a scalar.') - case default - call lammps_error_all (ptr, FLERR, 'Invalid extract_fix style/& - &type combination.') - end select - return - end if - Cptr = lammps_extract_fix_Cptr (ptr, id, style, type, i, j) - call C_F_pointer (Cptr, Fptr) - fix = Fptr - nullify (Fptr) - ! Memory is only allocated for "global" fix variables - if ( style == 0 ) call lammps_free (Cptr) - end subroutine lammps_extract_fix_dp - subroutine lammps_extract_fix_dpa (fix, ptr, id, style, type, i, j) - real (C_double), dimension(:), pointer, intent(out) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - type (C_ptr) :: Cptr - integer :: fix_len - ! Check for the correct dimensionality - if ( style == 0 ) then - call lammps_error_all (ptr, FLERR, 'You can''t extract the& - & whole vector from global fix data') - return - else if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You can''t extract a fix& - & scalar into a rank 1 variable') - return - else if ( type == 2 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix& - & array into a rank 1 variable.') - return - else if ( type /= 1 ) then - call lammps_error_all (ptr, FLERR, 'Invalid type for fix extraction.') - return - end if - fix_len = lammps_extract_fix_vectorsize (ptr, id, style) - call C_F_pointer (Cptr, fix, (/fix_len/)) - ! Memory is only allocated for "global" fix variables, which we should - ! never get here, so no need to call lammps_free! - end subroutine lammps_extract_fix_dpa - subroutine lammps_extract_fix_dp2a (fix, ptr, id, style, type, i, j) - real (C_double), dimension(:,:), pointer, intent(out) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - type (C_ptr) :: Cptr - type (C_ptr), pointer, dimension(:) :: Cfix - integer :: nr, nc - ! Check for the correct dimensionality - if ( style == 0 ) then - call lammps_error_all (ptr, FLERR, 'It is not possible to extract the& - & entire array from global fix data.') - return - else if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix& - & scalar (rank 0) into a rank 2 variable.') - return - else if ( type == 1 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix& - & vector (rank 1) into a rank 2 variable.') - return - end if - call lammps_extract_fix_arraysize (ptr, id, style, nr, nc) - ! Extract pointer to first element as Cfix(1) - call C_F_pointer (Cptr, Cfix, (/nr/)) - ! Now extract the array, which is transposed - call C_F_pointer (Cfix(1), fix, (/nc, nr/)) - end subroutine lammps_extract_fix_dp2a - -!----------------------------------------------------------------------------- - -! lammps_extract_variable {{{2 - function lammps_extract_variable_Cptr (ptr, name, group) result (variable) - type (C_ptr) :: ptr, variable - character (len=*) :: name - character (len=*), optional :: group - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - character (kind=C_char), dimension(:), allocatable :: Cgroup - Cname = string2Cstring (name) - if ( present(group) ) then - allocate (Cgroup(len_trim(group)+1)) - Cgroup = string2Cstring (group) - else - allocate (Cgroup(1)) - Cgroup(1) = C_NULL_CHAR - end if - variable = lammps_actual_extract_variable (ptr, Cname, Cgroup) - deallocate (Cgroup) - end function lammps_extract_variable_Cptr - subroutine lammps_extract_variable_dp (variable, ptr, name, group) - real (C_double), intent(out) :: variable - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (len=*), intent(in), optional :: group - type (C_ptr) :: Cptr - real (C_double), pointer :: Fptr - if ( present(group) ) then - Cptr = lammps_extract_variable_Cptr (ptr, name, group) - else - Cptr = lammps_extract_variable_Cptr (ptr, name) - end if - call C_F_pointer (Cptr, Fptr) - variable = Fptr - nullify (Fptr) - call lammps_free (Cptr) - end subroutine lammps_extract_variable_dp - subroutine lammps_extract_variable_dpa (variable, ptr, name, group) - real (C_double), dimension(:), allocatable, intent(out) :: variable - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (len=*), intent(in), optional :: group - type (C_ptr) :: Cptr - real (C_double), dimension(:), pointer :: Fptr - integer :: natoms - if ( present(group) ) then - Cptr = lammps_extract_variable_Cptr (ptr, name, group) - else - Cptr = lammps_extract_variable_Cptr (ptr, name) - end if - natoms = lammps_get_natoms (ptr) - allocate (variable(natoms)) - call C_F_pointer (Cptr, Fptr, (/natoms/)) - variable = Fptr - nullify (Fptr) - call lammps_free (Cptr) - end subroutine lammps_extract_variable_dpa - -!-------------------------------------------------------------------------2}}} - - function lammps_get_thermo (ptr, name) result (dval) - double precision :: dval - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - Cname = string2Cstring (name) - dval = lammps_actual_get_thermo (ptr, Cname) - end function lammps_get_thermo - - subroutine lammps_set_variable (ptr, name, str, err) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name, str - integer, optional :: err - integer (C_int) :: Cerr - character (kind=C_char) :: Cname(len_trim(name)+1), Cstr(len_trim(str)+1) - Cname = string2Cstring (name) - Cstr = string2Cstring (str) - Cerr = lammps_actual_set_variable (ptr, Cname, Cstr) - if ( present(err) ) err = Cerr - end subroutine lammps_set_variable - - subroutine lammps_reset_box (ptr, boxlo, boxhi, xy, yz, xz) - type (C_ptr), intent(in) :: ptr - double precision, dimension(3), intent(in) :: boxlo, boxhi - double precision, intent(in) :: xy, yz, xz - real (C_double) :: C_boxlo(3), C_boxhi(3), C_xy, C_yz, C_xz - C_boxlo = boxlo - C_boxhi = boxhi - C_xy = xy - C_xz = xz - C_yz = yz - call lammps_actual_reset_box (ptr, C_boxlo, C_boxhi, C_xy, C_yz, C_xz) - end subroutine lammps_reset_box - -! lammps_gather_atoms {{{2 - subroutine lammps_gather_atoms_ia (ptr, name, count, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count - integer, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - integer (C_int), dimension(:), pointer :: Fdata - integer (C_int) :: natoms - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 0_C_int - integer (C_int) :: Ccount - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*natoms) ) - allocate ( data(count*natoms) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms (ptr, Cname, Ctype, Ccount, Cdata) - data = Fdata - deallocate (Fdata) - end subroutine lammps_gather_atoms_ia - subroutine lammps_gather_atoms_dpa (ptr, name, count, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count - double precision, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - real (C_double), dimension(:), pointer :: Fdata - integer (C_int) :: natoms - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 1_C_int - integer (C_int) :: Ccount - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*natoms) ) - allocate ( data(count*natoms) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms (ptr, Cname, Ctype, Ccount, Cdata) - data = Fdata(:) - deallocate (Fdata) - end subroutine lammps_gather_atoms_dpa - -! lammps_gather_atoms_concat {{{2 - subroutine lammps_gather_atoms_concat_ia (ptr, name, count, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count - integer, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - integer (C_int), dimension(:), pointer :: Fdata - integer (C_int) :: natoms - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 0_C_int - integer (C_int) :: Ccount - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*natoms) ) - allocate ( data(count*natoms) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms_concat (ptr, Cname, Ctype, Ccount, Cdata) - data = Fdata - deallocate (Fdata) - end subroutine lammps_gather_atoms_concat_ia - subroutine lammps_gather_atoms_concat_dpa (ptr, name, count, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count - double precision, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - real (C_double), dimension(:), pointer :: Fdata - integer (C_int) :: natoms - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 1_C_int - integer (C_int) :: Ccount - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms_concat& - & requires count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*natoms) ) - allocate ( data(count*natoms) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms_concat (ptr, Cname, Ctype, Ccount, Cdata) - data = Fdata(:) - deallocate (Fdata) - end subroutine lammps_gather_atoms_concat_dpa - -!----------------------------------------------------------------------------- - -! lammps_gather_atoms_subset {{{2 - subroutine lammps_gather_atoms_subset_ia (ptr,name,count,ids,data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count, ids(:) - integer, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - integer (C_int), dimension(:), pointer :: Fdata - integer (C_int) :: ndata, Cids(size(ids)) - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 0_C_int - integer (C_int) :: Ccount - ndata = size(ids) - Cname = string2Cstring (name) - Cids = ids - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms_subset& - & requires count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*ndata) ) - allocate ( data(count*ndata) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms_subset (ptr, Cname, Ctype, Ccount, & - ndata, Cids, Cdata) - data = Fdata - deallocate (Fdata) - end subroutine lammps_gather_atoms_subset_ia - subroutine lammps_gather_atoms_subset_dpa (ptr,name,count,ids,data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count, ids(:) - double precision, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - real (C_double), dimension(:), pointer :: Fdata - integer (C_int) :: ndata, Cids(size(ids)) - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 1_C_int - integer (C_int) :: Ccount - ndata = size(ids) - Cname = string2Cstring (name) - Cids = ids - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*ndata) ) - allocate ( data(count*ndata) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms_subset (ptr, Cname, Ctype, Ccount, & - ndata, Cids, Cdata) - data = Fdata - deallocate (Fdata) - end subroutine lammps_gather_atoms_subset_dpa - -!----------------------------------------------------------------------------- - -! lammps_scatter_atoms {{{2 - subroutine lammps_scatter_atoms_ia (ptr, name, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, dimension(:), intent(in) :: data - integer (kind=C_int) :: natoms, Ccount - integer (kind=C_int), parameter :: Ctype = 0_C_int - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), dimension(size(data)), target :: Fdata - type (C_ptr) :: Cdata - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - Ccount = size(data) / natoms - if ( Ccount /= 1 .and. Ccount /= 3 ) & - call lammps_error_all (ptr, FLERR, 'lammps_scatter_atoms requires& - & count to be either 1 or 3') - Fdata = data - Cdata = C_loc (Fdata(1)) - call lammps_actual_scatter_atoms (ptr, Cname, Ctype, Ccount, Cdata) - end subroutine lammps_scatter_atoms_ia - subroutine lammps_scatter_atoms_dpa (ptr, name, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - double precision, dimension(:), intent(in) :: data - integer (kind=C_int) :: natoms, Ccount - integer (kind=C_int), parameter :: Ctype = 1_C_int - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - real (C_double), dimension(size(data)), target :: Fdata - type (C_ptr) :: Cdata - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - Ccount = size(data) / natoms - if ( Ccount /= 1 .and. Ccount /= 3 ) & - call lammps_error_all (ptr, FLERR, 'lammps_scatter_atoms requires& - & count to be either 1 or 3') - Fdata = data - Cdata = C_loc (Fdata(1)) - call lammps_actual_scatter_atoms (ptr, Cname, Ctype, Ccount, Cdata) - end subroutine lammps_scatter_atoms_dpa - -!----------------------------------------------------------------------------- - -! lammps_scatter_atoms_subset {{{2 - subroutine lammps_scatter_atoms_subset_ia (ptr, name, ids, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, dimension(:), intent(in) :: data, ids - integer (kind=C_int) :: ndata, Ccount, Cids(size(ids)) - integer (kind=C_int), parameter :: Ctype = 0_C_int - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), dimension(size(data)), target :: Fdata - type (C_ptr) :: Cdata - ndata = size(ids) - Cname = string2Cstring (name) - Ccount = size(data) / ndata - if ( Ccount /= 1 .and. Ccount /= 3 ) & - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - Fdata = data - Cdata = C_loc (Fdata(1)) - Cids = ids - call lammps_actual_scatter_atoms_subset (ptr, Cname, Ctype, Ccount, & - ndata, Cids, Cdata) - end subroutine lammps_scatter_atoms_subset_ia - subroutine lammps_scatter_atoms_subset_dpa (ptr, name, ids, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - double precision, dimension(:), intent(in) :: data, ids - integer (kind=C_int) :: ndata, Ccount, Cids(size(ids)) - integer (kind=C_int), parameter :: Ctype = 1_C_int - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - real (C_double), dimension(size(data)), target :: Fdata - type (C_ptr) :: Cdata - ndata = size(ids) - Cname = string2Cstring (name) - Ccount = size(data) / ndata - if ( Ccount /= 1 .and. Ccount /= 3 ) & - call lammps_error_all (ptr, FLERR, 'lammps_scatter_atoms requires& - & count to be either 1 or 3') - Fdata = data - Cdata = C_loc (Fdata(1)) - call lammps_actual_scatter_atoms_subset (ptr, Cname, Ctype, Ccount, & - ndata, Cids, Cdata) - end subroutine lammps_scatter_atoms_subset_dpa - -!----------------------------------------------------------------------------- - - subroutine lammps_create_atoms (ptr, id, type, x, v, image, shrinkexceed) - type (C_ptr), intent(in) :: ptr - integer (kind=C_tagint), dimension(:), optional :: id - integer, dimension(:) :: type - double precision, dimension(:,:) :: x - double precision, dimension(:,:), optional :: v - integer (kind=C_imageint), dimension(:), target, optional :: image - logical, optional :: shrinkexceed - real (C_double), dimension(size(x)) :: C_x, C_v - integer (C_int) :: C_shrinkexceed, n - integer (kind=C_tagint) :: C_id - integer (C_imageint), dimension(size(x)/3) :: C_image - integer (C_int) :: C_type - if (shrinkexceed) then - C_shrinkexceed = 1_C_int - else - C_shrinkexceed = 0_C_int - end if - C_x = reshape(transpose(x), shape(C_x)) - if ( present(v) ) then - C_v = reshape(transpose(v), shape(C_v)) - else - C_v = 0.0_C_double - end if - if ( present(image) ) then - C_image = image - else - C_image = int(0,kind=C_imageint) - end if - n = size(type) - call lammps_actual_create_atoms (ptr, n, C_id, C_type, C_x, C_v, & - C_image, C_shrinkexceed) - end subroutine lammps_create_atoms - -!----------------------------------------------------------------------------- - - function lammps_config_has_package (package_name) result (has_it) - character (len=*), intent(in) :: package_name - character (len=1, kind=C_char), dimension(len_trim(package_name)+1) :: & - C_package_name - logical :: has_it - integer (C_int) :: C_has_it - C_package_name = string2Cstring (package_name) - C_has_it = lammps_actual_config_has_package (C_package_name) - has_it = (C_has_it == 1) - end function lammps_config_has_package - -!----------------------------------------------------------------------------- - - function lammps_config_package_name (index, buffer) result (installed) - character (len=*), intent(inout) :: buffer - integer, intent(in) :: index - logical :: installed - integer (kind=C_int) :: C_installed, C_index, max_size - character (len=1, kind=C_char), dimension(len_trim(buffer)+1) :: C_buffer - C_buffer = string2Cstring (buffer) - max_size = len(buffer) - C_index = index - C_installed = lammps_actual_config_package_name (C_index, C_buffer, & - max_size) - installed = (C_installed == 1_C_int) - buffer = Cstring2string (C_buffer) - end function lammps_config_package_name - -!----------------------------------------------------------------------------- - - logical function lammps_config_has_gzip_support () result (has_it) - integer (C_int) :: C_has_it - C_has_it = lammps_actual_config_has_gzip_support () - has_it = (C_has_it == 1_C_int) - end function lammps_config_has_gzip_support - -!----------------------------------------------------------------------------- - - logical function lammps_config_has_png_support () result (has_it) - integer (C_int) :: C_has_it - C_has_it = lammps_actual_config_has_png_support () - has_it = (C_has_it == 1_C_int) - end function lammps_config_has_png_support - -!----------------------------------------------------------------------------- - - logical function lammps_config_has_jpeg_support () result (has_it) - integer (C_int) :: C_has_it - C_has_it = lammps_actual_config_has_jpeg_support () - has_it = (C_has_it == 1_C_int) - end function lammps_config_has_jpeg_support - -!----------------------------------------------------------------------------- - - logical function lammps_config_has_ffmpeg_support () result (has_it) - integer (C_int) :: C_has_it - C_has_it = lammps_actual_config_has_ffmpeg_support () - has_it = (C_has_it == 1_C_int) - end function lammps_config_has_ffmpeg_support - -!----------------------------------------------------------------------------- - - logical function lammps_config_has_exceptions () result (has_it) - integer (C_int) :: C_has_it - C_has_it = lammps_actual_config_has_exceptions () - has_it = (C_has_it == 1_C_int) - end function lammps_config_has_exceptions - -!----------------------------------------------------------------------------- - - function lammps_find_pair_neighlist (ptr, style, exact, nsub, request) & - result (neighlist) - integer :: neighlist - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: style - logical, intent(in) :: exact - integer, intent(in) :: nsub, request - integer (C_int) :: C_exact, C_nsub, C_neighlist, C_request - character (kind=C_char), dimension(len_trim(style)+1) :: C_style - if (exact) then - C_exact = 1_C_int - else - C_exact = 0_C_int - end if - C_nsub = nsub - C_request = request - C_style = string2Cstring (style) - C_neighlist = lammps_actual_find_pair_neighlist (ptr, C_style, C_exact, & - C_nsub, C_request) - neighlist = C_neighlist - end function lammps_find_pair_neighlist - -!----------------------------------------------------------------------------- - - function lammps_find_fix_neighlist (ptr, id, request) result (neighlist) - integer :: neighlist - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: request - integer (C_int) :: C_request, C_neighlist - character (kind=C_char), dimension(len_trim(id)+1) :: C_id - C_id = string2Cstring(id) - C_request = request - C_neighlist = lammps_actual_find_fix_neighlist (ptr, C_id, C_request) - neighlist = C_neighlist - end function lammps_find_fix_neighlist - -!----------------------------------------------------------------------------- - - function lammps_find_compute_neighlist (ptr, id, request) result (neighlist) - integer :: neighlist - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: request - integer (C_int) :: C_request - character (kind=C_char), dimension(len_trim(id)+1) :: C_id - C_id = string2Cstring(id) - C_request = request - neighlist = lammps_actual_find_compute_neighlist (ptr, C_id, C_request) - end function lammps_find_compute_neighlist - -!----------------------------------------------------------------------------- - - function lammps_neighlist_num_elements (ptr, idx) result (nelements) - integer :: nelements - type (C_ptr), intent(in) :: ptr - integer, intent(in) :: idx - integer (C_int) :: C_idx - C_idx = idx - nelements = lammps_actual_neighlist_num_elements (ptr, C_idx) - end function lammps_neighlist_num_elements - -!----------------------------------------------------------------------------- - - subroutine lammps_neighlist_element_neighbors (ptr, idx, element, iatom, & - numneigh, neighbors) - type (C_ptr), intent(in) :: ptr - integer, intent(in) :: idx, element - integer, intent(out) :: iatom, numneigh - integer (C_int), dimension(:), pointer, intent(out) :: neighbors - integer (C_int) :: C_idx, C_element, C_iatom, C_numneigh - type (C_ptr) :: C_neighbors - C_idx = idx - C_element = element - call lammps_actual_neighlist_element_neighbors (ptr, C_idx, C_element, & - C_iatom, C_numneigh, C_neighbors) - iatom = C_iatom - numneigh = C_numneigh - call C_F_pointer (C_neighbors, neighbors, [numneigh]) - end subroutine lammps_neighlist_element_neighbors - -!----------------------------------------------------------------------------- - -! These are only defined if -DLAMMPS_EXCEPTIONS was issued -#ifdef LAMMPS_EXCEPTIONS - logical function lammps_has_error (ptr) result (has_it) - type (C_ptr), intent(in) :: ptr - integer (kind=C_int) :: C_has_it - C_has_it = lammps_actual_has_error (ptr) - has_it = (C_has_it == 1_C_int) - end function lammps_has_error - -!----------------------------------------------------------------------------- - - function lammps_get_last_error_message (ptr, buffer) result (error_type) - integer (C_int) :: error_type - type (C_ptr), intent(in) :: ptr - character (len=*), intent(out) :: buffer - integer (C_int) :: buffer_size - character (len=1, kind=C_char), dimension(len(buffer)+1) :: C_buffer - buffer_size = len(buffer) - error_type = lammps_actual_get_last_error_message (ptr, C_buffer, & - buffer_size) - buffer = Cstring2string (C_buffer) - end function lammps_get_last_error_message -#endif -!-------------------------------------------------------------------------2}}} - - function lammps_extract_compute_vectorsize (ptr, id, style) & - result (vectorsize) - integer :: vectorsize - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer (C_int) :: Cvectorsize, Cstyle - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int(style, C_int) - Cvectorsize = lammps_actual_extract_compute_vectorsize (ptr, Cid, Cstyle) - vectorsize = int(Cvectorsize, kind(vectorsize)) - end function lammps_extract_compute_vectorsize - -!----------------------------------------------------------------------------- - - function lammps_extract_fix_vectorsize (ptr, id, style) & - result (vectorsize) - integer :: vectorsize - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer (C_int) :: Cvectorsize, Cstyle - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int(style, C_int) - Cvectorsize = lammps_actual_extract_fix_vectorsize (ptr, Cid, Cstyle) - vectorsize = int(Cvectorsize, kind(vectorsize)) - end function lammps_extract_fix_vectorsize - -!----------------------------------------------------------------------------- - - subroutine lammps_extract_compute_arraysize (ptr, id, style, nrows, ncols) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer, intent(out) :: nrows, ncols - integer (C_int) :: Cstyle, Cnrows, Cncols - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int (style, C_int) - call lammps_actual_extract_compute_arraysize (ptr, Cid, Cstyle, & - Cnrows, Cncols) - nrows = int (Cnrows, kind(nrows)) - ncols = int (Cncols, kind(ncols)) - end subroutine lammps_extract_compute_arraysize - -!----------------------------------------------------------------------------- - - subroutine lammps_extract_fix_arraysize (ptr, id, style, nrows, ncols) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer, intent(out) :: nrows, ncols - integer (C_int) :: Cstyle, Cnrows, Cncols - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int (style, kind(Cstyle)) - call lammps_actual_extract_fix_arraysize (ptr, Cid, Cstyle, & - Cnrows, Cncols) - nrows = int (Cnrows, kind(nrows)) - ncols = int (Cncols, kind(ncols)) - end subroutine lammps_extract_fix_arraysize - -!----------------------------------------------------------------------------- - - subroutine lammps_error_all (ptr, file, line, str) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: file, str - integer, intent(in) :: line - character (kind=C_char), dimension(len_trim(file)+1) :: Cfile - character (kind=C_char), dimension(len_trim(str)+1) :: Cstr - integer (C_int) :: Cline - Cline = int(line, kind(Cline)) - Cfile = string2Cstring (file) - Cstr = string2Cstring (str) - call lammps_actual_error_all (ptr, Cfile, Cline, Cstr) - end subroutine lammps_error_all - -!----------------------------------------------------------------------------- - -! Locally defined helper functions {{{1 - - pure function string2Cstring (string) result (C_string) - use, intrinsic :: ISO_C_binding, only : C_char, C_NULL_CHAR - character (len=*), intent(in) :: string - character (len=1, kind=C_char) :: C_string (len_trim(string)+1) - integer :: i, n - n = len_trim (string) - forall (i = 1:n) - C_string(i) = string(i:i) - end forall - C_string(n+1) = C_NULL_CHAR - end function string2Cstring - -!----------------------------------------------------------------------------- - - pure function Cstrlen (Cstring) result (n) - character (len=1, kind=C_char), dimension(:), intent(in) :: Cstring - integer :: n, i - n = size(Cstring) - do i = 1, size(Cstring) - if ( Cstring(i) == C_NULL_CHAR ) then - n = i - 1 - return - end if - end do - end function Cstrlen - -!----------------------------------------------------------------------------- - - pure function Cstring2string (Cstring) result (string) - !use, intrinsic :: ISO_C_binding, only : C_char, C_NULL_CHAR - character (len=1, kind=C_char), intent(in) :: Cstring (:) - character (len=Cstrlen(Cstring)) :: string - integer :: i, n - n = Cstrlen(Cstring) - string = '' - forall (i = 1:n) - string(i:i) = Cstring(i) - end forall - end function Cstring2string - -!----------------------------------------------------------------------------- - - subroutine Cstring2argcargv (Cstring, argc, argv) - !! Converts a C-style string to argc and argv, that is, words in Cstring - !! become C-style strings in argv. IMPORTANT: Cstring is modified by - !! this routine! I would make Cstring local TO this routine and accept - !! a Fortran-style string instead, but we run into scoping and - !! allocation problems that way. This routine assumes the string is - !! null-terminated, as all C-style strings must be. - - character (kind=C_char), dimension(*), target, intent(inout) :: Cstring - integer (C_int), intent(out) :: argc - type (C_ptr), dimension(:), allocatable, intent(out) :: argv - - integer :: StringStart, SpaceIndex, strlen, argnum - - argc = 1_C_int - - ! Find the length of the string - strlen = 1 - do while ( Cstring(strlen) /= C_NULL_CHAR ) - strlen = strlen + 1 - end do - - ! Find the number of non-escaped spaces - SpaceIndex = 2 - do while ( SpaceIndex < strlen ) - if ( Cstring(SpaceIndex) == ' ' .and. & - Cstring(SpaceIndex-1) /= '\' ) then - argc = argc + 1_C_int - ! Find the next non-space character - do while ( Cstring(SpaceIndex+1) == ' ') - SpaceIndex = SpaceIndex + 1 - end do - end if - SpaceIndex = SpaceIndex + 1 - end do - - ! Now allocate memory for argv - allocate (argv(argc)) - - ! Now find the string starting and ending locations - StringStart = 1 - SpaceIndex = 2 - argnum = 1 - do while ( SpaceIndex < strlen ) - if ( Cstring(SpaceIndex) == ' ' .and. & - Cstring(SpaceIndex-1) /= '\' ) then - ! Found a real space => split strings and store this one - Cstring(Spaceindex) = C_NULL_CHAR ! Replaces space with NULL - argv(argnum) = C_loc(Cstring(StringStart)) - argnum = argnum + 1 - ! Find the next non-space character - do while ( Cstring(SpaceIndex+1) == ' ') - SpaceIndex = SpaceIndex + 1 - end do - StringStart = SpaceIndex + 1 - else if ( Cstring(SpaceIndex) == ' ' .and. & - Cstring(SpaceIndex-1) == '\' ) then - ! Escaped space => remove backslash and move rest of array - Cstring(SpaceIndex-1:strlen-1) = Cstring(SpaceIndex:strlen) - strlen = strlen - 1 ! Last character is still C_NULL_CHAR - end if - SpaceIndex = SpaceIndex + 1 - end do - ! Now handle the last argument - argv(argnum) = C_loc(Cstring(StringStart)) - - end subroutine Cstring2argcargv - -! 1}}} - -end module LAMMPS - -! vim: foldmethod=marker tabstop=3 softtabstop=3 shiftwidth=3 expandtab diff --git a/examples/COUPLE/fortran2/Makefile b/examples/COUPLE/fortran2/Makefile deleted file mode 100644 index 8ac957a4c1..0000000000 --- a/examples/COUPLE/fortran2/Makefile +++ /dev/null @@ -1,41 +0,0 @@ -SHELL = /bin/sh - -# Path to LAMMPS extraction directory -LAMMPS_ROOT = ../../.. -LAMMPS_SRC = $(LAMMPS_ROOT)/src - -# Uncomment the line below if using the MPI stubs library -MPI_STUBS = #-I$(LAMMPS_SRC)/STUBS - -FC = mpifort # replace with your Fortran compiler -CXX = mpicxx # replace with your C++ compiler -CXXLIB = -lstdc++ # replace with your C++ runtime libs - -# Flags for Fortran compiler, C++ compiler, and C preprocessor, respectively -FFLAGS = -O2 -fPIC -CXXFLAGS = -O2 -fPIC -CPPFLAGS = -DOMPI_SKIP_MPICXX=1 -DMPICH_SKIP_MPICXX - -all : liblammps_fortran.a liblammps_fortran.so - @echo "WARNING: this Fortran interface is obsolete and is no longer -maintained. See $(LAMMPS_ROOT)/fortran for the new, maintained interface -(largely written by the same author). You may continue to use this interface if -desired, but it may eventually be removed from LAMMPS." - -liblammps_fortran.so : LAMMPS.o LAMMPS-wrapper.o - $(FC) $(FFLAGS) -shared -o $@ $^ $(CXXLIB) - -liblammps_fortran.a : LAMMPS.o LAMMPS-wrapper.o - $(AR) rs $@ $^ - -LAMMPS.o lammps.mod : LAMMPS.F90 - $(FC) $(CPPFLAGS) $(FFLAGS) -c $< - -LAMMPS-wrapper.o : LAMMPS-wrapper.cpp LAMMPS-wrapper.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -I$(LAMMPS_SRC) $(MPI_STUBS) - -clean : - $(RM) *.o *.mod liblammps_fortran.a liblammps_fortran.so - -dist : - tar -czf Fortran-interface.tar.gz LAMMPS-wrapper.h LAMMPS-wrapper.cpp LAMMPS.F90 makefile README diff --git a/examples/COUPLE/fortran2/README b/examples/COUPLE/fortran2/README deleted file mode 100644 index b36cb43746..0000000000 --- a/examples/COUPLE/fortran2/README +++ /dev/null @@ -1,273 +0,0 @@ -!! NOTE ------------------------------------------------------------------- -! This interface is obsolete and may be removed in a future release of -! LAMMPS. The interface in fortran/lammps.f90 replaces this one. That API -! is maintained by the LAMMPS developers and has documentation written for -! it; it is based loosely on this one, but binds all procedures to a lammps -! derived type. That interface was written in large -! part by the same author, but is also supported by other developers. -!-------------------------------------------------------------------------- - -LAMMPS.F90 defines a Fortran 2003 module, LAMMPS, which wraps all functions in -src/library.h so they can be used directly from Fortran-encoded programs. - -All functions in src/library.h that use and/or return C-style pointers have -Fortran wrapper functions that use Fortran-style arrays, pointers, and -strings; all C-style memory management is handled internally with no user -intervention. See --USE-- for notes on how this interface differs from the -C interface (and the Python interface). - -This interface was created by Karl Hammond who you can contact with -questions: - -Karl D. Hammond -University of Missouri -hammondkd at missouri.edu - -------------------------------------- - ---COMPILATION-- - -First, be advised that mixed-language programming is not trivial. It requires -you to link in the required libraries of all languages you use (in this case, -those for Fortran, C, and C++), as well as any other libraries required. -You are also advised to read the --USE-- section below before trying to -compile. - -The following steps will work to compile this module (replace ${LAMMPS_SRC} -with the path to your LAMMPS source directory). - -Steps 3-5 are accomplished, possibly after some modifications to -the makefile, by make using the attached makefile. Said makefile also builds -the dynamically-linkable library (liblammps_fortran.so). - -** STATIC LIBRARY INSTRUCTIONS ** - (1) Compile LAMMPS as a static library. - Call the resulting file ${LAMMPS_LIB}, which will have an actual name - like liblmp_openmpi.a. If compiling using the MPI stubs in - ${LAMMPS_SRC}/STUBS, you will need to know where libmpi_stubs.a - is as well (I'll call it ${MPI_STUBS} hereafter) - (2) Copy said library to your Fortran program's source directory or replace - ${LAMMPS_LIB} with its full path in the instructions below. - (3) Compile (but don't link!) LAMMPS.F90. Example: - mpifort -c LAMMPS.f90 - OR - gfortran -c LAMMPS.F90 - NOTE: you may get a warning such as, - subroutine lammps_open_wrapper (argc, argv, communicator, ptr) & - Variable 'communicator' at (1) is a parameter to the BIND(C) - procedure 'lammps_open_wrapper' but may not be C interoperable - This is normal (see --IMPLEMENTATION NOTES--). - - (4) Compile (but don't link) LAMMPS-wrapper.cpp. You will need its header - file as well. You will have to provide the locations of LAMMPS's - header files. For example, - mpicxx -c -I${LAMMPS_SRC} LAMMPS-wrapper.cpp - OR - g++ -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp - OR - icpc -c -I${LAMMPS_SRC} -I${LAMMPS_SRC}/STUBS LAMMPS-wrapper.cpp - (5) OPTIONAL: Make a library from the object files so you can carry around - two files instead of three. Example: - ar rs liblammps_fortran.a LAMMPS.o LAMMPS-wrapper.o - This will create the file liblammps_fortran.a that you can use in place - of "LAMMPS.o LAMMPS-wrapper.o" later. Note that you will still - need to have the .mod file from part (3). - - It is also possible to add LAMMPS.o and LAMMPS-wrapper.o into the - LAMMPS library (e.g., liblmp_openmpi.a) instead of creating a separate - library, like so: - ar rs ${LAMMPS_LIB} LAMMPS.o LAMMPS-wrapper.o - In this case, you can now use the Fortran wrapper functions as if they - were part of the usual LAMMPS library interface (if you have the module - file visible to the compiler, that is). - (6) Compile (but don't link) your Fortran program. Example: - mpifort -c myfreeformatfile.f90 - mpifort -c myfixedformatfile.f - OR - gfortran -c myfreeformatfile.f90 - gfortran -c myfixedformatfile.f - The object files generated by these steps are collectively referred to - as ${my_object_files} in the next step(s). - - IMPORTANT: If the Fortran module from part (3) is not in the current - directory or in one searched by the compiler for module files, you will - need to include that location via the -I flag to the compiler, like so: - mpifort -I${LAMMPS_SRC}/examples/COUPLE/fortran2 -c myfreeformatfile.f90 - - (7) Link everything together, including any libraries needed by LAMMPS (such - as the C++ standard library, the C math library, the JPEG library, fftw, - etc.) For example, - mpifort LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \ - ${LAMMPS_LIB} -lmpi_cxx -lstdc++ -lm - OR - gfortran LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \ - ${LAMMPS_LIB} ${MPI_STUBS} -lstdc++ -lm - OR - ifort LAMMPS.o LAMMPS-wrapper.o ${my_object_files} \ - ${LAMMPS_LIB} ${MPI_STUBS} -cxxlib -lm - Any other required libraries (e.g. -ljpeg, -lfftw) should be added to - the end of this line. - -You should now have a working executable. - -** DYNAMIC LIBRARY INSTRUCTIONS ** - (1) Compile LAMMPS as a dynamic library - (make makeshlib && make -f Makefile.shlib [targetname]). - (2) Compile, but don't link, LAMMPS.F90 using the -fPIC flag, such as - mpifort -fPIC -c LAMMPS.f90 - (3) Compile, but don't link, LAMMPS-wrapper.cpp in the same manner, e.g. - mpicxx -fPIC -c LAMMPS-wrapper.cpp - (4) Make the dynamic library, like so: - mpifort -fPIC -shared -o liblammps_fortran.so LAMMPS.o LAMMPS-wrapper.o - (5) Compile your program, such as, - mpifort -I${LAMMPS_SRC}/examples/COUPLE/fortran2 -c myfreeformatfile.f90 - where ${LAMMPS_SRC}/examples/COUPLE/fortran2 contains the .mod file from - step (3) - (6) Link everything together, such as - mpifort ${my_object_files} -L${LAMMPS_SRC} \ - -L${LAMMPS_SRC}/examples/COUPLE/fortran2 -llammps_fortran \ - -llammps_openmpi -lmpi_cxx -lstdc++ -lm - -If you wish to avoid the -L flags, add the directories containing your -shared libraries to the LIBRARY_PATH environment variable. At run time, you -will have to add these directories to LD_LIBRARY_PATH as well; otherwise, -your executable will not find the libraries it needs. - -------------------------------------- - ---USAGE-- - -To use this API, your program unit (PROGRAM/SUBROUTINE/FUNCTION/MODULE/etc.) -should look something like this: - program call_lammps - use LAMMPS - ! Other modules, etc. - implicit none - type (lammps_instance) :: lmp ! This is a pointer to your LAMMPS instance - real (C_double) :: fix - real (C_double), dimension(:), pointer :: fix2 - ! Rest of declarations - call lammps_open_no_mpi ('lmp -in /dev/null -screen out.lammps',lmp) - ! Set up rest of program here - call lammps_file (lmp, 'in.example') - call lammps_extract_fix (fix, lmp, '2', 0, 1, 1, 1) - call lammps_extract_fix (fix2, lmp, '4', 0, 2, 1, 1) - call lammps_close (lmp) - end program call_lammps - -Important notes: - * Though I dislike the use of pointers, they are necessary when communicating - with C and C++, which do not support Fortran's ALLOCATABLE attribute. - * There is no need to deallocate C-allocated memory; this is done for you in - the cases when it is done (which are all cases when pointers are not - accepted, such as global fix data) - * All arguments which are char* variables in library.cpp are character (len=*) - variables here. For example, - call lammps_command (lmp, 'units metal') - will work as expected. - * The public functions (the only ones you can use) have interfaces as - described in the comments at the top of LAMMPS.F90. They are not always - the same as those in library.h, since C strings are replaced by Fortran - strings and the like. - * The module attempts to check whether you have done something stupid (such - as assign a 2D array to a scalar), but it's not perfect. For example, the - command - call lammps_extract_global (nlocal, ptr, 'nlocal') - will give nlocal correctly if nlocal is a pointer to type INTEGER, but it - will give the wrong answer if nlocal is a pointer to type REAL. This is a - feature of the (void*) type cast in library.cpp. There is no way I can - check this for you! It WILL catch you if you pass it an allocatable or - fixed-size array when it expects a pointer. - * Arrays constructed from temporary data from LAMMPS are ALLOCATABLE, and - represent COPIES of data, not the originals. Functions like - lammps_extract_atom, which return actual LAMMPS data, are pointers. - * IMPORTANT: Due to the differences between C and Fortran arrays (C uses - row-major vectors, Fortran uses column-major vectors), all arrays returned - from LAMMPS have their indices swapped. - * An example of a complete program, simple.f90, is included with this - package. - -------------------------------------- - ---TROUBLESHOOTING-- - -Compile-time errors (when compiling LAMMPS.F90, that is) probably indicate -that your compiler is not new enough to support Fortran 2003 features. For -example, GCC 4.1.2 will not compile this module, but GCC 4.4.0 will. - -If your compiler balks at 'use, intrinsic :: ISO_C_binding,' try removing the -intrinsic part so it looks like an ordinary module. However, it is likely -that such a compiler will also have problems with everything else in the -file as well. - -If you get a segfault as soon as the lammps_open call is made, check that you -compiled your program AND LAMMPS-wrapper.cpp using the same MPI headers. Using -the stubs for one and the actual MPI library for the other will cause Bad -Things to happen. - -If you find run-time errors, please pass them along via the LAMMPS Users -mailing list (please CC me as well; address above). Please provide a minimal -working example along with the names and versions of the compilers you are -using. Please make sure the error is repeatable and is in MY code, not yours -(generating a minimal working example will usually ensure this anyway). - -------------------------------------- - ---IMPLEMENTATION NOTES-- - -The Fortran procedures have the same names as the C procedures, and -their purpose is the same, but they may take different arguments. Here are -some of the important differences: - * lammps_open and lammps_open_no_mpi take a string instead of argc and - argv. This is necessary because C and C++ have a very different way - of treating strings than Fortran. If you want the command line to be - passed to lammps_open (as it often would be from C/C++), use the - GET_COMMAND intrinsic to obtain it. - * All C++ functions that accept char* pointers now accept Fortran-style - strings within this interface instead. - * All of the lammps_extract_[something] functions, which return void* - C-style pointers, have been replaced by generic subroutines that return - Fortran variables (which may be arrays). The first argument houses the - variable/pointer to be returned (pretend it's on the left-hand side); all - other arguments are identical except as stipulated above. - Note that it is not possible to declare generic functions that are selected - based solely on the type/kind/rank (TKR) signature of the return value, - only based on the TKR of the arguments. - * The SHAPE of the first argument to lammps_extract_[something] is checked - against the "shape" of the C array (e.g., double vs. double* vs. double**). - Calling a subroutine with arguments of inappropriate rank will result in an - error at run time. - * The indices i and j in lammps_extract_fix are used the same way they - are in f_ID[i][j] references in LAMMPS (i.e., starting from 1). This is - different than the way library.cpp uses these numbers, but is more - consistent with the way arrays are accessed in LAMMPS and in Fortran. - * The char* pointer normally returned by lammps_command is thrown away - in this version; note also that lammps_command is now a subroutine - instead of a function. - * The pointer to LAMMPS itself is of type(lammps_instance), which is itself - a synonym for type(C_ptr), part of ISO_C_BINDING. Type (C_ptr) is - C's void* data type. - * This module will almost certainly generate a compile-time warning, - such as, - subroutine lammps_open_wrapper (argc, argv, communicator, ptr) & - Variable 'communicator' at (1) is a parameter to the BIND(C) - procedure 'lammps_open_wrapper' but may not be C interoperable - This happens because lammps_open_wrapper actually takes a Fortran - INTEGER argument, whose type is defined by the MPI library itself. The - Fortran integer is converted to a C integer by the MPI library (if such - conversion is actually necessary). - * lammps_extract_global returns COPIES of the (scalar) data, as does the - C version. - * lammps_extract_atom, lammps_extract_compute, and lammps_extract_fix - have a first argument that will be associated with ACTUAL LAMMPS DATA. - This means the first argument must be: - * The right rank (via the DIMENSION modifier) - * A C-interoperable POINTER type (i.e., INTEGER (C_int) or - REAL (C_double)). - * lammps_extract_variable returns COPIES of the data, as the C library - interface does. There is no need to deallocate using lammps_free. - * The 'data' argument to lammps_gather_atoms and lammps_scatter atoms must - be ALLOCATABLE. It should be of type INTEGER or DOUBLE PRECISION. It - does NOT need to be C inter-operable (and indeed should not be). - * The 'count' argument of lammps_scatter_atoms is unnecessary; the shape of - the array determines the number of elements LAMMPS will read. diff --git a/examples/COUPLE/fortran2/in.simple b/examples/COUPLE/fortran2/in.simple deleted file mode 100644 index 5982cbaac1..0000000000 --- a/examples/COUPLE/fortran2/in.simple +++ /dev/null @@ -1,16 +0,0 @@ -units lj -atom_modify map array -lattice bcc 1.0 -region simbox block 0 10 0 10 0 10 -create_box 2 simbox -create_atoms 1 region simbox -pair_style lj/cut 2.5 -pair_coeff * * 1.0 1.0 -mass 1 58.2 # These are made-up numbers -mass 2 28.3 -velocity all create 1200.0 7474848 dist gaussian -fix 1 all nve -fix 2 all dt/reset 1 1E-5 1E-3 0.01 units box -fix 4 all ave/histo 10 5 100 0.5 1.5 50 f_2 file temp.histo ave running -thermo_style custom step dt temp press etotal f_4[1][1] -thermo 100 diff --git a/examples/COUPLE/fortran2/simple.f90 b/examples/COUPLE/fortran2/simple.f90 deleted file mode 100644 index 0b84a1ecc1..0000000000 --- a/examples/COUPLE/fortran2/simple.f90 +++ /dev/null @@ -1,112 +0,0 @@ -program simple - - use MPI - use LAMMPS - - ! The following line is unnecessary, as I have included these three entities - ! with the LAMMPS module, but I leave them in anyway to remind people where - ! they came from - use, intrinsic :: ISO_C_binding, only : C_double, C_ptr, C_int - - implicit none - - ! Notes: - ! * If LAMMPS returns a scalar that is allocated by the library interface - ! (see library.cpp), then that memory is deallocated automatically and - ! the argument to lammps_extract_fix must be a SCALAR. - ! * If LAMMPS returns a pointer to an array, consisting of internal LAMMPS - ! data, then the argument must be an interoperable Fortran pointer. - ! Interoperable means it is of type INTEGER (C_INT) or of type - ! REAL (C_DOUBLE) in this context. - ! * Pointers should NEVER be deallocated, as that would deallocate internal - ! LAMMPS data! - ! * Note that just because you can read the values of, say, a compute at - ! any time does not mean those values represent the "correct" values. - ! LAMMPS will abort you if you try to grab a pointer to a non-current - ! entity, but once it's bound, it's your responsibility to check that - ! it's current before evaluating. - ! * IMPORTANT: Two-dimensional arrays (such as 'x' from extract_atom) - ! will be transposed from what they might look like in C++. This is - ! because of different bookkeeping conventions between Fortran and C - ! that date back to about 1970 or so (when C was written). - ! * Arrays start from 1, EXCEPT for mass from extract_atom, which - ! starts from 0. This is because the C array actually has a blank - ! first element (and thus mass[1] corresponds to the mass of type 1) - - type (C_ptr) :: lmp - real (C_double), pointer :: compute => NULL() - real (C_double) :: fix, fix2 - real (C_double), dimension(:), pointer :: compute_v => NULL() - real (C_double), dimension(:,:), pointer :: x => NULL() - real (C_double), dimension(:), pointer :: mass => NULL() - integer, dimension(:), allocatable :: types - double precision, dimension(:), allocatable :: r - integer :: error, narg, me, nprocs - character (len=1024) :: command_line - - call MPI_Init (error) - call MPI_Comm_rank (MPI_COMM_WORLD, me, error) - call MPI_Comm_size (MPI_COMM_WORLD, nprocs, error) - - ! You are free to pass any string you like to lammps_open or - ! lammps_open_no_mpi; here is how you pass it the command line - !call get_command (command_line) - !call lammps_open (command_line, MPI_COMM_WORLD, lmp) - - ! And here's how to to it with a string constant of your choice - call lammps_open_no_mpi ('lmp -log log.simple', lmp) - - call lammps_file (lmp, 'in.simple') - call lammps_command (lmp, 'run 500') - - ! This extracts f_2 as a scalar (the last two arguments can be arbitrary) - call lammps_extract_fix (fix, lmp, '2', LMP_STYLE_GLOBAL, LMP_TYPE_SCALAR, 1, 1) - print *, 'Fix is ', fix - - ! This extracts f_4[1][1] as a scalar - call lammps_extract_fix (fix2, lmp, '4', LMP_STYLE_GLOBAL, LMP_TYPE_ARRAY, 1, 1) - print *, 'Fix 2 is ', fix2 - - ! This extracts the scalar compute of compute thermo_temp - call lammps_extract_compute (compute, lmp, 'thermo_temp', LMP_STYLE_GLOBAL, LMP_TYPE_SCALAR) - print *, 'Compute is ', compute - - ! This extracts the vector compute of compute thermo_temp - call lammps_extract_compute (compute_v, lmp, 'thermo_temp', LMP_STYLE_GLOBAL, LMP_TYPE_VECTOR) - print *, 'Vector is ', compute_v - - ! This extracts the masses - call lammps_extract_atom (mass, lmp, 'mass') - print *, 'Mass is ', mass(1:) - - ! Extracts a pointer to the arrays of positions for all atoms - call lammps_extract_atom (x, lmp, 'x') - if ( .not. associated (x) ) print *, 'x is not associated' - print *, 'x is ', x(:,1) ! Prints x, y, z for atom 1 - - ! Extracts pointer to atom types - call lammps_gather_atoms (lmp, 'type', 1, types) - print *, 'types is ', types(1:3) - - ! Allocates an array and assigns all positions to it - call lammps_gather_atoms (lmp, 'x', 3, r) - print *, 'natoms = ', int(lammps_get_natoms(lmp)) - print *, 'size(r) = ', size(r) - print *, 'r is ', r(1:6) - - ! Puts those position data back - call lammps_scatter_atoms (lmp, 'x', r) - - call lammps_command (lmp, 'run 1') - print *, 'x is ', x(:,1) ! Note that the position updates! - print *, 'Compute is ', compute ! This did only because "temp" is part of - ! the thermo output; the vector part did - ! not, and won't until we give LAMMPS a - ! thermo output or other command that - ! requires its value - - call lammps_close (lmp) - - call MPI_Finalize (error) - -end program simple diff --git a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper.cpp b/examples/COUPLE/fortran_dftb/LAMMPS-wrapper.cpp deleted file mode 100644 index 4774cb6b49..0000000000 --- a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper.cpp +++ /dev/null @@ -1,96 +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: Karl D. Hammond - University of Missouri (USA), 2012 -------------------------------------------------------------------------- */ - -/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself - provides a (I hope) robust Fortran interface to library.cpp and - library.h. All functions herein COULD be added to library.cpp instead of - including this as a separate file. See the README for instructions. */ - -#include -#include "LAMMPS-wrapper.h" -#define LAMMPS_LIB_MPI 1 -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace LAMMPS_NS; - -void lammps_open_fortran_wrapper (int argc, char **argv, - MPI_Fint communicator, void **ptr) -{ - MPI_Comm C_communicator = MPI_Comm_f2c (communicator); - lammps_open (argc, argv, C_communicator, ptr); -} - -int lammps_get_ntypes (void *ptr) -{ - class LAMMPS *lmp = (class LAMMPS *) ptr; - int ntypes = lmp->atom->ntypes; - return ntypes; -} - -void lammps_error_all (void *ptr, const char *file, int line, const char *str) -{ - class LAMMPS *lmp = (class LAMMPS *) ptr; - lmp->error->all (file, line, str); -} - -int lammps_extract_compute_vectorsize (void *ptr, char *id, int style) -{ - int *size; - size = (int *) lammps_extract_compute(ptr, id, style, LMP_SIZE_VECTOR); - if (size) return *size; - return 0; -} - -void lammps_extract_compute_arraysize (void *ptr, char *id, int style, - int *nrows, int *ncols) -{ - int *tmp; - tmp = (int *) lammps_extract_compute(ptr, id, style, LMP_SIZE_ROWS); - if (tmp) *nrows = *tmp; - tmp = (int *) lammps_extract_compute(ptr, id, style, LMP_SIZE_COLS); - if (tmp) *ncols = *tmp; - return; -} - -int lammps_extract_fix_vectorsize (void *ptr, char *id, int style) -{ - int *size; - size = (int *) lammps_extract_fix(ptr, id, style, LMP_SIZE_VECTOR, 0, 0); - if (size) return *size; - return 0; -} - -void lammps_extract_fix_arraysize (void *ptr, char *id, int style, - int *nrows, int *ncols) -{ - int *tmp; - tmp = (int *) lammps_extract_fix(ptr, id, style, LMP_SIZE_ROWS, 0, 0); - if (tmp) *nrows = *tmp; - tmp = (int *) lammps_extract_fix(ptr, id, style, LMP_SIZE_COLS, 0, 0); - if (tmp) *ncols = *tmp; - return; -} - -/* vim: set ts=3 sts=3 expandtab: */ diff --git a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper.h b/examples/COUPLE/fortran_dftb/LAMMPS-wrapper.h deleted file mode 100644 index e1eec9fc72..0000000000 --- a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper.h +++ /dev/null @@ -1,40 +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: Karl D. Hammond - University of Missouri (USA), 2012 -------------------------------------------------------------------------- */ - -/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself - provides a (I hope) robust Fortran interface to library.cpp and - library.h. All prototypes herein COULD be added to library.h instead of - including this as a separate file. See the README for instructions. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Prototypes for auxiliary functions */ -void lammps_open_fortran_wrapper (int, char**, MPI_Fint, void**); -int lammps_get_ntypes (void*); -int lammps_extract_compute_vectorsize (void*, char*, int); -void lammps_extract_compute_arraysize (void*, char*, int, int*, int*); -int lammps_extract_fix_vectorsize (void*, char*, int); -void lammps_extract_fix_arraysize (void*, char*, int, int*, int*); -void lammps_error_all (void*, const char*, int, const char*); - -#ifdef __cplusplus -} -#endif - -/* vim: set ts=3 sts=3 expandtab: */ diff --git a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.cpp b/examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.cpp deleted file mode 100644 index 83d594df60..0000000000 --- a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.cpp +++ /dev/null @@ -1,80 +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: Nir Goldman, LLNL , 2016 -------------------------------------------------------------------------- */ - -/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself - provides a (I hope) robust Fortran interface to library.cpp and - library.h. All functions herein COULD be added to library.cpp instead of - including this as a separate file. See the README for instructions. */ - -#include -#include "LAMMPS-wrapper2.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace LAMMPS_NS; - -extern "C" void f_callback(void *, bigint, int, tagint *, double **, double **); - -void lammps_set_callback (void *ptr) { - class LAMMPS *lmp = (class LAMMPS *) ptr; - int ifix = lmp->modify->find_fix_by_style("external"); - FixExternal *fix = (FixExternal *) lmp->modify->fix[ifix]; - fix->set_callback(f_callback, ptr); - return; -} - -void lammps_set_external_vector_length (void *ptr, int n) { - class LAMMPS *lmp = (class LAMMPS *) ptr; - int ifix = lmp->modify->find_fix_by_style("external"); - FixExternal *fix = (FixExternal *) lmp->modify->fix[ifix]; - fix->set_vector_length(n); - return; -} - -void lammps_set_external_vector (void *ptr, int n, double val) { - class LAMMPS *lmp = (class LAMMPS *) ptr; - int ifix = lmp->modify->find_fix_by_style("external"); - FixExternal *fix = (FixExternal *) lmp->modify->fix[ifix]; - fix->set_vector (n, val); - return; -} - -void lammps_set_user_energy (void *ptr, double energy) { - class LAMMPS *lmp = (class LAMMPS *) ptr; - int ifix = lmp->modify->find_fix_by_style("external"); - FixExternal *fix = (FixExternal *) lmp->modify->fix[ifix]; - fix->set_energy_global(energy); - return; -} - -void lammps_set_user_virial (void *ptr, double *virial) { - class LAMMPS *lmp = (class LAMMPS *) ptr; - int ifix = lmp->modify->find_fix_by_style("external"); - FixExternal *fix = (FixExternal *) lmp->modify->fix[ifix]; - fix->set_virial_global(virial); - return; -} - diff --git a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.h b/examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.h deleted file mode 100644 index 45c41b569a..0000000000 --- a/examples/COUPLE/fortran_dftb/LAMMPS-wrapper2.h +++ /dev/null @@ -1,37 +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: Nir Goldman, LLNL , 2016 -------------------------------------------------------------------------- */ - -/* This is set of "wrapper" functions to assist LAMMPS.F90, which itself - provides a (I hope) robust Fortran interface to library.cpp and - library.h. All prototypes herein COULD be added to library.h instead of - including this as a separate file. See the README for instructions. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* Prototypes for auxiliary functions */ -void lammps_set_callback (void *); -void lammps_set_user_energy (void*, double); -void lammps_set_user_virial (void*, double*); -void lammps_set_external_vector_length (void*, int); -void lammps_set_external_vector (void*, int, double); - -#ifdef __cplusplus -} -#endif - -/* vim: set ts=3 sts=3 expandtab: */ diff --git a/examples/COUPLE/fortran_dftb/LAMMPS.F90 b/examples/COUPLE/fortran_dftb/LAMMPS.F90 deleted file mode 100644 index 188fff9d60..0000000000 --- a/examples/COUPLE/fortran_dftb/LAMMPS.F90 +++ /dev/null @@ -1,982 +0,0 @@ -!! ----------------------------------------------------------------------- -! LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator -! www.cs.sandia.gov/~sjplimp/lammps.html -! Steve Plimpton, sjplimp@sandia.gov, Sandia National Laboratories -! -! 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: Karl D. Hammond -! University of Missouri (USA), 2012 -!-------------------------------------------------------------------------- - -!! LAMMPS, a Fortran 2003 module containing an interface between Fortran -!! programs and the C-style functions in library.cpp that ship with LAMMPS. -!! This file should be accompanied by LAMMPS-wrapper.cpp and LAMMPS-wrapper.h, -!! which define wrapper functions that ease portability and enforce array -!! dimensions. -!! -!! Everything in this module should be 100% portable by way of Fortran 2003's -!! ISO_C_BINDING intrinsic module. See the README for instructions for -!! compilation and use. -!! -!! Here are the PUBLIC functions and subroutines included in this module. -!! subroutine lammps_open (command_line, communicator, ptr) -!! subroutine lammps_open_no_mpi (command_line, ptr) -!! subroutine lammps_close (ptr) -!! subroutine lammps_file (ptr, str) -!! subroutine lammps_command (ptr, str) -!! subroutine lammps_free (ptr) -!! subroutine lammps_extract_global (global, ptr, name) -!! subroutine lammps_extract_atom (atom, ptr, name) -!! subroutine lammps_extract_fix (fix, ptr, id, style, type, i, j) -!! subroutine lammps_extract_compute (compute, ptr, id, style, type) -!! subroutine lammps_extract_variable (variable, ptr, name, group) -!! function lammps_get_natoms (ptr) -!! subroutine lammps_gather_atoms (ptr, name, count, data) -!! subroutine lammps_scatter_atoms (ptr, name, data) - -#define FLERR __FILE__,__LINE__ -! The above line allows for similar error checking as is done with standard -! LAMMPS files. - -module LAMMPS - - use, intrinsic :: ISO_C_binding, only : C_double, C_int, C_ptr, C_char, & - C_NULL_CHAR, C_loc, C_F_pointer, lammps_instance => C_ptr - implicit none - private - public :: lammps_set_user_virial - public :: lammps_set_external_vector_length - public :: lammps_set_external_vector - public :: lammps_set_user_energy - public :: lammps_open, lammps_open_no_mpi, lammps_close, lammps_file, & - lammps_command, lammps_free, lammps_extract_global, & - lammps_extract_atom, lammps_extract_compute, lammps_extract_fix, & - lammps_extract_variable, lammps_get_natoms, lammps_gather_atoms, & - lammps_set_callback - public :: lammps_scatter_atoms, lammps_instance, C_ptr, C_double, C_int - - !! Functions supplemental to the prototypes in library.h. {{{1 - !! The function definitions (in C++) are contained in LAMMPS-wrapper.cpp. - !! I would have written the first in Fortran, but the MPI libraries (which - !! were written in C) have C-based functions to convert from Fortran MPI - !! handles to C MPI handles, and there is no Fortran equivalent for those - !! functions. - interface - subroutine lammps_open_wrapper (argc, argv, communicator, ptr) & - bind (C, name='lammps_open_fortran_wrapper') - import :: C_int, C_ptr - integer (C_int), value :: argc - type (C_ptr), dimension(*) :: argv - integer, value :: communicator - type (C_ptr) :: ptr - end subroutine lammps_open_wrapper - subroutine lammps_actual_error_all (ptr, file, line, str) & - bind (C, name='lammps_error_all') - import :: C_int, C_char, C_ptr - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*), intent(in) :: file, str - integer (C_int), value :: line - end subroutine lammps_actual_error_all - function lammps_get_ntypes (ptr) result (ntypes) & - bind (C, name='lammps_get_ntypes') - import :: C_int, C_ptr - type (C_ptr), value :: ptr - integer (C_int) :: ntypes - end function lammps_get_ntypes - function lammps_actual_extract_compute_vectorsize (ptr, id, style) & - result (vectorsize) bind (C, name='lammps_extract_compute_vectorsize') - import :: C_int, C_char, C_ptr - integer (C_int) :: vectorsize - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - end function lammps_actual_extract_compute_vectorsize - subroutine lammps_actual_extract_compute_arraysize (ptr, id, style, & - nrows, ncols) bind (C, name='lammps_extract_compute_arraysize') - import :: C_int, C_char, C_ptr - integer (C_int) :: arraysize - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - integer (C_int) :: nrows, ncols - end subroutine lammps_actual_extract_compute_arraysize - function lammps_actual_extract_fix_vectorsize (ptr, id, style) & - result (vectorsize) bind (C, name='lammps_extract_fix_vectorsize') - import :: C_int, C_char, C_ptr - integer (C_int) :: vectorsize - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - end function lammps_actual_extract_fix_vectorsize - subroutine lammps_actual_extract_fix_arraysize (ptr, id, style, & - nrows, ncols) bind (C, name='lammps_extract_fix_arraysize') - import :: C_int, C_char, C_ptr - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style - integer (C_int) :: nrows, ncols - end subroutine lammps_actual_extract_fix_arraysize - end interface - - !! Functions/subroutines defined in library.h and library.cpp {{{1 - interface - subroutine lammps_actual_open_no_mpi (argc, argv, ptr) & - bind (C, name='lammps_open_no_mpi') - import :: C_int, C_ptr - integer (C_int), value :: argc - type (C_ptr), dimension(*) :: argv - type (C_ptr) :: ptr - end subroutine lammps_actual_open_no_mpi - - subroutine lammps_close (ptr) bind (C, name='lammps_close') - import :: C_ptr - type (C_ptr), value :: ptr - end subroutine lammps_close - - subroutine lammps_actual_file (ptr, str) bind (C, name='lammps_file') - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: str - end subroutine lammps_actual_file - - function lammps_actual_command (ptr, str) result (command) & - bind (C, name='lammps_command') - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: str - type (C_ptr) :: command - end function lammps_actual_command - - subroutine lammps_free (ptr) bind (C, name='lammps_free') - import :: C_ptr - type (C_ptr), value :: ptr - end subroutine lammps_free - - function lammps_actual_extract_global (ptr, name) & - bind (C, name='lammps_extract_global') result (global) - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name - type (C_ptr) :: global - end function lammps_actual_extract_global - - function lammps_actual_extract_atom (ptr, name) & - bind (C, name='lammps_extract_atom') result (atom) - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name - type (C_ptr) :: atom - end function lammps_actual_extract_atom - - function lammps_actual_extract_compute (ptr, id, style, type) & - result (compute) bind (C, name='lammps_extract_compute') - import :: C_ptr, C_char, C_int - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style, type - type (C_ptr) :: compute - end function lammps_actual_extract_compute - - function lammps_actual_extract_fix (ptr, id, style, type, i, j) & - result (fix) bind (C, name='lammps_extract_fix') - import :: C_ptr, C_char, C_int - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: id - integer (C_int), value :: style, type, i, j - type (C_ptr) :: fix - end function lammps_actual_extract_fix - - function lammps_actual_extract_variable (ptr, name, group) & - result (variable) bind (C, name='lammps_extract_variable') - import :: C_ptr, C_char - type (C_ptr), value :: ptr - character (kind=C_char), dimension(*) :: name, group - type (C_ptr) :: variable - end function lammps_actual_extract_variable - - function lammps_get_natoms (ptr) result (natoms) & - bind (C, name='lammps_get_natoms') - import :: C_ptr, C_int - type (C_ptr), value :: ptr - integer (C_int) :: natoms - end function lammps_get_natoms - - subroutine lammps_set_callback (ptr) & - bind (C, name='lammps_set_callback') - import :: C_ptr - type (C_ptr), value :: ptr - end subroutine lammps_set_callback - - subroutine lammps_set_user_energy (ptr, energy) & - bind (C, name='lammps_set_user_energy') - import :: C_ptr, C_double - type (C_ptr), value :: ptr - real(C_double), value :: energy - end subroutine lammps_set_user_energy - - subroutine lammps_set_user_virial (ptr, virial) & - bind (C, name='lammps_set_user_virial') - import :: C_ptr, C_double - type (C_ptr), value :: ptr - real(C_double) :: virial(6) - end subroutine lammps_set_user_virial - - subroutine lammps_set_external_vector_length (ptr, n) & - bind (C, name='lammps_set_external_vector_length') - import :: C_ptr, C_double, C_int - type(C_ptr), value :: ptr - integer (C_int), value :: n - end subroutine lammps_set_external_vector_length - - subroutine lammps_set_external_vector (ptr, n, val) & - bind (C, name='lammps_set_external_vector') - import :: C_ptr, C_int, C_double - type (C_ptr), value :: ptr - integer (C_int), value :: n - real(C_double), value :: val - end subroutine lammps_set_external_vector - - subroutine lammps_actual_gather_atoms (ptr, name, type, count, data) & - bind (C, name='lammps_gather_atoms') - import :: C_ptr, C_int, C_char - type (C_ptr), value :: ptr, data - character (kind=C_char), dimension(*) :: name - integer (C_int), value :: type, count - end subroutine lammps_actual_gather_atoms - - subroutine lammps_actual_scatter_atoms (ptr, name, type, count, data) & - bind (C, name='lammps_scatter_atoms') - import :: C_ptr, C_int, C_char - type (C_ptr), value :: ptr, data - character (kind=C_char), dimension(*) :: name - integer (C_int), value :: type, count - end subroutine lammps_actual_scatter_atoms - end interface - - ! Generic functions for the wrappers below {{{1 - - interface lammps_extract_global - module procedure lammps_extract_global_i, & - lammps_extract_global_dp - end interface lammps_extract_global - - interface lammps_extract_atom - module procedure lammps_extract_atom_ia, & - lammps_extract_atom_dpa, & - lammps_extract_atom_dp2a - end interface lammps_extract_atom - - interface lammps_extract_compute - module procedure lammps_extract_compute_dp, & - lammps_extract_compute_dpa, & - lammps_extract_compute_dp2a - end interface lammps_extract_compute - - interface lammps_extract_fix - module procedure lammps_extract_fix_dp, & - lammps_extract_fix_dpa, & - lammps_extract_fix_dp2a - end interface lammps_extract_fix - - interface lammps_extract_variable - module procedure lammps_extract_variable_dp, & - lammps_extract_variable_dpa - end interface lammps_extract_variable - - interface lammps_gather_atoms - module procedure lammps_gather_atoms_ia, lammps_gather_atoms_dpa - end interface lammps_gather_atoms - - interface lammps_scatter_atoms - module procedure lammps_scatter_atoms_ia, lammps_scatter_atoms_dpa - end interface lammps_scatter_atoms - -contains !! Wrapper functions local to this module {{{1 - - subroutine lammps_open (command_line, communicator, ptr) - character (len=*), intent(in) :: command_line - integer, intent(in) :: communicator - type (C_ptr) :: ptr - integer (C_int) :: argc - type (C_ptr), dimension(:), allocatable :: argv - character (kind=C_char), dimension(len_trim(command_line)+1), target :: & - c_command_line - c_command_line = string2Cstring (command_line) - call Cstring2argcargv (c_command_line, argc, argv) - call lammps_open_wrapper (argc, argv, communicator, ptr) - deallocate (argv) - end subroutine lammps_open - -!----------------------------------------------------------------------------- - - subroutine lammps_open_no_mpi (command_line, ptr) - character (len=*), intent(in) :: command_line - type (C_ptr) :: ptr - integer (C_int) :: argc - type (C_ptr), dimension(:), allocatable :: argv - character (kind=C_char), dimension(len_trim(command_line)+1), target :: & - c_command_line - c_command_line = string2Cstring (command_line) - call Cstring2argcargv (c_command_line, argc, argv) - call lammps_actual_open_no_mpi (argc, argv, ptr) - deallocate (argv) - end subroutine lammps_open_no_mpi - -!----------------------------------------------------------------------------- - - subroutine lammps_file (ptr, str) - type (C_ptr) :: ptr - character (len=*) :: str - character (kind=C_char), dimension(len_trim(str)+1) :: Cstr - Cstr = string2Cstring (str) - call lammps_actual_file (ptr, Cstr) - end subroutine lammps_file - -!----------------------------------------------------------------------------- - - subroutine lammps_command (ptr, str) - type (C_ptr) :: ptr - character (len=*) :: str - character (kind=C_char), dimension(len_trim(str)+1) :: Cstr - type (C_ptr) :: dummy - Cstr = string2Cstring (str) - dummy = lammps_actual_command (ptr, Cstr) - end subroutine lammps_command - -!----------------------------------------------------------------------------- - -! lammps_extract_global {{{2 - function lammps_extract_global_Cptr (ptr, name) result (global) - type (C_ptr) :: global - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - Cname = string2Cstring (name) - global = lammps_actual_extract_global (ptr, Cname) - end function lammps_extract_global_Cptr - subroutine lammps_extract_global_i (global, ptr, name) - integer (C_int), pointer, intent(out) :: global - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - Cptr = lammps_extract_global_Cptr (ptr, name) - call C_F_pointer (Cptr, global) - end subroutine lammps_extract_global_i - subroutine lammps_extract_global_dp (global, ptr, name) - real (C_double), pointer, intent(out) :: global - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - Cptr = lammps_extract_global_Cptr (ptr, name) - call C_F_pointer (Cptr, global) - end subroutine lammps_extract_global_dp - -!----------------------------------------------------------------------------- - -! lammps_extract_atom {{{2 - function lammps_extract_atom_Cptr (ptr, name) result (atom) - type (C_ptr) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - Cname = string2Cstring (name) - atom = lammps_actual_extract_atom (ptr, Cname) - end function lammps_extract_atom_Cptr - subroutine lammps_extract_atom_ia (atom, ptr, name) - integer (C_int), dimension(:), pointer, intent(out) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - integer (C_int), pointer :: nelements - call lammps_extract_global_i (nelements, ptr, 'nlocal') - Cptr = lammps_extract_atom_Cptr (ptr, name) - call C_F_pointer (Cptr, atom, (/nelements/)) - end subroutine lammps_extract_atom_ia - subroutine lammps_extract_atom_dpa (atom, ptr, name) - real (C_double), dimension(:), pointer, intent(out) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - integer (C_int), pointer :: nlocal - integer :: nelements - real (C_double), dimension(:), pointer :: Fptr - if ( name == 'mass' ) then - nelements = lammps_get_ntypes (ptr) + 1 - else if ( name == 'x' .or. name == 'v' .or. name == 'f' .or. & - name == 'mu' .or. name == 'omega' .or. name == 'torque' .or. & - name == 'angmom' ) then - ! We should not be getting a rank-2 array here! - call lammps_error_all (ptr, FLERR, 'You cannot extract those atom& - & data (' // trim(name) // ') into a rank 1 array.') - return - else - ! Everything else we can get is probably nlocal units long - call lammps_extract_global_i (nlocal, ptr, 'nlocal') - nelements = nlocal - end if - Cptr = lammps_extract_atom_Cptr (ptr, name) - call C_F_pointer (Cptr, Fptr, (/nelements/)) - if ( name == 'mass' ) then - !atom(0:) => Fptr - atom => Fptr - else - atom => Fptr - end if - end subroutine lammps_extract_atom_dpa - subroutine lammps_extract_atom_dp2a (atom, ptr, name) - real (C_double), dimension(:,:), pointer, intent(out) :: atom - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - type (C_ptr) :: Cptr - type (C_ptr), pointer, dimension(:) :: Catom - integer (C_int), pointer :: nelements - if ( name /= 'x' .and. name /= 'v' .and. name /= 'f' .and. & - name /= 'mu' .and. name /= 'omega' .and. name /= 'tandque' .and. & - name /= 'angmom' .and. name /= 'fexternal' ) then - ! We should not be getting a rank-2 array here! - call lammps_error_all (ptr, FLERR, 'You cannot extract those atom& - & data (' // trim(name) // ') into a rank 2 array.') - return - end if - Cptr = lammps_extract_atom_Cptr (ptr, name) - call lammps_extract_global_i (nelements, ptr, 'nlocal') - ! Catom will now be the array of void* pointers that the void** pointer - ! pointed to. Catom(1) is now the pointer to the first element. - call C_F_pointer (Cptr, Catom, (/nelements/)) - ! Now get the actual array, which has its shape transposed from what we - ! might think of it in C - call C_F_pointer (Catom(1), atom, (/3, nelements/)) - end subroutine lammps_extract_atom_dp2a - -!----------------------------------------------------------------------------- - -! lammps_extract_compute {{{2 - function lammps_extract_compute_Cptr (ptr, id, style, type) result (compute) - type (C_ptr) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - integer (kind=C_int) :: Cstyle, Ctype - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = style - Ctype = type - compute = lammps_actual_extract_compute (ptr, Cid, Cstyle, Ctype) - end function lammps_extract_compute_Cptr - subroutine lammps_extract_compute_dp (compute, ptr, id, style, type) - real (C_double), pointer, intent(out) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - type (C_ptr) :: Cptr - ! The only valid values of (style,type) are (0,0) for scalar 'compute' - if ( style /= 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot pack per-atom/local& - & data into a scalar.') - return - end if - if ( type == 1 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & vector (rank 1) into a scalar.') - return - else if ( type == 2 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & array (rank 2) into a scalar.') - return - end if - Cptr = lammps_extract_compute_Cptr (ptr, id, style, type) - call C_F_pointer (Cptr, compute) - end subroutine lammps_extract_compute_dp - subroutine lammps_extract_compute_dpa (compute, ptr, id, style, type) - real (C_double), dimension(:), pointer, intent(out) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - type (C_ptr) :: Cptr - integer :: nelements - ! Check for the correct dimensionality - if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & scalar (rank 0) into a rank 1 variable.') - return - else if ( type == 2 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & array (rank 2) into a rank 1 variable.') - return - end if - nelements = lammps_extract_compute_vectorsize (ptr, id, style) - Cptr = lammps_extract_compute_Cptr (ptr, id, style, type) - call C_F_pointer (Cptr, compute, (/nelements/)) - end subroutine lammps_extract_compute_dpa - subroutine lammps_extract_compute_dp2a (compute, ptr, id, style, type) - real (C_double), dimension(:,:), pointer, intent(out) :: compute - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type - type (C_ptr) :: Cptr - type (C_ptr), pointer, dimension(:) :: Ccompute - integer :: nr, nc - ! Check for the correct dimensionality - if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & scalar (rank 0) into a rank 2 variable.') - return - else if ( type == 1 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a compute& - & array (rank 1) into a rank 2 variable.') - return - end if - call lammps_extract_compute_arraysize (ptr, id, style, nr, nc) - Cptr = lammps_extract_compute_Cptr (ptr, id, style, type) - call C_F_pointer (Cptr, Ccompute, (/nr/)) - ! Note that the matrix is transposed, from Fortran's perspective - call C_F_pointer (Ccompute(1), compute, (/nc, nr/)) - end subroutine lammps_extract_compute_dp2a - -!----------------------------------------------------------------------------- - -! lammps_extract_fix {{{2 - function lammps_extract_fix_Cptr (ptr, id, style, type, i, j) & - result (fix) - type (C_ptr) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - integer (kind=C_int) :: Cstyle, Ctype, Ci, Cj - Cid = string2Cstring (id) - Cstyle = style - Ctype = type - Ci = i - 1 ! This is for consistency with the values from f_ID[i], - Cj = j - 1 ! which is different from what library.cpp uses! - if ( (type >= 1 .and. Ci < 0) .or. & - (type == 2 .and. (Ci < 0 .or. Cj < 0) ) ) then - call lammps_error_all (ptr, FLERR, 'Index out of range in& - & lammps_extract_fix') - end if - fix = lammps_actual_extract_fix (ptr, Cid, Cstyle, Ctype, Ci, Cj) - end function lammps_extract_fix_Cptr - subroutine lammps_extract_fix_dp (fix, ptr, id, style, type, i, j) - real (C_double), intent(out) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - type (C_ptr) :: Cptr - real (C_double), pointer :: Fptr - ! Check for the correct dimensionality - if ( style /= 0 ) then - select case (type) - case (0) - call lammps_error_all (ptr, FLERR, 'There is no per-atom or local& - & scalar data available from fixes.') - case (1) - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix''s & - &per-atom/local vector (rank 1) into a scalar.') - case (2) - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix''s & - &per-atom/local array (rank 2) into a scalar.') - case default - call lammps_error_all (ptr, FLERR, 'Invalid extract_fix style/& - &type combination.') - end select - return - end if - Cptr = lammps_extract_fix_Cptr (ptr, id, style, type, i, j) - call C_F_pointer (Cptr, Fptr) - fix = Fptr - nullify (Fptr) - ! Memory is only allocated for "global" fix variables - if ( style == 0 ) call lammps_free (Cptr) - end subroutine lammps_extract_fix_dp - subroutine lammps_extract_fix_dpa (fix, ptr, id, style, type, i, j) - real (C_double), dimension(:), pointer, intent(out) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - type (C_ptr) :: Cptr - integer :: fix_len - ! Check for the correct dimensionality - if ( style == 0 ) then - call lammps_error_all (ptr, FLERR, 'You can''t extract the& - & whole vector from global fix data') - return - else if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You can''t extract a fix& - & scalar into a rank 1 variable') - return - else if ( type == 2 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix& - & array into a rank 1 variable.') - return - else if ( type /= 1 ) then - call lammps_error_all (ptr, FLERR, 'Invalid type for fix extraction.') - return - end if - fix_len = lammps_extract_fix_vectorsize (ptr, id, style) - call C_F_pointer (Cptr, fix, (/fix_len/)) - ! Memory is only allocated for "global" fix variables, which we should - ! never get here, so no need to call lammps_free! - end subroutine lammps_extract_fix_dpa - subroutine lammps_extract_fix_dp2a (fix, ptr, id, style, type, i, j) - real (C_double), dimension(:,:), pointer, intent(out) :: fix - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style, type, i, j - type (C_ptr) :: Cptr - type (C_ptr), pointer, dimension(:) :: Cfix - integer :: nr, nc - ! Check for the correct dimensionality - if ( style == 0 ) then - call lammps_error_all (ptr, FLERR, 'It is not possible to extract the& - & entire array from global fix data.') - return - else if ( type == 0 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix& - & scalar (rank 0) into a rank 2 variable.') - return - else if ( type == 1 ) then - call lammps_error_all (ptr, FLERR, 'You cannot extract a fix& - & vector (rank 1) into a rank 2 variable.') - return - end if - call lammps_extract_fix_arraysize (ptr, id, style, nr, nc) - ! Extract pointer to first element as Cfix(1) - call C_F_pointer (Cptr, Cfix, (/nr/)) - ! Now extract the array, which is transposed - call C_F_pointer (Cfix(1), fix, (/nc, nr/)) - end subroutine lammps_extract_fix_dp2a - -!----------------------------------------------------------------------------- - -! lammps_extract_variable {{{2 - function lammps_extract_variable_Cptr (ptr, name, group) result (variable) - type (C_ptr) :: ptr, variable - character (len=*) :: name - character (len=*), optional :: group - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - character (kind=C_char), dimension(:), allocatable :: Cgroup - Cname = string2Cstring (name) - if ( present(group) ) then - allocate (Cgroup(len_trim(group)+1)) - Cgroup = string2Cstring (group) - else - allocate (Cgroup(1)) - Cgroup(1) = C_NULL_CHAR - end if - variable = lammps_actual_extract_variable (ptr, Cname, Cgroup) - deallocate (Cgroup) - end function lammps_extract_variable_Cptr - subroutine lammps_extract_variable_dp (variable, ptr, name, group) - real (C_double), intent(out) :: variable - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (len=*), intent(in), optional :: group - type (C_ptr) :: Cptr - real (C_double), pointer :: Fptr - if ( present(group) ) then - Cptr = lammps_extract_variable_Cptr (ptr, name, group) - else - Cptr = lammps_extract_variable_Cptr (ptr, name) - end if - call C_F_pointer (Cptr, Fptr) - variable = Fptr - nullify (Fptr) - call lammps_free (Cptr) - end subroutine lammps_extract_variable_dp - subroutine lammps_extract_variable_dpa (variable, ptr, name, group) - real (C_double), dimension(:), allocatable, intent(out) :: variable - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - character (len=*), intent(in), optional :: group - type (C_ptr) :: Cptr - real (C_double), dimension(:), pointer :: Fptr - integer :: natoms - if ( present(group) ) then - Cptr = lammps_extract_variable_Cptr (ptr, name, group) - else - Cptr = lammps_extract_variable_Cptr (ptr, name) - end if - natoms = lammps_get_natoms (ptr) - allocate (variable(natoms)) - call C_F_pointer (Cptr, Fptr, (/natoms/)) - variable = Fptr - nullify (Fptr) - call lammps_free (Cptr) - end subroutine lammps_extract_variable_dpa - -!-------------------------------------------------------------------------2}}} - - subroutine lammps_gather_atoms_ia (ptr, name, count, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count - integer, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - integer (C_int), dimension(:), pointer :: Fdata - integer (C_int) :: natoms - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 0_C_int - integer (C_int) :: Ccount - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*natoms) ) - allocate ( data(count*natoms) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms (ptr, Cname, Ctype, Ccount, Cdata) - data = Fdata - deallocate (Fdata) - end subroutine lammps_gather_atoms_ia - subroutine lammps_gather_atoms_dpa (ptr, name, count, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, intent(in) :: count - double precision, dimension(:), allocatable, intent(out) :: data - type (C_ptr) :: Cdata - real (C_double), dimension(:), pointer :: Fdata - integer (C_int) :: natoms - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), parameter :: Ctype = 1_C_int - integer (C_int) :: Ccount - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - if ( count /= 1 .and. count /= 3 ) then - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - else - Ccount = count - end if - allocate ( Fdata(count*natoms) ) - allocate ( data(count*natoms) ) - Cdata = C_loc (Fdata(1)) - call lammps_actual_gather_atoms (ptr, Cname, Ctype, Ccount, Cdata) - data = Fdata(:) - deallocate (Fdata) - end subroutine lammps_gather_atoms_dpa - -!----------------------------------------------------------------------------- - - subroutine lammps_scatter_atoms_ia (ptr, name, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - integer, dimension(:), intent(in) :: data - integer (kind=C_int) :: natoms, Ccount - integer (kind=C_int), parameter :: Ctype = 0_C_int - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - integer (C_int), dimension(size(data)), target :: Fdata - type (C_ptr) :: Cdata - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - Ccount = size(data) / natoms - if ( Ccount /= 1 .and. Ccount /= 3 ) & - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - Fdata = data - Cdata = C_loc (Fdata(1)) - call lammps_actual_scatter_atoms (ptr, Cname, Ctype, Ccount, Cdata) - end subroutine lammps_scatter_atoms_ia - subroutine lammps_scatter_atoms_dpa (ptr, name, data) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: name - double precision, dimension(:), intent(in) :: data - integer (kind=C_int) :: natoms, Ccount - integer (kind=C_int), parameter :: Ctype = 1_C_int - character (kind=C_char), dimension(len_trim(name)+1) :: Cname - real (C_double), dimension(size(data)), target :: Fdata - type (C_ptr) :: Cdata - natoms = lammps_get_natoms (ptr) - Cname = string2Cstring (name) - Ccount = size(data) / natoms - if ( Ccount /= 1 .and. Ccount /= 3 ) & - call lammps_error_all (ptr, FLERR, 'lammps_gather_atoms requires& - & count to be either 1 or 3') - Fdata = data - Cdata = C_loc (Fdata(1)) - call lammps_actual_scatter_atoms (ptr, Cname, Ctype, Ccount, Cdata) - end subroutine lammps_scatter_atoms_dpa - -!----------------------------------------------------------------------------- - - function lammps_extract_compute_vectorsize (ptr, id, style) & - result (vectorsize) - integer :: vectorsize - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer (C_int) :: Cvectorsize, Cstyle - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int(style, C_int) - Cvectorsize = lammps_actual_extract_compute_vectorsize (ptr, Cid, Cstyle) - vectorsize = int(Cvectorsize, kind(vectorsize)) - end function lammps_extract_compute_vectorsize - -!----------------------------------------------------------------------------- - - function lammps_extract_fix_vectorsize (ptr, id, style) & - result (vectorsize) - integer :: vectorsize - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer (C_int) :: Cvectorsize, Cstyle - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int(style, C_int) - Cvectorsize = lammps_actual_extract_fix_vectorsize (ptr, Cid, Cstyle) - vectorsize = int(Cvectorsize, kind(vectorsize)) - end function lammps_extract_fix_vectorsize - -!----------------------------------------------------------------------------- - - subroutine lammps_extract_compute_arraysize (ptr, id, style, nrows, ncols) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer, intent(out) :: nrows, ncols - integer (C_int) :: Cstyle, Cnrows, Cncols - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int (style, C_int) - call lammps_actual_extract_compute_arraysize (ptr, Cid, Cstyle, & - Cnrows, Cncols) - nrows = int (Cnrows, kind(nrows)) - ncols = int (Cncols, kind(ncols)) - end subroutine lammps_extract_compute_arraysize - -!----------------------------------------------------------------------------- - - subroutine lammps_extract_fix_arraysize (ptr, id, style, nrows, ncols) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: id - integer, intent(in) :: style - integer, intent(out) :: nrows, ncols - integer (C_int) :: Cstyle, Cnrows, Cncols - character (kind=C_char), dimension(len_trim(id)+1) :: Cid - Cid = string2Cstring (id) - Cstyle = int (style, kind(Cstyle)) - call lammps_actual_extract_fix_arraysize (ptr, Cid, Cstyle, & - Cnrows, Cncols) - nrows = int (Cnrows, kind(nrows)) - ncols = int (Cncols, kind(ncols)) - end subroutine lammps_extract_fix_arraysize - -!----------------------------------------------------------------------------- - - subroutine lammps_error_all (ptr, file, line, str) - type (C_ptr), intent(in) :: ptr - character (len=*), intent(in) :: file, str - integer, intent(in) :: line - character (kind=C_char), dimension(len_trim(file)+1) :: Cfile - character (kind=C_char), dimension(len_trim(str)+1) :: Cstr - integer (C_int) :: Cline - Cline = int(line, kind(Cline)) - Cfile = string2Cstring (file) - Cstr = string2Cstring (str) - call lammps_actual_error_all (ptr, Cfile, Cline, Cstr) - end subroutine lammps_error_all - -!----------------------------------------------------------------------------- - -! Locally defined helper functions {{{1 - - pure function string2Cstring (string) result (C_string) - use, intrinsic :: ISO_C_binding, only : C_char, C_NULL_CHAR - character (len=*), intent(in) :: string - character (len=1, kind=C_char) :: C_string (len_trim(string)+1) - integer :: i, n - n = len_trim (string) - forall (i = 1:n) - C_string(i) = string(i:i) - end forall - C_string(n+1) = C_NULL_CHAR - end function string2Cstring - -!----------------------------------------------------------------------------- - - subroutine Cstring2argcargv (Cstring, argc, argv) - !! Converts a C-style string to argc and argv, that is, words in Cstring - !! become C-style strings in argv. IMPORTANT: Cstring is modified by - !! this routine! I would make Cstring local TO this routine and accept - !! a Fortran-style string instead, but we run into scoping and - !! allocation problems that way. This routine assumes the string is - !! null-terminated, as all C-style strings must be. - - character (kind=C_char), dimension(*), target, intent(inout) :: Cstring - integer (C_int), intent(out) :: argc - type (C_ptr), dimension(:), allocatable, intent(out) :: argv - - integer :: StringStart, SpaceIndex, strlen, argnum - - argc = 1_C_int - - ! Find the length of the string - strlen = 1 - do while ( Cstring(strlen) /= C_NULL_CHAR ) - strlen = strlen + 1 - end do - - ! Find the number of non-escaped spaces - SpaceIndex = 2 - do while ( SpaceIndex < strlen ) - if ( Cstring(SpaceIndex) == ' ' .and. & - Cstring(SpaceIndex-1) /= '\' ) then - argc = argc + 1_C_int - ! Find the next non-space character - do while ( Cstring(SpaceIndex+1) == ' ') - SpaceIndex = SpaceIndex + 1 - end do - end if - SpaceIndex = SpaceIndex + 1 - end do - - ! Now allocate memory for argv - allocate (argv(argc)) - - ! Now find the string starting and ending locations - StringStart = 1 - SpaceIndex = 2 - argnum = 1 - do while ( SpaceIndex < strlen ) - if ( Cstring(SpaceIndex) == ' ' .and. & - Cstring(SpaceIndex-1) /= '\' ) then - ! Found a real space => split strings and store this one - Cstring(Spaceindex) = C_NULL_CHAR ! Replaces space with NULL - argv(argnum) = C_loc(Cstring(StringStart)) - argnum = argnum + 1 - ! Find the next non-space character - do while ( Cstring(SpaceIndex+1) == ' ') - SpaceIndex = SpaceIndex + 1 - end do - StringStart = SpaceIndex + 1 - else if ( Cstring(SpaceIndex) == ' ' .and. & - Cstring(SpaceIndex-1) == '\' ) then - ! Escaped space => remove backslash and move rest of array - Cstring(SpaceIndex-1:strlen-1) = Cstring(SpaceIndex:strlen) - strlen = strlen - 1 ! Last character is still C_NULL_CHAR - end if - SpaceIndex = SpaceIndex + 1 - end do - ! Now handle the last argument - argv(argnum) = C_loc(Cstring(StringStart)) - - end subroutine Cstring2argcargv - -! 1}}} - -end module LAMMPS - -! vim: foldmethod=marker tabstop=3 softtabstop=3 shiftwidth=3 expandtab diff --git a/examples/COUPLE/fortran_dftb/README b/examples/COUPLE/fortran_dftb/README deleted file mode 100644 index 39a2f18169..0000000000 --- a/examples/COUPLE/fortran_dftb/README +++ /dev/null @@ -1,37 +0,0 @@ -This directory has an example of using a callback function to obtain -forces from a fortran code for a LAMMPS simulation. The reader should -refer to the README file in COUPLE/fortran2 before proceeding. Here, -the LAMMPS.F90 file has been modified slightly and additional files -named LAMMPS-wrapper2.h and LAMMPS-wrapper2.cpp have been included in -order to supply wrapper functions to set the LAMMPS callback function, -total energy, virial, and electronic entropy contribution (needed for -MSST simulations with a quantum code). - -In this example, the callback function is set to run the -semi-empirical quantum code DFTB+ in serial and then read in the total -energy, forces, and stress tensor from file. In this case, nlocal = -the total number of atoms in the system, so particle positions can be -read from the pos array directly, and DFTB+ forces can simply be -included via the fext array. The user should take care in the case of -a parallel calculation, where LAMMPS can assign different particules -to each processor. For example, the user should use functions such as -lammps_gather_atoms() and lammps_scatter_atoms() in the case where the -fortran force calculating code requires the positions of all atoms, -etc. - -A few more important notes: - --Calling the subroutine lammps_set_callback() is required in order to set - a pointer to the callback function in LAMMPS. --The subroutine lammps_set_user_energy() passes in the potential energy - from DFTB+ to LAMMPS. Similarly, lammps_set_user_virial passes the stress tensor. - --The electronic entropy contribution is set via lammps_set_external_vector(). Their needs - to be a call to lammps_set_external_vector_length() before this value can be - passed to LAMMPS. - -This example was created by Nir Goldman, whom you can contact with -questions: - -Nir Goldman, LLNL -ngoldman@llnl.gov diff --git a/examples/COUPLE/fortran_dftb/data.diamond b/examples/COUPLE/fortran_dftb/data.diamond deleted file mode 100644 index b3dd599cf4..0000000000 --- a/examples/COUPLE/fortran_dftb/data.diamond +++ /dev/null @@ -1,148 +0,0 @@ -# Position data file - -64 atoms -1 atom types - -0 7.134 xlo xhi -0 7.134 ylo yhi -0 7.134 zlo zhi - -0.00000000 0.00000000 0.00000000 xy xz yz - -Masses - -1 12.010000 - -Atoms - - 1 1 0 0 0 0 - 2 1 0 0.89175 0.89175 0.89175 - 3 1 0 1.7835 1.7835 0 - 4 1 0 2.67525 2.67525 0.89175 - 5 1 0 0 1.7835 1.7835 - 6 1 0 0.89175 2.67525 2.67525 - 7 1 0 1.7835 0 1.7835 - 8 1 0 2.67525 0.89175 2.67525 - 9 1 0 0 0 3.567 - 10 1 0 0.89175 0.89175 4.45875 - 11 1 0 1.7835 1.7835 3.567 - 12 1 0 2.67525 2.67525 4.45875 - 13 1 0 0 1.7835 5.3505 - 14 1 0 0.89175 2.67525 6.24225 - 15 1 0 1.7835 0 5.3505 - 16 1 0 2.67525 0.89175 6.24225 - 17 1 0 0 3.567 0 - 18 1 0 0.89175 4.45875 0.89175 - 19 1 0 1.7835 5.3505 0 - 20 1 0 2.67525 6.24225 0.89175 - 21 1 0 0 5.3505 1.7835 - 22 1 0 0.89175 6.24225 2.67525 - 23 1 0 1.7835 3.567 1.7835 - 24 1 0 2.67525 4.45875 2.67525 - 25 1 0 0 3.567 3.567 - 26 1 0 0.89175 4.45875 4.45875 - 27 1 0 1.7835 5.3505 3.567 - 28 1 0 2.67525 6.24225 4.45875 - 29 1 0 0 5.3505 5.3505 - 30 1 0 0.89175 6.24225 6.24225 - 31 1 0 1.7835 3.567 5.3505 - 32 1 0 2.67525 4.45875 6.24225 - 33 1 0 3.567 0 0 - 34 1 0 4.45875 0.89175 0.89175 - 35 1 0 5.3505 1.7835 0 - 36 1 0 6.24225 2.67525 0.89175 - 37 1 0 3.567 1.7835 1.7835 - 38 1 0 4.45875 2.67525 2.67525 - 39 1 0 5.3505 0 1.7835 - 40 1 0 6.24225 0.89175 2.67525 - 41 1 0 3.567 0 3.567 - 42 1 0 4.45875 0.89175 4.45875 - 43 1 0 5.3505 1.7835 3.567 - 44 1 0 6.24225 2.67525 4.45875 - 45 1 0 3.567 1.7835 5.3505 - 46 1 0 4.45875 2.67525 6.24225 - 47 1 0 5.3505 0 5.3505 - 48 1 0 6.24225 0.89175 6.24225 - 49 1 0 3.567 3.567 0 - 50 1 0 4.45875 4.45875 0.89175 - 51 1 0 5.3505 5.3505 0 - 52 1 0 6.24225 6.24225 0.89175 - 53 1 0 3.567 5.3505 1.7835 - 54 1 0 4.45875 6.24225 2.67525 - 55 1 0 5.3505 3.567 1.7835 - 56 1 0 6.24225 4.45875 2.67525 - 57 1 0 3.567 3.567 3.567 - 58 1 0 4.45875 4.45875 4.45875 - 59 1 0 5.3505 5.3505 3.567 - 60 1 0 6.24225 6.24225 4.45875 - 61 1 0 3.567 5.3505 5.3505 - 62 1 0 4.45875 6.24225 6.24225 - 63 1 0 5.3505 3.567 5.3505 - 64 1 0 6.24225 4.45875 6.24225 - -Velocities - -1 -0.00733742 -0.0040297 -0.00315229 -2 -0.00788609 -0.00567535 -0.00199152 -3 -0.00239042 0.00710139 -0.00335049 -4 0.00678551 0.0019976 0.00219289 -5 0.00413717 0.00275709 0.000937637 -6 -0.00126313 0.00485636 0.00727862 -7 0.00337547 -0.00234623 -0.000922223 -8 -0.00792183 -0.00509186 -0.00104168 -9 0.00414091 0.00390285 0.000845961 -10 -0.000284543 0.0010771 -0.00458404 -11 -0.00394968 -0.00446363 -0.00361688 -12 0.00067088 -0.00655175 -0.00752464 -13 0.00306632 -0.00245545 -0.00183867 -14 -0.0082145 -0.00564127 0.000281191 -15 0.00504454 0.0045835 0.000495763 -16 0.0035767 0.00320441 -0.00486426 -17 0.00420597 0.00262005 -0.0049459 -18 0.00440579 -1.76783e-05 0.00449311 -19 -0.00406463 0.00613304 0.00285599 -20 0.00171215 -0.00517887 0.00124326 -21 0.0011118 0.00334129 -0.0015222 -22 -0.00838394 -0.00112906 -0.00353379 -23 -0.00578527 -0.00415501 0.00297043 -24 -0.00211466 0.000964108 -0.00716523 -25 -0.000204107 -0.00380986 0.00681648 -26 0.00677838 0.00540935 0.0044354 -27 -0.00266809 -0.00358382 -0.00241889 -28 -0.0003973 0.00236566 0.00558871 -29 0.000754103 0.00457797 0.000105531 -30 -0.00246049 0.00110428 0.00511088 -31 0.00248891 0.00623314 0.00461597 -32 -0.00509423 0.000570503 0.00720856 -33 -0.00244427 -0.00374384 0.00618767 -34 -0.000360752 -8.10558e-05 0.00314052 -35 0.00435313 -0.00630587 -0.0070309 -36 0.00651087 -0.00389833 3.72525e-05 -37 0.00631828 -0.00316064 0.00231522 -38 -0.00579624 -0.00345068 -0.000277486 -39 0.00483974 0.000715028 0.000206355 -40 -0.00388164 -0.00189242 -0.00554862 -41 0.00398115 0.00152915 0.00756919 -42 -0.000552263 0.00352025 -0.000246143 -43 -0.00800284 0.00555703 0.00425716 -44 -0.00734405 -0.00752512 0.00667173 -45 -0.00545636 0.00421035 0.00399552 -46 0.00480246 0.00621147 -0.00492715 -47 -0.00424168 0.00621818 -9.37733e-05 -48 -0.00649561 0.00612908 -0.0020753 -49 -0.0075007 -0.00384737 -0.00687913 -50 -0.00203903 -0.00764372 0.0023883 -51 0.00442642 0.00744072 -0.0049344 -52 -0.00280486 -0.00509128 -0.00678045 -53 0.00679491 0.00583493 0.00333875 -54 0.00574665 -0.00521074 0.00523475 -55 0.00305618 -0.00320094 0.00341297 -56 0.004304 0.000615544 -0.00668787 -57 0.00564532 0.00327373 0.00388611 -58 0.000676899 0.00210326 0.00495295 -59 0.000160781 -0.00744313 -0.00279828 -60 0.00623521 0.00371301 0.00178015 -61 0.00520759 0.000642669 0.00207913 -62 0.00398042 0.0046438 -0.00359978 -63 -0.00478071 -0.00304932 -0.00765125 -64 0.00282671 -0.00548392 -0.00692691 diff --git a/examples/COUPLE/fortran_dftb/dftb_in.hsd b/examples/COUPLE/fortran_dftb/dftb_in.hsd deleted file mode 100644 index 104a4c04ce..0000000000 --- a/examples/COUPLE/fortran_dftb/dftb_in.hsd +++ /dev/null @@ -1,40 +0,0 @@ -#sample DFTB+ script to run this test code -Geometry = GenFormat { -<<< "lammps.gen" -} - -Driver = { -} - -Hamiltonian = DFTB { - LAMMPS = Yes # keyword to print energy, forces, and stress tensor to file(results.out) - SCC = No - MaxAngularMomentum = { - C = "p" - } - Charge = 0.0 - Eigensolver = Standard {} - Filling = Fermi { - Temperature [Kelvin] = 298.0 - } - SlaterKosterFiles = Type2FileNames { - Prefix = "~/slako/mio-1-1/" # the user must define the location of the skf files - Separator = "-" - Suffix = ".skf" - LowerCaseTypeName = No - } - KPointsAndWeights = { - 0.0000000000000 0.0000000000000 0.0000000000000 1.00000000000000 - } -} - -Options = { - CalculateForces = Yes - WriteDetailedOut = No - WriteBandOut = No - RandomSeed = 12345 -} - -ParserOptions = { - ParserVersion = 3 -} diff --git a/examples/COUPLE/fortran_dftb/dftb_pin.hsd b/examples/COUPLE/fortran_dftb/dftb_pin.hsd deleted file mode 100644 index 6d9dea4a15..0000000000 --- a/examples/COUPLE/fortran_dftb/dftb_pin.hsd +++ /dev/null @@ -1,129 +0,0 @@ -Geometry = GenFormat { -64 S -C -1 1 7.099007 7.117657 7.119139 -2 1 0.858709 0.867233 0.882294 -3 1 1.772527 1.811776 7.120239 -4 1 2.702145 2.681271 0.901362 -5 1 0.017539 1.794455 1.788454 -6 1 0.885593 2.694118 2.707994 -7 1 1.795055 7.120787 1.777896 -8 1 2.642849 0.868278 2.670699 -9 1 0.016060 0.017156 3.568644 -10 1 0.891891 0.896406 4.439286 -11 1 1.766086 1.764402 3.550134 -12 1 2.677349 2.648926 4.427174 -13 1 0.010133 1.771283 5.342173 -14 1 0.858153 2.653565 6.241596 -15 1 1.804087 0.020636 5.353268 -16 1 2.689680 0.907188 6.224575 -17 1 0.017845 3.577563 7.113016 -18 1 0.910027 4.459286 0.910286 -19 1 1.766394 5.376046 0.015526 -20 1 2.683727 6.220728 0.898553 -21 1 0.003357 5.363423 1.774139 -22 1 0.856735 6.238324 2.660213 -23 1 1.761079 3.549776 1.797054 -24 1 2.667227 4.463441 2.646074 -25 1 7.132499 3.551558 3.599764 -26 1 0.920387 4.482191 4.479257 -27 1 1.772194 5.337132 3.555569 -28 1 2.675010 6.251629 4.483124 -29 1 0.005702 5.371095 5.351147 -30 1 0.880807 6.249819 6.264231 -31 1 1.793177 3.592396 5.369939 -32 1 2.653179 4.463595 6.274044 -33 1 3.557243 7.118913 0.026006 -34 1 4.458971 0.889331 0.904950 -35 1 5.367903 1.759757 7.104941 -36 1 6.271565 2.658454 0.890168 -37 1 3.591915 1.768681 1.793880 -38 1 4.435612 2.662184 2.676722 -39 1 5.371040 0.000196 1.783464 -40 1 6.226453 0.886640 2.653384 -41 1 3.583339 0.005449 3.600177 -42 1 4.453692 0.909417 4.459713 -43 1 5.314554 1.805409 3.584215 -44 1 6.210181 2.642660 4.486206 -45 1 3.545704 1.802745 5.365369 -46 1 4.476660 2.701226 6.220451 -47 1 5.332820 0.029557 5.347965 -48 1 6.215725 0.915081 6.230289 -49 1 3.536446 3.551469 7.106600 -50 1 4.451181 4.426439 0.900180 -51 1 5.368735 5.377996 7.109524 -52 1 6.230666 6.220985 0.862175 -53 1 3.596626 5.372822 1.797613 -54 1 4.485613 6.221252 2.699652 -55 1 5.364421 3.549838 1.796281 -56 1 6.261739 4.459046 2.648152 -57 1 3.588752 3.581054 3.581755 -58 1 4.462342 4.467270 4.478800 -59 1 5.355202 5.318323 3.556531 -60 1 6.268570 6.259831 4.465795 -61 1 3.588636 5.354278 5.362327 -62 1 4.475747 6.263866 6.227803 -63 1 5.331158 3.554349 5.318368 -64 1 6.254581 4.436344 6.209681 -0.0 0.0 0.0 -7.13400000000000 0 0 -0 7.13400000000000 0 -0 0 7.13400000000000 -} -Driver = {} -Hamiltonian = DFTB { - LAMMPS = Yes - SCC = No - MaxAngularMomentum = { - C = "p" - } - Charge = 0.0 - Eigensolver = Standard {} - Filling = Fermi { - Temperature [Kelvin] = 298.0 - IndependentKFilling = No - } - SlaterKosterFiles = Type2FileNames { - Prefix = "~/slako/mio-1-1/" - Separator = "-" - Suffix = ".skf" - LowerCaseTypeName = No - } - KPointsAndWeights = { -0.0000000000000 0.0000000000000 0.0000000000000 1.00000000000000 - } - PolynomialRepulsive = {} - OldRepulsiveSum = No - OrbitalResolvedSCC = No - OldSKInterpolation = No - NoErep = No - Dispersion = {} - ThirdOrder = No - ThirdOrderFull = No -} -Options = { - CalculateForces = Yes - WriteDetailedOut = No - WriteBandOut = No - RandomSeed = 12345 - MullikenAnalysis = No - WriteEigenvectors = No - WriteAutotestTag = No - WriteDetailedXML = No - WriteResultsTag = No - AtomResolvedEnergies = No - WriteHS = No - WriteRealHS = No - MinimiseMemoryUsage = No - ShowFoldedCoords = No -} -ParserOptions = { - ParserVersion = 3 - WriteHSDInput = Yes - WriteXMLInput = No - StopAfterParsing = No - IgnoreUnprocessedNodes = No -} -Analysis = { - ProjectStates = {} -} diff --git a/examples/COUPLE/fortran_dftb/in.simple b/examples/COUPLE/fortran_dftb/in.simple deleted file mode 100644 index 894a490cf8..0000000000 --- a/examples/COUPLE/fortran_dftb/in.simple +++ /dev/null @@ -1,16 +0,0 @@ -units real -atom_style charge -atom_modify map array -atom_modify sort 0 0.0 -read_data data.diamond -neighbor 1.0 bin -neigh_modify delay 0 every 5 check no -fix 1 all nve -fix 2 all external pf/callback 1 1 - -fix_modify 2 energy yes -thermo_style custom step temp etotal ke pe lx ly lz pxx pyy pzz press - -thermo 1 -timestep 0.5 - diff --git a/examples/COUPLE/fortran_dftb/log.simple b/examples/COUPLE/fortran_dftb/log.simple deleted file mode 100644 index 3496e94ebe..0000000000 --- a/examples/COUPLE/fortran_dftb/log.simple +++ /dev/null @@ -1,71 +0,0 @@ -LAMMPS (6 Jul 2017) -units real -atom_style charge -atom_modify map array -atom_modify sort 0 0.0 -read_data data.diamond - triclinic box = (0 0 0) to (7.134 7.134 7.134) with tilt (0 0 0) - 1 by 1 by 1 MPI processor grid - reading atoms ... - 64 atoms - reading velocities ... - 64 velocities -neighbor 1.0 bin -neigh_modify delay 0 every 5 check no -fix 1 all nve -fix 2 all external pf/callback 1 1 - -fix_modify 2 energy yes -thermo_style custom step temp etotal ke pe lx ly lz pxx pyy pzz press - -thermo 1 -timestep 0.5 - -run 10 -Neighbor list info ... - update every 5 steps, delay 0 steps, check no - max neighbors/atom: 2000, page size: 100000 - master list distance cutoff = 0 - ghost atom cutoff = 0 - binsize = 7.134, bins = 1 1 1 - 0 neighbor lists, perpetual/occasional/extra = 0 0 0 -Per MPI rank memory allocation (min/avg/max) = 2.3 | 2.3 | 2.3 Mbytes -Step Temp TotEng KinEng PotEng Lx Ly Lz Pxx Pyy Pzz Press - 0 298.24835 -69593.587 56.008365 -69649.595 7.134 7.134 7.134 -19980.19 -21024.038 -21097.458 -20700.562 - 1 295.24358 -69593.585 55.444098 -69649.029 7.134 7.134 7.134 -19778.833 -20799.657 -20854.156 -20477.549 - 2 286.37211 -69593.58 53.778115 -69647.358 7.134 7.134 7.134 -19227.52 -20177.28 -20176.12 -19860.306 - 3 272.062 -69593.572 51.090804 -69644.663 7.134 7.134 7.134 -18360.869 -19189.684 -19100.021 -18883.525 - 4 253.01834 -69593.561 47.514575 -69641.075 7.134 7.134 7.134 -17198.143 -17855.03 -17652.036 -17568.403 - 5 230.19242 -69593.547 43.228073 -69636.775 7.134 7.134 7.134 -15750.247 -16183.764 -15854.145 -15929.386 - 6 204.71787 -69593.533 38.44418 -69631.977 7.134 7.134 7.134 -14083.498 -14247.434 -13789.835 -14040.256 - 7 177.82397 -69593.518 33.393748 -69626.911 7.134 7.134 7.134 -12340.963 -12202.878 -11623.171 -12055.671 - 8 150.76736 -69593.503 28.312758 -69621.816 7.134 7.134 7.134 -10637.824 -10180.827 -9495.0496 -10104.567 - 9 124.7737 -69593.49 23.431383 -69616.921 7.134 7.134 7.134 -9113.3842 -8339.0492 -7572.8076 -8341.747 - 10 100.98183 -69593.478 18.963481 -69612.442 7.134 7.134 7.134 -7833.9349 -6756.9749 -5945.8968 -6845.6022 -Loop time of 2.20497 on 1 procs for 10 steps with 64 atoms - -Performance: 0.196 ns/day, 122.499 hours/ns, 4.535 timesteps/s -0.2% CPU use with 1 MPI tasks x no OpenMP threads - -MPI task timing breakdown: -Section | min time | avg time | max time |%varavg| %total ---------------------------------------------------------------- -Pair | 0 | 0 | 0 | 0.0 | 0.00 -Neigh | 1.4305e-06 | 1.4305e-06 | 1.4305e-06 | 0.0 | 0.00 -Comm | 4.22e-05 | 4.22e-05 | 4.22e-05 | 0.0 | 0.00 -Output | 0.00067687 | 0.00067687 | 0.00067687 | 0.0 | 0.03 -Modify | 2.2042 | 2.2042 | 2.2042 | 0.0 | 99.96 -Other | | 6.533e-05 | | | 0.00 - -Nlocal: 64 ave 64 max 64 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Nghost: 0 ave 0 max 0 min -Histogram: 1 0 0 0 0 0 0 0 0 0 -Neighs: 0 ave 0 max 0 min -Histogram: 1 0 0 0 0 0 0 0 0 0 - -Total # of neighbors = 0 -Ave neighs/atom = 0 -Neighbor list builds = 2 -Dangerous builds not checked -Total wall time: 0:00:02 diff --git a/examples/COUPLE/fortran_dftb/makefile b/examples/COUPLE/fortran_dftb/makefile deleted file mode 100644 index 225bd0025a..0000000000 --- a/examples/COUPLE/fortran_dftb/makefile +++ /dev/null @@ -1,45 +0,0 @@ -SHELL = /bin/sh - -# Path to LAMMPS extraction directory -LAMMPS_ROOT = ../../.. -LAMMPS_SRC = $(LAMMPS_ROOT)/src - -# Uncomment the line below if using the MPI stubs library -MPI_STUBS = #-I$(LAMMPS_SRC)/STUBS - -FC = mpif90 # replace with your Fortran compiler -CXX = mpicc # replace with your C++ compiler - -# Flags for Fortran compiler, C++ compiler, and C preprocessor, respectively -FFLAGS = -O2 -fPIC -CXXFLAGS = -O2 -fPIC -CPPFLAGS = -DOMPI_SKIP_MPICXX=1 -DMPICH_SKIP_MPICXX - -all : liblammps_fortran.a liblammps_fortran.so simpleF.x - -liblammps_fortran.so : LAMMPS.o LAMMPS-wrapper.o LAMMPS-wrapper2.o - $(FC) $(FFLAGS) -shared -o $@ $^ - -simpleF.x: simple.o LAMMPS.o LAMMPS-wrapper.o LAMMPS-wrapper2.o - $(FC) $(FFLAGS) simple.o -o simpleF.x liblammps_fortran.a $(LAMMPS_SRC)/liblammps_mvapich.a -lstdc++ /usr/lib64/libfftw3.a - -liblammps_fortran.a : LAMMPS.o LAMMPS-wrapper.o LAMMPS-wrapper2.o - $(AR) rs $@ $^ - -LAMMPS.o lammps.mod : LAMMPS.F90 - $(FC) $(CPPFLAGS) $(FFLAGS) -c $< - -simple.o : simple.f90 - $(FC) $(FFLAGS) -c $< - -LAMMPS-wrapper.o : LAMMPS-wrapper.cpp LAMMPS-wrapper.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -I$(LAMMPS_SRC) $(MPI_STUBS) - -LAMMPS-wrapper2.o : LAMMPS-wrapper2.cpp LAMMPS-wrapper2.h - $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -I$(LAMMPS_SRC) $(MPI_STUBS) - -clean : - $(RM) *.o *.mod liblammps_fortran.a liblammps_fortran.so - -dist : - tar -czvf fortran-interface-callback.tar.gz LAMMPS-wrapper.h LAMMPS-wrapper.cpp LAMMPS-wrapper2.h LAMMPS-wrapper2.cpp LAMMPS.F90 makefile README simple.f90 diff --git a/examples/COUPLE/fortran_dftb/simple.f90 b/examples/COUPLE/fortran_dftb/simple.f90 deleted file mode 100644 index 4604b4e4a9..0000000000 --- a/examples/COUPLE/fortran_dftb/simple.f90 +++ /dev/null @@ -1,110 +0,0 @@ - module callback - implicit none - contains - subroutine fortran_callback(lmp, timestep, nlocal, ids, c_pos, c_fext) & - & bind(C, name='f_callback') - use, intrinsic :: ISO_C_binding - use LAMMPS - implicit none - type (C_ptr), value :: lmp - integer(C_int64_t), intent(in), value :: timestep - integer(C_int), intent(in), value :: nlocal - real (C_double), dimension(:,:), pointer :: x - type(c_ptr) :: c_pos, c_fext, c_ids - double precision, pointer :: fext(:,:), pos(:,:) - integer, intent(in) :: ids(nlocal) - real(C_double) :: virial(6) - real (C_double) :: etot - real(C_double), pointer :: ts_lmp - double precision :: stress(3,3), ts_dftb - integer :: natom , i - real (C_double), parameter :: econv = 627.4947284155114 ! converts from Ha to - double precision, parameter :: fconv = 1185.793095983065 ! converts from Ha/bohr to - double precision, parameter :: autoatm = 2.9037166638E8 - double precision lx, ly, lz - real (C_double), pointer :: boxxlo, boxxhi - real (C_double), pointer :: boxylo, boxyhi - real (C_double), pointer :: boxzlo, boxzhi - double precision, parameter :: nktv2p = 68568.4149999999935972 - double precision :: volume - type (C_ptr) :: Cptr - type (C_ptr), pointer, dimension(:) :: Catom - - call c_f_pointer(c_pos, pos, [3,nlocal]) - call c_f_pointer(c_fext, fext, [3,nlocal]) - call lammps_extract_global(boxxlo, lmp, 'boxxlo') - call lammps_extract_global(boxxhi, lmp, 'boxxhi') - call lammps_extract_global(boxylo, lmp, 'boxylo') - call lammps_extract_global(boxyhi, lmp, 'boxyhi') - call lammps_extract_global(boxzlo, lmp, 'boxzlo') - call lammps_extract_global(boxzhi, lmp, 'boxzhi') - lx = boxxhi - boxxlo - ly = boxyhi - boxylo - lz = boxzhi - boxzlo - volume = lx*ly*lz - open (unit = 10, status = 'replace', action = 'write', file='lammps.gen') - write(10,*)nlocal,"S" - write(10,*) "C" - do i = 1, nlocal - write(10,'(2I,3F15.6)')i,1,pos(:,ids(i)) - enddo - write(10,*)"0.0 0.0 0.0" - write(10,*)lx,0,0 - write(10,*)0,ly,0 - write(10,*)0,0,lz - close(10) - call system("./dftb+ > dftb.out") - open (unit = 10, status = 'old', file = 'results.out') - read(10,*)etot - read(10,*)ts_dftb - do i = 1, 3 - read(10,*)stress(i,:) - enddo - stress (:,:) = stress(:,:)*autoatm - virial(1) = stress(1,1)/(nktv2p/volume) - virial(2) = stress(2,2)/(nktv2p/volume) - virial(3) = stress(3,3)/(nktv2p/volume) - virial(4) = stress(1,2)/(nktv2p/volume) - virial(5) = stress(1,3)/(nktv2p/volume) - virial(6) = stress(2,3)/(nktv2p/volume) - etot = etot*econv - call lammps_set_external_vector(lmp,1,ts_dftb*econv) - do i = 1, nlocal - read(10,*)fext(:,ids(i)) - fext(:,ids(i)) = fext(:,ids(i))*fconv - enddo - close(10) - call lammps_set_user_energy (lmp, etot) - call lammps_set_user_virial (lmp, virial) - - end subroutine - end module callback - - -program simple_fortran_callback - - use MPI - use LAMMPS - use callback - use, intrinsic :: ISO_C_binding, only : C_double, C_ptr, C_int, C_FUNPTR - implicit none - type (C_ptr) :: lmp - integer :: error, narg, me, nprocs - - call MPI_Init (error) - call MPI_Comm_rank (MPI_COMM_WORLD, me, error) - call MPI_Comm_size (MPI_COMM_WORLD, nprocs, error) - - call lammps_open_no_mpi ('lmp -log log.simple', lmp) - call lammps_file (lmp, 'in.simple') - call lammps_set_callback(lmp) - call lammps_set_external_vector_length(lmp,2) - - call lammps_command (lmp, 'run 10') - call lammps_close (lmp) - call MPI_Finalize (error) - - -end program simple_fortran_callback - - From e2e9170dfa8ddcd9bce8f3376619b8993537c46c Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 18:52:57 -0400 Subject: [PATCH 442/448] protect a couple more fixes from segfaults from errors in derived classes --- src/RIGID/fix_rigid.cpp | 2 +- src/fix_langevin.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/RIGID/fix_rigid.cpp b/src/RIGID/fix_rigid.cpp index df49d84439..44427d2914 100644 --- a/src/RIGID/fix_rigid.cpp +++ b/src/RIGID/fix_rigid.cpp @@ -610,7 +610,7 @@ FixRigid::~FixRigid() { // unregister callbacks to this fix from Atom class - atom->delete_callback(id,Atom::GROW); + if (modify->get_fix_by_id(id)) atom->delete_callback(id,Atom::GROW); delete random; delete[] inpfile; diff --git a/src/fix_langevin.cpp b/src/fix_langevin.cpp index 0e083ce012..35bffb24fa 100644 --- a/src/fix_langevin.cpp +++ b/src/fix_langevin.cpp @@ -203,7 +203,7 @@ FixLangevin::~FixLangevin() if (gjfflag) { memory->destroy(franprev); memory->destroy(lv); - atom->delete_callback(id, Atom::GROW); + if (modify->get_fix_by_id(id)) atom->delete_callback(id, Atom::GROW); } } From 70823cac50a1bfecce5ed484adc6c7010bba8056 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sat, 17 Jun 2023 23:30:36 -0400 Subject: [PATCH 443/448] remove dead code --- python/lammps/pylammps.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/lammps/pylammps.py b/python/lammps/pylammps.py index bdbed3e971..c693b7d565 100644 --- a/python/lammps/pylammps.py +++ b/python/lammps/pylammps.py @@ -761,8 +761,6 @@ class PyLammps(object): for line in output: if line.startswith("Atom map"): system['atom_map'] = self._get_pair(line)[1] - elif line.startswith("Atoms"): - parts = self._split_values(line) elif line.startswith("Boundaries"): system['boundaries'] = self._get_pair(line)[1] elif line.startswith("Molecule type"): From 5196e4422be2059a68081c1197729fe0759660d2 Mon Sep 17 00:00:00 2001 From: Shern Tee Date: Sun, 18 Jun 2023 17:51:15 +1000 Subject: [PATCH 444/448] debug fix_modify press for press/berendsen --- src/fix_press_berendsen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fix_press_berendsen.cpp b/src/fix_press_berendsen.cpp index da49b3dbdb..e27a4560f0 100644 --- a/src/fix_press_berendsen.cpp +++ b/src/fix_press_berendsen.cpp @@ -491,7 +491,7 @@ int FixPressBerendsen::modify_param(int narg, char **arg) id_press = utils::strdup(arg[1]); pressure = modify->get_compute_by_id(arg[1]); - if (pressure) error->all(FLERR,"Could not find fix_modify pressure compute ID: {}", arg[1]); + if (!pressure) error->all(FLERR,"Could not find fix_modify pressure compute ID: {}", arg[1]); if (pressure->pressflag == 0) error->all(FLERR,"Fix_modify pressure compute {} does not compute pressure", arg[1]); return 2; From 2cea819e7fe05e1ee97e152a29eecd0701a20f5e Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 18 Jun 2023 07:24:42 -0400 Subject: [PATCH 445/448] cosmetic --- potentials/BNC.tersoff | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/potentials/BNC.tersoff b/potentials/BNC.tersoff index 046566dd99..a072aa05b3 100644 --- a/potentials/BNC.tersoff +++ b/potentials/BNC.tersoff @@ -1,4 +1,4 @@ -# DATE: 2013-03-21 UNITS: metal CONTRIBUTOR: Cem Sevik CITATION: Kinaci, Haskins, Sevik and Cagin, Phys Rev B, 86, 115410 (2012) +# DATE: 2013-03-21 UNITS: metal CONTRIBUTOR: Cem Sevik CITATION: Kinaci, Haskins, Sevik and Cagin, Phys Rev B, 86, 115410 (2012) # Tersoff parameters for B, C, and BN-C hybrid based graphene like nano structures # multiple entries can be added to this file, LAMMPS reads the ones it needs @@ -7,11 +7,11 @@ # other quantities are unitless # Cem Sevik (csevik at anadolu.edu.tr) takes full blame for this -# file. It specifies B-N, B-C, and N-C interaction parameters -# generated and published by the reseacrh group of Prof. Tahir Cagin. +# file. It specifies B-N, B-C, and N-C interaction parameters +# generated and published by the research group of Prof. Tahir Cagin. # 1. Physical Review B 84, 085409 2011 -# Characterization of thermal transport in low-dimensional boron nitride nanostructures, +# Characterization of thermal transport in low-dimensional boron nitride nanostructures, # # 2. Physical Review B 86, 075403 2012 @@ -22,14 +22,14 @@ # Thermal conductivity of BN-C nanostructures # -# The file also specifies C-C, interaction parameters +# The file also specifies C-C, interaction parameters # generated and published by the research group of Dr. D. A. Broido # Physical Review B 81, 205441 2010 -# Optimized Tersoff and Brenner empirical potential parameters for +# Optimized Tersoff and Brenner empirical potential parameters for # lattice dynamics and phonon thermal transport in carbon nanotubes and graphene # Users in referring the full parameters can cite the full parameter paper (3) as: -# A. Kinaci, J. B. Haskins, C. Sevik, T. Cagin, Physical Review B 86, 115410 (2012) +# A. Kinaci, J. B. Haskins, C. Sevik, T. Cagin, Physical Review B 86, 115410 (2012) # Thermal conductivity of BN-C nanostructures # @@ -38,11 +38,11 @@ # m, gamma, lambda3, c, d, costheta0, n, beta, lambda2, B, R, D, lambda1, A N B B 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 -N B N 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 +N B N 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 N B C 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 B N B 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 -B N N 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 +B N N 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 B N C 3.0 1.0 0.0 25000 4.3484 -0.89000 0.72751 1.25724e-7 2.199 340.00 1.95 0.05 3.568 1380.0 N N B 3.0 1.0 0.0 17.7959 5.9484 0.00000 0.6184432 0.019251 2.6272721 138.77866 2.0 0.1 2.8293093 128.86866 From 21fb50f37b264c7ec33cb34be97b76fbd0169578 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Sun, 18 Jun 2023 07:40:04 -0400 Subject: [PATCH 446/448] correct logic bug --- src/compute_chunk_spread_atom.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compute_chunk_spread_atom.cpp b/src/compute_chunk_spread_atom.cpp index 933cf0af0c..53b8517c22 100644 --- a/src/compute_chunk_spread_atom.cpp +++ b/src/compute_chunk_spread_atom.cpp @@ -106,7 +106,7 @@ ComputeChunkSpreadAtom(LAMMPS *lmp, int narg, char **arg) : } else if (val.which == ArgInfo::FIX) { auto ifix = modify->get_fix_by_id(val.id); - if (ifix) + if (!ifix) error->all(FLERR,"Fix ID {} for compute chunk/spread/atom does not exist", val.id); if (val.argindex == 0) { if (!ifix->vector_flag) From 6ccf5f107c3767b0f1e42b4ced7cee141aaebff5 Mon Sep 17 00:00:00 2001 From: John Lucas Date: Sun, 18 Jun 2023 20:39:18 -0500 Subject: [PATCH 447/448] fix a bug in fix pair --- src/fix_pair.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/fix_pair.cpp b/src/fix_pair.cpp index 81e62ba966..66212684a8 100644 --- a/src/fix_pair.cpp +++ b/src/fix_pair.cpp @@ -283,11 +283,14 @@ void FixPair::post_force(int /*vflag*/) } else { double **parray = (double **) pvoid; - for (int i = 0; i < nlocal; i++) + int icoltmp = icol; + for (int i = 0; i < nlocal; i++) { + icol = icoltmp; for (int m = 0; m < columns; m++) { array[i][icol] = parray[i][m]; icol++; } + } } } From 542aa203dad3b18602b8b4ff58a1292ba4bb7f71 Mon Sep 17 00:00:00 2001 From: John Lucas Date: Sun, 18 Jun 2023 20:42:45 -0500 Subject: [PATCH 448/448] correct typo in fix pair documentation --- doc/src/fix_pair.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/fix_pair.rst b/doc/src/fix_pair.rst index 44c91f18ee..07e934d1c0 100644 --- a/doc/src/fix_pair.rst +++ b/doc/src/fix_pair.rst @@ -85,7 +85,7 @@ columns 4-6 will store the "uinp" values. .. code-block:: LAMMPS pair_style amoeba - fix ex all pair amoeba 10 uind 0 uinp 0 + fix ex all pair 10 amoeba uind 0 uinp 0 Restart, fix_modify, output, run start/stop, minimize info """""""""""""""""""""""""""""""""""""""""""""""""""""""""""